/*
 * Copyright 2014 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.jjs.test;

import com.google.gwt.core.client.GwtScriptOnly;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.dev.jjs.test.defaultmethods.ImplementsWithDefaultMethodAndStaticInitializer;
import com.google.gwt.dev.jjs.test.defaultmethods.SomeClass;
import com.google.gwt.junit.client.GWTTestCase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsOverlay;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsProperty;
import jsinterop.annotations.JsType;

/**
 * Tests Java 8 features. It is super sourced so that gwt can be compiles under Java 7.
 *
 * IMPORTANT: For each test here there must exist the corresponding method in the non super sourced
 * version.
 *
 * Eventually this test will graduate and not be super sourced.
 */
@GwtScriptOnly
public class Java8Test extends GWTTestCase {
  int local = 42;

  static abstract class SameClass {
    public int method1() { return 10; }
    public abstract int method2();
  }

  interface Lambda<T> {
    T run(int a, int b);
  }

  interface Lambda2<String> {
    boolean run(String a, String b);
  }

  interface Lambda3<String> {
    boolean run(String a);
  }

  class AcceptsLambda<T> {
    public T accept(Lambda<T> foo) {
      return foo.run(10, 20);
    }
    public boolean accept2(Lambda2<String> foo) {
      return foo.run("a", "b");
    }
    public boolean accept3(Lambda3<String> foo) {
      return foo.run("hello");
    }
  }

  class Pojo {
    private final int x;
    private final int y;

    public Pojo(int x, int y) {
      this.x = x;
      this.y = y;
    }

    public int fooInstance(int a, int b) {
      return a + b + x + y;
    }
  }

  interface DefaultInterface {
    void method1();
    // CHECKSTYLE_OFF
    default int method2() { return 42; }
    default int redeclaredAsAbstract() {
        return 88;
    }
    default Integer addInts(int x, int y) { return x + y; }
    default String print() { return "DefaultInterface"; }
    // CHECKSTYLE_ON
  }

  interface DefaultInterface2 {
    void method3();
    // CHECKSTYLE_OFF
    default int method4() { return 23; }
    default int redeclaredAsAbstract() {
      return 77;
    }
    // CHECKSTYLE_ON
  }

  interface DefaultInterfaceSubType extends DefaultInterface {
    // CHECKSTYLE_OFF
    default int method2() { return 43; }
    default String print() {
      return "DefaultInterfaceSubType " + DefaultInterface.super.print();
    }
    // CHECKSTYLE_ON
  }

  static abstract class DualImplementorSuper implements DefaultInterface {
    public void method1() {
    }

    public abstract int redeclaredAsAbstract();
  }

  static class DualImplementorBoth extends VirtualUpRef implements DefaultInterface,
      DefaultInterface2 {
    public void method1() {
    }
    public void method3() {
    }
  }

  static class DualImplementor extends DualImplementorSuper implements DefaultInterface2 {
    public void method3() {
    }

    public int redeclaredAsAbstract() {
      return DefaultInterface2.super.redeclaredAsAbstract();
    }
  }

  // this doesn't implement DefaultInterface, but will provide implementation in subclasses
  static class VirtualUpRef {
    public int method2() {
      return 99;
    }
    public int redeclaredAsAbstract() {
      return 44;
    }
  }

  class Inner {
    int local = 22;
    public void run() {
      assertEquals(94, new AcceptsLambda<Integer>().accept((a,b) -> Java8Test.this.local +  local + a + b).intValue());
    }
  }

  static class Static {
    static int staticField;
    static {
      staticField = 99;
    }
    static Integer staticMethod(int x, int y) { return x + y + staticField; }
  }

  static class StaticFailIfClinitRuns {
    static {
      fail("clinit() shouldn't run from just taking a reference to a method");
    }

    public static Integer staticMethod(int x, int y) {
      return null;
    }
  }

  static class DefaultInterfaceImpl implements DefaultInterface {
    public void method1() {
    }
  }

  static class DefaultInterfaceImpl2 implements DefaultInterface {
    public void method1() {
    }
    public int method2() {
      return 100;
    }
  }

  static class DefaultInterfaceImplVirtualUpRef extends VirtualUpRef implements DefaultInterface {
    public void method1() {
    }
  }

  static class DefaultInterfaceImplVirtualUpRefTwoInterfaces extends VirtualUpRef
      implements DefaultInterfaceSubType {
    public void method1() {
    }
    // CHECKSTYLE_OFF
    public String print() { return "DefaultInterfaceImplVirtualUpRefTwoInterfaces"; }
    // CHECKSTYLE_ON
  }

  @Override
  public String getModuleName() {
    return "com.google.gwt.dev.jjs.Java8Test";
  }

  public void testLambdaNoCapture() {
    assertEquals(30, new AcceptsLambda<Integer>().accept((a, b) -> a + b).intValue());
  }

  public void testLambdaCaptureLocal() {
    int x = 10;
    assertEquals(40, new AcceptsLambda<Integer>().accept((a,b) -> x + a + b).intValue());
  }

  public void testLambdaCaptureLocalWithInnerClass() {
    int x = 10;
    Lambda<Integer> l = (a,b) -> new Lambda<Integer>() {
      @Override public Integer run(int a, int b) {
        int t = x;
        return t + a + b;
      }
    }.run(a,b);
    assertEquals(40, new AcceptsLambda<Integer>().accept(l).intValue());
  }

  public void testLambdaCaptureLocalAndField() {
    int x = 10;
    assertEquals(82, new AcceptsLambda<Integer>().accept((a,b) -> x + local + a + b).intValue());
  }

  public void testLambdaCaptureLocalAndFieldWithInnerClass() {
    int x = 10;
    Lambda<Integer> l = (a,b) -> new Lambda<Integer>() {
      @Override public Integer run(int j, int k) {
        int t = x;
        int s = local;
        return t + s + a + b;
      }
    }.run(a,b);
    assertEquals(82, new AcceptsLambda<Integer>().accept(l).intValue());
  }

  public void testCompileLambdaCaptureOuterInnerField() throws Exception {
    new Inner().run();
  }

  public void testStaticReferenceBinding() throws Exception {
    assertEquals(129, new AcceptsLambda<Integer>().accept(Static::staticMethod).intValue());
    // if this next line runs a clinit, it fails
    Lambda l = dummyMethodToMakeCheckStyleHappy(StaticFailIfClinitRuns::staticMethod);
    try {
      // but now it should fail
      l.run(1,2);
      fail("Clinit should have run for the first time");
    } catch (AssertionError ae) {
      // success, it was supposed to throw!
    }
  }

  private static Lambda<Integer> dummyMethodToMakeCheckStyleHappy(Lambda<Integer> l) {
    return l;
  }

  public void testInstanceReferenceBinding() throws Exception {
    Pojo instance1 = new Pojo(1, 2);
    Pojo instance2 = new Pojo(3, 4);
    assertEquals(33, new AcceptsLambda<Integer>().accept(instance1::fooInstance).intValue());
    assertEquals(37, new AcceptsLambda<Integer>().accept(instance2::fooInstance).intValue());
  }

  public void testImplicitQualifierReferenceBinding() throws Exception {
    assertFalse(new AcceptsLambda<String>().accept2(String::equalsIgnoreCase));
    assertTrue(new AcceptsLambda<String>().accept3("hello world"::contains));
  }

  public void testConstructorReferenceBinding() {
    assertEquals(30, new AcceptsLambda<Pojo>().accept(Pojo::new).fooInstance(0, 0));
  }

  public void testStaticInterfaceMethod() {
    assertEquals(99, (int) Static.staticMethod(0, 0));
  }

  interface ArrayCtor {
    ArrayElem [][][] copy(int i);
  }

  interface ArrayCtorBoxed {
    ArrayElem [][][] copy(Integer i);
  }

  static class ArrayElem {
  }

  public void testArrayConstructorReference() {
    ArrayCtor ctor = ArrayElem[][][]::new;
    ArrayElem[][][] array = ctor.copy(100);
    assertEquals(100, array.length);
  }

  public void testArrayConstructorReferenceBoxed() {
    ArrayCtorBoxed ctor = ArrayElem[][][]::new;
    ArrayElem[][][] array = ctor.copy(100);
    assertEquals(100, array.length);
  }

  interface ThreeArgs {
    int foo(int x, int y, int z);
  }

  interface ThreeVarArgs {
    int foo(int x, int y, int... z);
  }

  public static int addMany(int x, int y, int... nums) {
    int sum = x + y;
    for (int num : nums) {
      sum += num;
    }
    return sum;
  }

  public void testVarArgsReferenceBinding() {
    ThreeArgs t = Java8Test::addMany;
    assertEquals(6, t.foo(1,2,3));
  }

  public void testVarArgsPassthroughReferenceBinding() {
    ThreeVarArgs t = Java8Test::addMany;
    assertEquals(6, t.foo(1,2,3));
  }

  public void testVarArgsPassthroughReferenceBindingProvidedArray() {
    ThreeVarArgs t = Java8Test::addMany;
    assertEquals(6, t.foo(1,2, new int[] {3}));
  }

  interface I {
    int foo(Integer i);
  }

  public void testSuperReferenceExpression() {
    class Y {
      int foo(Integer i) {
        return 42;
      }
    }

    class X extends Y {
      int foo(Integer i) {
        return 23;
      }

      int goo() {
        I i = super::foo;
        return i.foo(0);
      }
    }

    assertEquals(42, new X().goo());
  }

  public void testQualifiedSuperReferenceExpression() {
    class Y {
      int foo(Integer i) {
        return 42;
      }
    }

    class X extends Y {
      int foo(Integer i) {
        return 23;
      }

      int goo() {
        I i = X.super::foo;
        return i.foo(0);
      }
    }

    assertEquals(42, new X().goo());
  }

  static class X2 {
    protected int field;
    void foo() {
      int local;
      class Y extends X2 {
        class Z extends X2 {
          void f() {
            Ctor c = X2::new;
            X2 x = c.makeX(123456);
            assertEquals(123456, x.field);
            c = Y::new;
            x = c.makeX(987654);
            x = new Y(987654);
            assertEquals(987655, x.field);
            c = Z::new;
            x = c.makeX(456789);
            x = new Z(456789);
            assertEquals(456791, x.field);
          }
          private Z(int z) {
            super(z + 2);
          }
          Z() {
          }
        }

        private Y(int y) {
          super(y + 1);
        }

        private Y() {
        }
      }
      new Y().new Z().f();
    }

    private X2(int x) {
      this.field = x;
    }
    X2() {
    }
  }

  public void testSuperReferenceExpressionWithVarArgs() {
    class Base {
      int foo(Object... objects) {
        return 0;
      }
    }

    class X extends Base {
      int foo(Object... objects) {
        throw new AssertionError();
      }

      void goo() {
        I i = super::foo;
        i.foo(10);
      }
    }
    new X().goo();
  }

  interface Ctor {
    X2 makeX(int x);
  }

  public void testPrivateConstructorReference() {
    new X2().foo();
  }

  public void testDefaultInterfaceMethod() {
    assertEquals(42, new DefaultInterfaceImpl().method2());
  }

  public void testDefaultInterfaceMethodVirtualUpRef() {
    assertEquals(99, new DefaultInterfaceImplVirtualUpRef().method2());
    assertEquals(99, new DefaultInterfaceImplVirtualUpRefTwoInterfaces().method2());
    assertEquals("SimpleB", new com.google.gwt.dev.jjs.test.package3.SimpleC().m());
    assertEquals("SimpleASimpleB", new com.google.gwt.dev.jjs.test.package1.SimpleD().m());
  }

  public void testDefaultInterfaceMethodMultiple() {
    assertEquals(42, new DualImplementor().method2());
    assertEquals(23, new DualImplementor().method4());
    assertEquals(77, new DualImplementor().redeclaredAsAbstract());
    assertEquals(44, new DualImplementorBoth().redeclaredAsAbstract());
    DefaultInterfaceImplVirtualUpRefTwoInterfaces instanceImplementInterfaceSubType =
        new DefaultInterfaceImplVirtualUpRefTwoInterfaces();
    DefaultInterfaceSubType interfaceSubType1 = instanceImplementInterfaceSubType;
    assertEquals("DefaultInterfaceImplVirtualUpRefTwoInterfaces",
        instanceImplementInterfaceSubType.print());
    assertEquals("DefaultInterfaceImplVirtualUpRefTwoInterfaces", interfaceSubType1.print());
    DefaultInterfaceSubType interfaceSubType2 = new DefaultInterfaceSubType() {
      @Override
      public void method1() { }
    };
    assertEquals("DefaultInterfaceSubType DefaultInterface",
        interfaceSubType2.print());
    DefaultInterfaceSubType interfaceSubType3 = () -> { };
    assertEquals("DefaultInterfaceSubType DefaultInterface",
        interfaceSubType3.print());
  }

  public void testDefenderMethodByInterfaceInstance() {
    DefaultInterfaceImpl2 interfaceImpl2 = new DefaultInterfaceImpl2();
    DefaultInterface interface1 = interfaceImpl2;
    assertEquals(100, interfaceImpl2.method2());
    assertEquals(100, interface1.method2());
  }

  public void testDefaultMethodReference() {
    DefaultInterfaceImplVirtualUpRef x = new DefaultInterfaceImplVirtualUpRef();
    assertEquals(30, (int) new AcceptsLambda<Integer>().accept(x::addInts));
  }

  interface InterfaceWithTwoDefenderMethods {
    // CHECKSTYLE_OFF
    default String foo() { return "interface.foo"; }
    default String bar() { return this.foo() + " " + foo(); }
    // CHECKSTYLE_ON
  }

  class ClassImplementOneDefenderMethod implements InterfaceWithTwoDefenderMethods {
    public String foo() {
      return "class.foo";
    }
  }

  public void testThisRefInDefenderMethod() {
    ClassImplementOneDefenderMethod c = new ClassImplementOneDefenderMethod();
    InterfaceWithTwoDefenderMethods i1 = c;
    InterfaceWithTwoDefenderMethods i2 = new InterfaceWithTwoDefenderMethods() { };
    assertEquals("class.foo class.foo", c.bar());
    assertEquals("class.foo class.foo", i1.bar());
    assertEquals("interface.foo interface.foo", i2.bar());
  }

  interface InterfaceImplementOneDefenderMethod extends InterfaceWithTwoDefenderMethods {
    // CHECKSTYLE_OFF
    default String foo() { return "interface1.foo"; }
    // CHECKSTYLE_ON
  }

  interface InterfaceImplementZeroDefenderMethod extends InterfaceWithTwoDefenderMethods {
  }

  class ClassImplementsTwoInterfaces implements InterfaceImplementOneDefenderMethod,
      InterfaceImplementZeroDefenderMethod {
  }

  public void testClassImplementsTwoInterfacesWithSameDefenderMethod() {
    ClassImplementsTwoInterfaces c = new ClassImplementsTwoInterfaces();
    assertEquals("interface1.foo", c.foo());
  }

  abstract class AbstractClass implements InterfaceWithTwoDefenderMethods {
  }

  class Child1 extends AbstractClass {
    public String foo() {
      return super.foo() + " child1.foo";
    }
  }

  class Child2 extends AbstractClass {
  }

  public void testAbstractClassImplementsInterface() {
    Child1 child1 = new Child1();
    Child2 child2 = new Child2();
    assertEquals("interface.foo child1.foo", child1.foo());
    assertEquals("interface.foo", child2.foo());
  }

  interface InterfaceI {
    // CHECKSTYLE_OFF
    default String print() { return "interface1"; }
    // CHECKSTYLE_ON
  }
  interface InterfaceII {
    // CHECKSTYLE_OFF
    default String print() { return "interface2"; }
    // CHECKSTYLE_ON
  }
  class ClassI {
    public String print() {
      return "class1";
    }
  }
  class ClassII extends ClassI implements InterfaceI, InterfaceII {
    public String print() {
      return super.print() + " " + InterfaceI.super.print() + " " + InterfaceII.super.print();
    }
  }

  public void testSuperRefInDefenderMethod() {
    ClassII c = new ClassII();
    assertEquals("class1 interface1 interface2", c.print());
  }

  interface II {
    // CHECKSTYLE_OFF
    default String fun() { return "fun() in i: " + this.foo(); };
    default String foo() { return "foo() in i.\n"; };
    // CHECKSTYLE_ON
  }
  interface JJ extends II {
    // CHECKSTYLE_OFF
    default String fun() { return "fun() in j: " + this.foo() + II.super.fun(); };
    default String foo() { return "foo() in j.\n"; }
    // CHECKSTYLE_ON
  }
  class AA {
    public String fun() {
      return "fun() in a: " + this.foo();
    }
    public String foo() {
      return "foo() in a.\n";
    }
  }
  class BB extends AA implements JJ {
    public String fun() {
      return "fun() in b: " + this.foo() + super.fun() + JJ.super.fun();
    }
    public String foo() {
      return "foo() in b.\n";
    }
  }
  class CC extends BB implements JJ {
    public String fun() {
      return "fun() in c: " + super.fun();
    }
  }

  public void testSuperThisRefsInDefenderMethod() {
    CC c = new CC();
    II i1 = c;
    JJ j1 = c;
    BB b = new BB();
    II i2 = b;
    JJ j2 = b;
    JJ j3 = new JJ() { };
    II i3 = j3;
    II i4 = new II() { };
    String c_fun = "fun() in c: fun() in b: foo() in b.\n"
        + "fun() in a: foo() in b.\n"
        + "fun() in j: foo() in b.\n"
        + "fun() in i: foo() in b.\n";
    String b_fun = "fun() in b: foo() in b.\n"
        + "fun() in a: foo() in b.\n"
        + "fun() in j: foo() in b.\n"
        + "fun() in i: foo() in b.\n";
    String j_fun = "fun() in j: foo() in j.\n"
        + "fun() in i: foo() in j.\n";
    String i_fun = "fun() in i: foo() in i.\n";
    assertEquals(c_fun, c.fun());
    assertEquals(c_fun, i1.fun());
    assertEquals(c_fun, j1.fun());
    assertEquals(b_fun, b.fun());
    assertEquals(b_fun, i2.fun());
    assertEquals(b_fun, j2.fun());
    assertEquals(j_fun, j3.fun());
    assertEquals(j_fun, i3.fun());
    assertEquals(i_fun, i4.fun());
  }

  interface OuterInterface {
    // CHECKSTYLE_OFF
    default String m() {
      return "I.m;" + new InnerClass().n();
    }
    default String n() {
      return "I.n;" + this.m();
    }
    // CHECKSTYLE_ON
    class InnerClass {
      public String n() {
        return "A.n;" + m();
      }
      public String m() {
        return "A.m;";
      }
    }
  }
  class OuterClass {
    public String m() {
      return "B.m;";
    }
    public String n1() {
      OuterInterface i = new OuterInterface() { };
      return "B.n1;" + i.n() + OuterClass.this.m();
    }
    public String n2() {
      OuterInterface i = new OuterInterface() {
        @Override
        public String n() {
          return this.m() + OuterClass.this.m();
        }
      };
      return "B.n2;" + i.n() + OuterClass.this.m();
    }
  }
  public void testNestedInterfaceClass() {
    OuterClass outerClass = new OuterClass();
    assertEquals("B.n1;I.n;I.m;A.n;A.m;B.m;", outerClass.n1());
    assertEquals("B.n2;I.m;A.n;A.m;B.m;B.m;", outerClass.n2());
  }

  class EmptyA { }
  interface EmptyI { }
  interface EmptyJ { }
  class EmptyB extends EmptyA implements EmptyI { }
  class EmptyC extends EmptyA implements EmptyI, EmptyJ { }
  public void testBaseIntersectionCast() {
    EmptyA localB = new EmptyB();
    EmptyA localC = new EmptyC();
    EmptyB b2BI = (EmptyB & EmptyI) localB;
    EmptyC c2CIJ = (EmptyC & EmptyI & EmptyJ) localC;
    EmptyI ii1 = (EmptyB & EmptyI) localB;
    EmptyI ii2 = (EmptyC & EmptyI) localC;
    EmptyI ii3 = (EmptyC & EmptyJ) localC;
    EmptyI ii4 = (EmptyC & EmptyI & EmptyJ) localC;
    EmptyJ jj1 = (EmptyC & EmptyI & EmptyJ) localC;
    EmptyJ jj2 = (EmptyC & EmptyI) localC;
    EmptyJ jj3 = (EmptyC & EmptyJ) localC;
    EmptyJ jj4 = (EmptyI & EmptyJ) localC;

    try {
      EmptyC b2CIJ = (EmptyC & EmptyI & EmptyJ) localB;
      fail("Should have thrown a ClassCastException");
    } catch (ClassCastException e) {
      // Expected.
    }
    try {
      EmptyB c2BI = (EmptyB & EmptyI) localC;
      fail("Should have thrown a ClassCastException");
    } catch (ClassCastException e) {
      // Expected.
    }
    try {
      EmptyJ jj = (EmptyB & EmptyJ) localB;
      fail("Should have thrown a ClassCastException");
    } catch (ClassCastException e) {
      // Expected.
    }
  }

  interface SimpleI {
    int fun();
  }
  interface SimpleK {
  }
  public void testIntersectionCastWithLambdaExpr() {
    SimpleI simpleI1 = (SimpleI & EmptyI) () -> 11;
    assertEquals(11, simpleI1.fun());
    SimpleI simpleI2 = (EmptyI & SimpleI) () -> 22;
    assertEquals(22, simpleI2.fun());
    EmptyI emptyI = (EmptyI & SimpleI) () -> 33;
    assertEquals(55, ((SimpleI & SimpleK) () -> 55).fun());
  }

  class SimpleA {
    public int bar() {
      return 11;
    }
  }

  class SimpleB extends SimpleA implements SimpleI {
    public int fun() {
      return 22;
    }
  }

  class SimpleC extends SimpleA implements SimpleI {
    public int fun() {
      return 33;
    }

    public int bar() {
      return 44;
    }
  }

  public void testIntersectionCastPolymorphism() {
    SimpleA bb = new SimpleB();
    assertEquals(22, ((SimpleB & SimpleI) bb).fun());
    assertEquals(11, ((SimpleB & SimpleI) bb).bar());
    SimpleA cc = new SimpleC();
    assertEquals(33, ((SimpleC & SimpleI) cc).fun());
    assertEquals(44, ((SimpleC & SimpleI) cc).bar());
    assertEquals(33, ((SimpleA & SimpleI) cc).fun());
    SimpleI ii = (SimpleC & SimpleI) cc;
    assertEquals(33, ii.fun());
  }

  interface ClickHandler {
    int onClick(int a);
  }
  private int addClickHandler(ClickHandler clickHandler) {
    return clickHandler.onClick(1);
  }
  private int addClickHandler(int a) {
    return addClickHandler(x -> { int temp = a; return temp; });
  }
  public void testLambdaCaptureParameter() {
    assertEquals(2, addClickHandler(2));
  }

  interface TestLambda_Inner {
    void f();
  }
  interface TestLambda_Outer {
    void accept(TestLambda_Inner t);
  }
  public void testLambda_call(TestLambda_Outer a) {
    a.accept(() -> { });
  }
  public void testLambdaNestingCaptureLocal() {
    int[] success = new int[] {0};
    testLambda_call(sam1 -> { testLambda_call(sam2 -> { success[0] = 10; }); });
    assertEquals(10, success[0]);
  }

  public void testLambdaNestingInAnonymousCaptureLocal() {
    int[] x = new int[] {42};
    new Runnable() {
      public void run() {
        Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b;
        l.run(1, 2);
      }
    }.run();
    assertEquals(45, x[0]);
  }

  public void testLambdaNestingInMultipleMixedAnonymousCaptureLocal() {
    // checks that lambda has access to local variable and arguments when placed in mixed scopes
    // Local Class -> Local Class -> Local Anonymous -> lambda -> Local Anonymous
    class A {
      int a() {
        int[] x = new int[] {42};
        class B {
          void b() {
            I i = new I() {
              public int foo(Integer arg) {
                Runnable r = () -> {
                  new Runnable() {
                    public void run() {
                      Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b + arg;
                      l.run(1, 2);
                    }
                  }.run();
                };
                r.run();
                return x[0];
              }
            };
            i.foo(1);
          }
        }
        B b = new B();
        b.b();
        return x[0];
      }
    }
    A a = new A();
    assertEquals(46, a.a());
  }

  public void testLambdaNestingInMultipleMixedAnonymousCaptureLocal_withInterference() {
    // checks that lambda has access to NEAREST local variable and arguments when placed in mixed
    // scopes Local Class -> Local Class -> Local Anonymous -> lambda -> Local Anonymous
    class A {
      int a() {
        int[] x = new int[] {42};
        class B {
          int b() {
            int[] x = new int[] {22};
            I i = new I() {
              public int foo(Integer arg) {
                Runnable r = () -> {
                  new Runnable() {
                    public void run() {
                      Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b + arg;
                      l.run(1, 2);
                    }
                  }.run();
                };
                r.run();
                return x[0];
              }
            };
            return i.foo(1);
          }
        }
        B b = new B();
        return b.b();
      }
    }
    A a = new A();
    assertEquals(26, a.a());
  }

  public void testLambdaNestingInMultipleMixedAnonymousCaptureLocalAndField() {
    // checks that lambda has access to local variable, field and arguments when placed in mixed
    // scopes - Local Class -> Local Class -> Local Anonymous -> lambda -> Local Anonymous
    class A {
      int fA = 1;

      int a() {
        int[] x = new int[] {42};
        class B {
          int fB = 2;

          int b() {
            I i = new I() {
              int fI = 3;

              public int foo(Integer arg) {
                Runnable r = () -> {
                  new Runnable() {
                    public void run() {
                      Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b + arg + fA + fB + fI;
                      l.run(1, 2);
                    }
                  }.run();
                };
                r.run();
                return x[0];
              }
            };
            return i.foo(1);
          }
        }
        B b = new B();
        return b.b();
      }
    }
    A a = new A();
    assertEquals(52, a.a());
  }

  public void testLambdaNestingInMultipleAnonymousCaptureLocal() {
    // checks that lambda has access to local variable and arguments when placed in local anonymous
    // class with multile nesting
    int[] x = new int[] {42};
    int result = new I() {
      public int foo(Integer i1) {
        return new I() {
          public int foo(Integer i2) {
            return new I() {
              public int foo(Integer i3) {
                Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b + i1 + i2 + i3;
                return l.run(1, 2);
              }
            }.foo(3);
          }
        }.foo(2);
      }
    }.foo(1);
    assertEquals(51, x[0]);
  }

  static class TestLambda_ClassA {
    int[] f = new int[] {42};

    class B {
      void m() {
        Runnable r = () -> f[0] = f[0] + 1;
        r.run();
      }
    }

    int a() {
      B b = new B();
      b.m();
      return f[0];
    }
  }

  public void testLambdaNestingCaptureField_InnerClassCapturingOuterClassVariable() {
    TestLambda_ClassA a = new TestLambda_ClassA();
    assertEquals(43, a.a());
  }

  public void testInnerClassCaptureLocalFromOuterLambda() {
    int[] x = new int[] {42};
    Lambda<Integer> l = (a, b) -> {
      int[] x1 = new int[] {32};
      Lambda<Integer> r = (rA, rB) -> {
        int[] x2 = new int[] {22};
        I i = new I() {
          public int foo(Integer arg) {
            x1[0] = x1[0] + 1;
            x[0] = x[0] + 1;
            return x2[0] = x2[0] + rA + rB + a + b;
          }
        };
        return i.foo(1);
      };
      return r.run(3, 4) + x1[0];
    };

    // x1[0](32) + 1 + x2[0](22) + rA(3) + rB(4) + a(1) + b(2)
    assertEquals(65, l.run(1, 2).intValue());
    assertEquals(43, x[0]);
  }

  static class TestLambda_Class {
    public int[] s = new int[] {0};
    public void call(TestLambda_Outer a) {
      a.accept(() -> { });
    }
    class TestLambda_InnerClass {
      public int[] s = new int[] {0};
      public int test() {
        int[] s = new int[] {0};
        TestLambda_Class.this.call(
            sam0 -> TestLambda_Class.this.call(
                sam1 -> {
                  TestLambda_Class.this.call(
                    sam2 -> {
                      TestLambda_Class.this.s[0] = 10;
                      this.s[0] = 20;
                      s[0] = 30;
                    });
                  }));
        return s[0];
      }
    }
  }

  public void testLambdaNestingCaptureField() {
    TestLambda_Class a = new TestLambda_Class();
    a.call(sam1 -> { a.call(sam2 -> { a.s[0] = 20; }); });
    assertEquals(20, a.s[0]);
  }

  public void testLambdaMultipleNestingCaptureFieldAndLocal() {
    TestLambda_Class a = new TestLambda_Class();
    TestLambda_Class b = new TestLambda_Class();
    int [] s = new int [] {0};
    b.call(sam0 -> a.call(sam1 -> { a.call(sam2 -> { a.s[0] = 20; b.s[0] = 30; s[0] = 40; }); }));
    assertEquals(20, a.s[0]);
    assertEquals(30, b.s[0]);
    assertEquals(40, s[0]);
  }

  public void testLambdaMultipleNestingCaptureFieldAndLocalInnerClass() {
    TestLambda_Class a = new TestLambda_Class();
    TestLambda_Class.TestLambda_InnerClass b = a.new TestLambda_InnerClass();
    int result = b.test();
    assertEquals(10, a.s[0]);
    assertEquals(20, b.s[0]);
    assertEquals(30, result);
  }

  static class TestMF_A {
    public static String getId() {
      return "A";
    }
    public int getIdx() {
      return 1;
    }
  }
  static class TestMF_B {
    public static String getId() {
      return "B";
    }
    public int getIdx() {
      return 2;
    }
  }
  interface Function<T> {
    T apply();
  }
  private String f(Function<String> arg) {
    return arg.apply();
  }
  private int g(Function<Integer> arg) {
    return arg.apply().intValue();
  }

  public void testMethodRefWithSameName() {
    assertEquals("A", f(TestMF_A::getId));
    assertEquals("B", f(TestMF_B::getId));
    TestMF_A a = new TestMF_A();
    TestMF_B b = new TestMF_B();
    assertEquals(1, g(a::getIdx));
    assertEquals(2, g(b::getIdx));
  }

  // Test particular scenarios involving multiple path to inherit defaults.
  interface ITop {
    default String m() {
      return "ITop.m()";
    }
  }

  interface IRight extends ITop {
    default String m() {
      return "IRight.m()";
    }
  }

  interface ILeft extends ITop { }

  public void testMultipleDefaults_fromInterfaces_left() {
    class A implements ILeft, IRight { }

    assertEquals("IRight.m()", new A().m());
  }

  public void testMultipleDefaults_fromInterfaces_right() {
    class A implements IRight, ILeft { }

    assertEquals("IRight.m()", new A().m());
  }

  public void testMultipleDefaults_superclass_left() {
    class A implements ITop { }
    class B extends A implements ILeft, IRight { }

    assertEquals("IRight.m()", new B().m());
  }

  public void testMultipleDefaults_superclass_right() {
    class A implements ITop { }
    class B extends A implements IRight, ILeft { }

    assertEquals("IRight.m()", new B().m());
  }

  static class DefaultTrumpsOverSyntheticAbstractStub {
    interface SuperInterface {
      String m();
    }

    interface SubInterface extends SuperInterface {
      default String m() {
        return "SubInterface.m()";
      }
    }
  }

  public void testMultipleDefaults_defaultShadowsOverSyntheticAbstractStub() {
    abstract class A implements DefaultTrumpsOverSyntheticAbstractStub.SuperInterface { }
    class B extends A implements DefaultTrumpsOverSyntheticAbstractStub.SubInterface { }

    assertEquals("SubInterface.m()", new B().m());
  }

  static class DefaultTrumpsOverDefaultOnSuperAbstract {
    interface SuperInterface {
      default String m() {
        return "SuperInterface.m()";
      }
    }

    interface SubInterface extends SuperInterface {
      default String m() {
        return "SubInterface.m()";
      }
    }
  }

  public void testMultipleDefaults_defaultShadowsOverDefaultOnSuperAbstract() {
    abstract class A implements DefaultTrumpsOverDefaultOnSuperAbstract.SuperInterface { }
    class B extends A implements DefaultTrumpsOverDefaultOnSuperAbstract.SubInterface { }

    assertEquals("SubInterface.m()", new B().m());
  }

  interface InterfaceWithThisReference {
    default String n() {
      return "default n";
    }
    default String callNUnqualified() {
      class Super implements InterfaceWithThisReference {
        public String n() {
          return "super n";
        }
      }
      return new Super() {
        public String callNUnqualified() {
          return "Object " + n();
        }
      }.callNUnqualified();
    }
    default String callNWithThis() {
      class Super implements InterfaceWithThisReference {
        public String n() {
          return "super n";
        }
      }
      return new Super() {
        public String callNWithThis() {
          return "Object " + this.n();
        }
      }.callNWithThis();
    }
    default String callNWithInterfaceThis() {
      class Super implements InterfaceWithThisReference {
        public String n() {
          return "super n";
        }
      }
      return new Super() {
        public String callNWithInterfaceThis() {
          // In this method this has interface Test as its type, but it refers to outer n();
          return "Object " + InterfaceWithThisReference.this.n();
        }
      }.callNWithInterfaceThis();
    }
    default String callNWithSuper() {
      class Super implements InterfaceWithThisReference {
        public String n() {
          return "super n";
        }
      }
      return new Super() {
        public String callNWithSuper() {
          // In this method this has interface Test as its type.
          return "Object " + super.n();
        }
      }.callNWithSuper();
    }
    default String callNWithInterfaceSuper() {
      return new InterfaceWithThisReference() {
        public String n() {
          return "this n";
        }
        public String callNWithInterfaceSuper() {
          // In this method this has interface Test as its type and refers to default n();
          return "Object " + InterfaceWithThisReference.super.n();
        }
      }.callNWithInterfaceSuper();
    }
  }

  public void testInterfaceThis() {
    class A implements InterfaceWithThisReference {
      public String n() {
        return "n";
      }
    }
    assertEquals("Object super n", new A().callNUnqualified());
    assertEquals("Object super n", new A().callNWithThis());
    assertEquals("Object n", new A().callNWithInterfaceThis());
    assertEquals("Object super n", new A().callNWithSuper());
    assertEquals("Object default n", new A().callNWithInterfaceSuper());
  }

  private static List<String> initializationOrder;

  private static int get(String s) {
    initializationOrder.add(s);
    return 1;
  }

  interface A1 {
    int fa1 = get("A1");

    default void a1() { }
  }

  interface A2 {
    int fa2 = get("A2");

    default void a2() { }
  }

  interface A3 {
    int fa3 = get("A3");

    default void a3() { }
  }

  interface B1 extends A1 {
    int fb1 = get("B1");

    default void b1() { }
  }

  interface B2 extends A2 {
    int fb2 = get("B2");

    default void b2() { }
  }

  interface B3 extends A3 {
    int fb3 = get("B3");
  }

  static class C implements B1, A2  {
    static {
      get("C");
    }
  }

  static class D extends C implements B2, B3 {
    static {
      get("D");
    }
  }

  public void testInterfaceWithDefaultMethodsInitialization() {
    initializationOrder = new ArrayList<String>();
    new D();
    assertContentsInOrder(initializationOrder, "A1", "B1", "A2", "C", "B2", "A3", "D");
  }

  /**
   * Regression test for issue 9214.
   */
  interface P<T> {
    boolean apply(T obj);
  }

  static class B {
    public boolean getTrue() {
      return true;
    }
  }
  private static <T> String getClassName(T obj) {
    return obj.getClass().getSimpleName();
  }

  public void testMethodReference_generics() {
    P<B> p = B::getTrue;
    assertTrue(p.apply(new B()));
    // The next two method references must result in two different lambda implementations due
    // to generics, see bug # 9333.
    MyFunction1<B, String> f1 = Java8Test::getClassName;
    MyFunction1<Double, String> f2 = Java8Test::getClassName;

    assertEquals(B.class.getSimpleName(), f1.apply(new B()));
    assertEquals(Double.class.getSimpleName(), f2.apply(new Double(2)));
  }

  public void testDefaultMethod_staticInitializer() {
    SomeClass.initializationOrder = new ArrayList<String>();
    Object object = ImplementsWithDefaultMethodAndStaticInitializer.someClass;
    assertContentsInOrder(SomeClass.initializationOrder, "1", "2", "3", "4");
  }

  private void assertContentsInOrder(Iterable<String> contents, String... elements) {
    assertEquals(Arrays.asList(elements).toString(), contents.toString());
  }

  @JsType(isNative = true)
  interface  NativeJsTypeInterfaceWithStaticInitializationAndFieldAccess {
    @JsOverlay
    Object object = new Integer(3);
  }

  @JsType(isNative = true)
  interface NativeJsTypeInterfaceWithStaticInitializationAndStaticOverlayMethod {
    @JsOverlay
    Object object = new Integer(4);

    @JsOverlay
    static Object getObject() {
      return object;
    }
  }

  @JsType(isNative = true)
  interface NativeJsTypeInterfaceWithStaticInitializationAndInstanceOverlayMethod {
    @JsOverlay
    Object object = new Integer(5);

    int getA();

    @JsOverlay
    default Object getObject() {
      return ((int) object) + this.getA();
    }
  }

  private native NativeJsTypeInterfaceWithStaticInitializationAndInstanceOverlayMethod
      createNativeJsTypeInterfaceWithStaticInitializationAndInstanceOverlayMethod() /*-{
    return { getA: function() { return 1; } };
  }-*/;

  @JsType(isNative = true)
  interface NativeJsTypeInterfaceWithStaticInitialization {
    @JsOverlay
    Object object = new Integer(6);
  }

  @JsType(isNative = true)
  interface NativeJsTypeInterfaceWithComplexStaticInitialization {
    @JsOverlay
    Object object = (Integer) (((int) NativeJsTypeInterfaceWithStaticInitialization.object) + 1);
  }

  static class JavaTypeImplementingNativeJsTypeInterceWithDefaultMethod implements
      NativeJsTypeInterfaceWithStaticInitializationAndInstanceOverlayMethod {
    public int getA() {
      return 4;
    }
  }

  public void testNativeJsTypeWithStaticInitializer() {
    assertEquals(3, NativeJsTypeInterfaceWithStaticInitializationAndFieldAccess.object);
    assertEquals(
        4, NativeJsTypeInterfaceWithStaticInitializationAndStaticOverlayMethod.getObject());
    assertEquals(6,
        createNativeJsTypeInterfaceWithStaticInitializationAndInstanceOverlayMethod()
            .getObject());
    assertEquals(7, NativeJsTypeInterfaceWithComplexStaticInitialization.object);
    assertEquals(9, new JavaTypeImplementingNativeJsTypeInterceWithDefaultMethod().getObject());
  }

  @JsFunction
  interface VarargsFunction {
    String f(int i, String... args);
  }

  private static native String callFromJSNI(VarargsFunction f) /*-{
    return f(2, "a", "b", "c");
  }-*/;

  public void testJsVarargsLambda() {
    VarargsFunction function = (i, args) -> args[i];
    assertSame("b", function.f(1, "a", "b", "c"));
    assertSame("c", callFromJSNI(function));
    String[] pars = new String[] {"a", "b", "c"};
    assertSame("a", function.f(0, pars));
  }

  private static <T> T m(T s) {
    return s;
  }

  static class Some<T> {
    T s;
    MyFunction2<T, T ,T> combine;
    Some(T s, MyFunction2<T, T, T>  combine) {
      this.s = s;
      this.combine = combine;
    }
    public T m(T s2) {
      return combine.apply(s, s2);
    }
    public T m1() {
      return s;
    }
  }

  @FunctionalInterface
  interface MyFunction1<T, U> {
    U apply(T t);
  }

  @FunctionalInterface
  interface MyFunction2<T, U, V> {
    V apply(T t, U u);
  }

  @FunctionalInterface
  interface MyFunction3<T, U, V, W> {
    W apply(T t, U u, V v);
  }

  @FunctionalInterface
  interface IntFunction1<U> {
    U apply(int t);
  }

  @FunctionalInterface
  interface IntFunction2<V> {
    V apply(int t, int u);
  }

  @FunctionalInterface
  interface IntFunction3<W> {
    W apply(int t, int u, int v);
  }

  public void testMethodReference_implementedInSuperclass() {
    MyFunction1<StringBuilder, String> toString = StringBuilder::toString;
    assertEquals("Hello", toString.apply(new StringBuilder("Hello")));
  }

  static MyFunction2<String, String, String> concat = (s,t) -> s + t;

  public void testMethodReference_genericTypeParameters() {
    testMethodReference_genericTypeParameters(
        new Some<String>("Hell", concat), "Hell", "o", concat);
  }

  static String concat(String... strs) {
    String result = "";
    for (String s : strs) {
      result += s;
    }
    return result;
  }

  static String anotherConcat(String s1, String s2, String... strs) {
    String result = s1 + s2;
    for (String s : strs) {
      result += s;
    }
    return result;
  }

  public String instanceConcat(String... strs) {
    String result = "";
    for (String s : strs) {
      result += s;
    }
    return result;
  }

  public String anotherInstanceConcat(String s1, String... strs) {
    String result = s1;
    for (String s : strs) {
      result += s;
    }
    return result;
  }

  private static class ClassWithVarArgsConstructor {
    private class Inner {
      private int sum;
      Inner(int i, Integer... nums) {
        this.sum = ClassWithVarArgsConstructor.this.sum + i;
        for (Integer n: nums) {
          sum += n;
        }
      }
    }

    private int sum;
    ClassWithVarArgsConstructor(int i, Integer... nums) {
      sum = i;
      for (Integer n: nums) {
        sum += n;
      }
    }

    private MyFunction1<Integer, Inner> createInner1Param() {
      return (MyFunction1<Integer, Inner>) Inner::new;
    }

    private MyFunction2<Integer, Integer, Inner> createInner2Param() {
      return (MyFunction2<Integer, Integer, Inner>) Inner::new;
    }

    private MyFunction3<Integer, Integer, Integer, Inner> createInner3Param() {
      return (MyFunction3<Integer, Integer, Integer, Inner>) Inner::new;
    }

    private MyFunction2<Integer, Integer[], Inner> createInner2ParamArray() {
      return (MyFunction2<Integer, Integer[], Inner>) Inner::new;
    }

    private IntFunction1<Inner> createInner1IntParam() {
      return (IntFunction1<Inner>) Inner::new;
    }

    private IntFunction2<Inner> createInner2IntParam() {
      return (IntFunction2<Inner>) Inner::new;
    }

    private IntFunction3<Inner> createInner3IntParam() {
      return (IntFunction3<Inner>) Inner::new;
    }
  }

  public void testMethodReference_varargs() {
    // More functional arguments than varargs
    MyFunction2<String, String, String> concat = Java8Test::concat;
    assertEquals("ab", concat.apply("a", "b"));

    // Less functional arguments than varargs
    MyFunction2<String, String, String> anotherConcat = Java8Test::anotherConcat;
    assertEquals("ab", anotherConcat.apply("a", "b"));

    MyFunction2<Java8Test, String, String> instanceConcat = Java8Test::instanceConcat;
    assertEquals("a", instanceConcat.apply(this, "a"));

    MyFunction2<Java8Test, String, String> anotherInstanceConcat = Java8Test::anotherInstanceConcat;
    assertEquals("a", anotherInstanceConcat.apply(this, "a"));

    // constructor varargs
    MyFunction1<Integer, ClassWithVarArgsConstructor> constructor1Param =
        ClassWithVarArgsConstructor::new;
    assertEquals(1, constructor1Param.apply(1).sum);

    MyFunction2<Integer, Integer, ClassWithVarArgsConstructor> constructor2Param =
        ClassWithVarArgsConstructor::new;
    assertEquals(3, constructor2Param.apply(1, 2).sum);

    MyFunction3<Integer, Integer, Integer, ClassWithVarArgsConstructor> constructor3Param =
        ClassWithVarArgsConstructor::new;
    assertEquals(6, constructor3Param.apply(1, 2, 3).sum);

    MyFunction2<Integer, Integer[], ClassWithVarArgsConstructor> constructor2ParamArray =
        ClassWithVarArgsConstructor::new;
    assertEquals(6, constructor2ParamArray.apply(1, new Integer[] {2, 3}).sum);

    // constructor varargs + autoboxing
    IntFunction1<ClassWithVarArgsConstructor> constructor1IntParam =
        ClassWithVarArgsConstructor::new;
    assertEquals(1, constructor1IntParam.apply(1).sum);

    IntFunction2<ClassWithVarArgsConstructor> constructor2IntParam =
        ClassWithVarArgsConstructor::new;
    assertEquals(3, constructor2IntParam.apply(1, 2).sum);

    IntFunction3<ClassWithVarArgsConstructor> constructor3IntParam =
        ClassWithVarArgsConstructor::new;
    assertEquals(6, constructor3IntParam.apply(1, 2, 3).sum);

    ClassWithVarArgsConstructor outer = new ClassWithVarArgsConstructor(1);

    // inner class constructor varargs
    assertEquals(2, outer.createInner1Param().apply(1).sum);
    assertEquals(4, outer.createInner2Param().apply(1, 2).sum);
    assertEquals(7, outer.createInner3Param().apply(1, 2, 3).sum);
    assertEquals(7, outer.createInner2ParamArray().apply(1, new Integer[] {2, 3}).sum);
    
    // inner class constructor varargs + autoboxing
    assertEquals(2, outer.createInner1IntParam().apply(1).sum);
    assertEquals(4, outer.createInner2IntParam().apply(1, 2).sum);
    assertEquals(7, outer.createInner3IntParam().apply(1, 2, 3).sum);
  }

  private static <T> void testMethodReference_genericTypeParameters(
      Some<T> some, T t1, T t2, MyFunction2<T, T, T> combine) {
    T t1t2 = combine.apply(t1, t2);

    // Test all 4 flavours of methodReference
    // 1. Static method
    assertEquals(t1t2, ((MyFunction1<T, T>) Java8Test::m).apply(t1t2));
    // 2. Qualified instance method
    assertEquals(t1t2, ((MyFunction1<T, T>) some::m).apply(t2));
    // 3. Unqualified instance method
    assertEquals(t1, ((MyFunction1<Some<T>, T>) Some<T>::m1).apply(some));
    assertEquals("Hello",
        ((MyFunction1<Some<String>, String>)
              Some<String>::m1).apply(new Some<>("Hello", concat)));
    // 4. Constructor reference.
    assertEquals(t1t2,
        ((MyFunction2<T, MyFunction2<T, T, T>, Some<T>>) Some<T>::new).apply(t1t2, combine).m1());
  }

  static MyFunction2<Integer, Integer, Integer> addInteger = (s,t) -> s + t;

  @FunctionalInterface
  interface MyIntFunction1 {
    int apply(int t);
  }

  @FunctionalInterface
  interface MyIntFunction2 {
    int apply(int t, int u);
  }

  @FunctionalInterface
  interface MyIntFuncToSomeIntegeFunction2 {
    SomeInteger apply(int t, MyFunction2<Integer, Integer, Integer> u);
  }

  @FunctionalInterface
  interface MySomeIntegerFunction1 {
    int apply(SomeInteger t);
  }

  @FunctionalInterface
  interface MySomeIntegerIntFunction2 {
    int apply(SomeInteger t, int u);
  }

  static MyIntFunction2 addint = (s,t) -> s + t;

  static class SomeInteger {
    int s;
    MyFunction2<Integer, Integer ,Integer> combine;
    SomeInteger(int s, MyFunction2<Integer, Integer, Integer>  combine) {
      this.s = s;
      this.combine = combine;
    }
    public int m(int s2) {
      return combine.apply(s, s2);
    }
    public int m1() {
      return s;
    }
  }

  public void testMethodReference_autoboxing() {
    SomeInteger some = new SomeInteger(3, addInteger);

    // Test all 4 flavours of methodReference autoboxing parameters.
    // 1. Static method
    assertEquals((Integer) 5, ((MyFunction1<Integer, Integer>) Java8Test::m).apply(5));
    // 2. Qualified instance method
    assertEquals((Integer) 5, ((MyFunction1<Integer, Integer>) some::m).apply(2));
    // 3. Unqualified instance method
    assertEquals((Integer) 3, ((MyFunction1<SomeInteger, Integer>) SomeInteger::m1).apply(some));
    assertEquals((Integer) 5, ((MyFunction2<SomeInteger, Integer, Integer>)
        SomeInteger::m).apply(some, 2));
    assertEquals((Integer) 5,
        ((MyFunction1<SomeInteger, Integer>)
            SomeInteger::m1).apply(new SomeInteger(5, addInteger)));
    // 4. Constructor reference.
    assertEquals(5,
        ((MyFunction2<Integer, MyFunction2<Integer, Integer, Integer>, SomeInteger>)
            SomeInteger::new).apply(5, addInteger).m1());

    // Test all 4 flavours of methodReference (interface unboxed)
    // 1. Static method
    assertEquals(5, ((MyIntFunction1) Java8Test::m).apply(5));
    // 2. Qualified instance method
    assertEquals(5, ((MyIntFunction1) some::m).apply(2));
    // 3. Unqualified instance method
    assertEquals(3, ((MySomeIntegerFunction1) SomeInteger::m1).apply(some));
    // The next expression was the one that triggered bug #9346 where decisions on whether to
    // box/unbox were decided incorrectly due to differring number of parameters in the method
    // reference and the functional interface method.
    assertEquals(5, ((MySomeIntegerIntFunction2) SomeInteger::m).apply(some, 2));
    assertEquals(5,
        ((MySomeIntegerFunction1)
            SomeInteger::m1).apply(new SomeInteger(5, addInteger)));
    // 4. Constructor reference.
    assertEquals(5,
        ((MyIntFuncToSomeIntegeFunction2) SomeInteger::new).apply(5, addInteger).m1());
  }

  @JsType(isNative = true)
  private static class NativeClassWithJsOverlay {
    @JsOverlay
    public static String m(String s) {
      MyFunction1<String, String> id = (a) -> a;
      return id.apply(s);
    }
  }
  public void testNativeJsOverlay_lambda() {
    assertSame("Hello", NativeClassWithJsOverlay.m("Hello"));
  }

  interface IntefaceWithDefaultMethodAndLambda {
    boolean f();

    default BooleanPredicate fAsPredicate() {
      // This lambda will be defined as an instance method in the enclosing class, which is an
      // interface. In this case the methdod will be devirtualized.
      return () -> this.f();
    }
  }

  interface BooleanPredicate {
    boolean apply();
  }

  public void testLambdaCapturingThis_onDefaultMethod() {
    assertTrue(
        new IntefaceWithDefaultMethodAndLambda() {
          @Override
          public boolean f() {
            return true;
          }
        }.fAsPredicate().apply());
  }

  @JsFunction
  interface MyJsFunctionInterface {
    int foo(int a);
  }

  public void testJsFunction_lambda() {
    MyJsFunctionInterface jsFunctionInterface = a -> a + 2;
    assertEquals(12, callAsFunction(jsFunctionInterface, 10));
    assertEquals(12, jsFunctionInterface.foo(10));
  }

  private static native int callAsFunction(Object fn, int arg) /*-{
    return fn(arg);
  }-*/;

  @JsFunction
  interface MyJsFunctionInterfaceWithOverlay {
    Double m();
    @JsOverlay
    default Double callM() {
      return this.m();
    }
  }

  private static native MyJsFunctionInterfaceWithOverlay createNative() /*-{
    return function () { return 5; };
  }-*/;

  public void testJsFunction_withOverlay() {
    MyJsFunctionInterfaceWithOverlay f = new MyJsFunctionInterfaceWithOverlay() {
      @Override
      public Double m() {
        return new Double(2.0);
      }
    };
    assertEquals(2, f.callM().intValue());
    assertEquals(5, createNative().callM().intValue());
  }

  interface FunctionalExpressionBridges_I<T> {
    T apply(T t);
    // TODO(rluble): uncomment the line below to when bridges for default methods are created
    // in functional expressions
    FunctionalExpressionBridges_I<T> m(T t);
  }

  @FunctionalInterface
  interface FunctionalExpressionBridges_J<T extends Comparable>
      extends FunctionalExpressionBridges_I<T> {
    T apply(T t);

    // Overrides I.m() and specializes return type
    default FunctionalExpressionBridges_J<T> m(T t) {
      return this;
    }
  }

  public static String identity(String s) {
    return s;
  }

  public void testFunctionalExpressionBridges() {
    FunctionalExpressionBridges_J<String> ann = new FunctionalExpressionBridges_J<String>() {
      @Override
      public String apply(String string) {
        return string;
      }
    };

    assertBrigdeDispatchIsCorrect(ann);
    assertBrigdeDispatchIsCorrect((String s) -> s + "");
    assertBrigdeDispatchIsCorrect(Java8Test::identity);
  }

  private void assertBrigdeDispatchIsCorrect(
      FunctionalExpressionBridges_J<String> functionalExpression) {
    assertEquals("Hello", functionalExpression.m(null).apply("Hello"));
    assertEquals("Hello", functionalExpression.apply("Hello"));
    assertEquals("Hello",
        ((FunctionalExpressionBridges_I<String>) functionalExpression).apply("Hello"));
  }

  static class ClassWithAVeryLoooooooooooooooooooooooooooooooooooongName {
    public static String m() {
      return null;
    }
  }

  // Regression test for bug: #9426.
  public void testCorrectNaming() {
    Function<String> f = ClassWithAVeryLoooooooooooooooooooooooooooooooooooongName::m;
    assertNotNull(f);
  }

  @JsType(isNative = true)
  interface InterfaceWithOverlay {

    @JsProperty
    int getLength();

    @JsOverlay
    default int len() {
      return this.getLength();
    }
  }

  @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
  static abstract class SubclassImplementingInterfaceWithOverlay implements InterfaceWithOverlay {
  }

  // Regression test for bug: #9440
  public void testInterfaceWithOverlayAndNativeSubclass() {
    SubclassImplementingInterfaceWithOverlay object =
        (SubclassImplementingInterfaceWithOverlay) (Object) new int[]{1, 2, 3};
    assertEquals(3, object.len());
  }

  interface Producer<T> {
    T get();
  }

  private static Producer<Object> createInnerClassProducer() {
    class InnerClass {
    }
    return (Producer) InnerClass::new;
  }

  public void testLocalClassConstructorReferenceInStaticMethod() {
    assertTrue(createInnerClassProducer().get() != null);
  }

  // NOTE: DO NOT reorder the following classes, bug  #9453 is only reproducible in certain
  // orderings.
  interface SubSub_SuperDefaultMethodDevirtualizationOrder
      extends Sub_SuperDefaultMethodDevirtualizationOrder {
    default String m() {
      return Sub_SuperDefaultMethodDevirtualizationOrder.super.m();
    }
  }

  interface Sub_SuperDefaultMethodDevirtualizationOrder
      extends Super_SuperDefaultMethodDevirtualizationOrder {
    @Override
    default String m() {
      return Super_SuperDefaultMethodDevirtualizationOrder.super.m();
    }
  }

  interface Super_SuperDefaultMethodDevirtualizationOrder {
    default String m() {
      return "Hi";
    }
  }

  // Regression test for bug #9453.
  public void testDefaultMethodDevirtualizationOrder() {
    assertEquals("Hi", new SubSub_SuperDefaultMethodDevirtualizationOrder() {
    }.m());
  }

  private static String first(String... strings) {
    return strings[0];
  }

  // Regresion test for https://github.com/gwtproject/gwt/issues/9497
  public void testVarargsFunctionalConversion() {
    java.util.function.Function<String[], String> function = Java8Test::first;
    assertEquals("Hello", function.apply(new String[] {"Hello", "GoodBye"}));
  }

  interface SingleJsoImplA {
    String getAData();

    List<SingleJsoImplB> getListOfB();
  }

  interface SingleJsoImplB {
    String getBData();
  }

  private static final class AOverlay extends JavaScriptObject implements SingleJsoImplA {
    protected AOverlay() { }

    @Override
    public native String getAData() /*-{
      return this.data;
    }-*/;

    @Override
    public native List<SingleJsoImplB> getListOfB() /*-{
      return @java.util.Arrays::asList(*)(this.listOfb);
    }-*/;
  }

  private static final class BOverlay extends JavaScriptObject implements SingleJsoImplB {
    protected BOverlay() { }

    @Override
    public native String getBData() /*-{
      return this.data;
    }-*/;
  }

  private static SingleJsoImplA createA() {
    return JsonUtils.safeEval(
        "{\"data\":\"a value\",\"listOfb\":[{\"data\":\"b1\"},{\"data\":\"b2\"}]}");
  }

  // Regression for issue #9558
  public void testJSOLivenessSingleImplErasure() {
    SingleJsoImplA a = createA();
    String result = a.getListOfB().stream()
        .map(SingleJsoImplB::getBData).collect(Collectors.joining(","));
    assertEquals("b1,b2", result);
    result = a.getListOfB().stream()
        .map(b -> b.getBData()).collect(Collectors.joining(","));
    assertEquals("b1,b2", result);
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testLambdaErasureCasts() {
    List list = new ArrayList<String>();
    list.add("2");
    try {
      ((List<Integer>) list).stream().map(n -> n.intValue() == 2).findAny();
      fail("Should have thrown.");
    } catch (ClassCastException expected) {
    }
  }

  public void testLambdaBoxing() {
    BiFunction<Integer, Integer, Boolean> equals = (i, j) -> i + 0 == j;
    assertTrue(equals.apply(1,1));
    assertTrue(equals.apply(new Integer(2),2));
    assertTrue(equals.apply(new Integer(3), new Integer(3)));

    IntFunction<Integer> unboxBox = i -> i;
    assertEquals(2, (int) unboxBox.apply(2));
    assertEquals(2, (int) unboxBox.apply(new Integer(2)));
  }

  ////////////////////////////////////////////////////////////
  //
  //   Tests for language features introduced in Java 9
  
  class Resource implements AutoCloseable {
    boolean isOpen = true;

    public void close() {
      this.isOpen = false;
    }
  }

  public void testTryWithResourcesJava9() {
    Resource r1 = new Resource();
    assertTrue(r1.isOpen);
    Resource r2Copy;
    try (r1; Resource r2 = new Resource()) {
      assertTrue(r1.isOpen);
      assertTrue(r2.isOpen);
      r2Copy = r2;
    }
    assertFalse(r1.isOpen);
    assertFalse(r2Copy.isOpen);
  }

  private interface InterfaceWithPrivateMethods {
    int implementedMethod();

    default int defaultMethod() {
      return privateMethod();
    }

    private int privateMethod() {
      return implementedMethod();
    }

    private int staticPrivateMethod() {
      return 42;
    }
  }

  public void testInterfacePrivateMethodsJava9() {
    InterfaceWithPrivateMethods implementor = () -> 50;
    assertEquals(50, implementor.implementedMethod());
    assertEquals(50, implementor.defaultMethod());
    assertEquals(42, implementor.staticPrivateMethod());
  }

  public void testAnonymousDiamondJava9() {
    Supplier<String> helloSupplier = new Supplier<>() {
      @Override
      public String get() {
        return "hello";
      }
    };
    assertEquals("hello", helloSupplier.get());
  }

  interface Selector extends Predicate<String> {
    @Override
    boolean test(String object);

    default Selector trueSelector() {
      // Unused variable that creates a lambda with a bridge for the method test. The bug #9598
      // was caused by GwtAstBuilder associating the bridge method Lambda.test(Object) on the
      // lambda below to the method Predicate.test(Object), causing the method resolution in the
      // code that refers to the Predicate.test(Object) in the test below to refer to
      // Lambda.test(Object) which is the wrong method.
      return receiver -> true;
    }
  }

  // Regression tests for #9598
  public void testImproperMethodResolution() {
    Predicate p = o -> true;
    assertTrue(p.test(null));
  }
}
