/*******************************************************************************
 * Copyright (c) 2009, 2014 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.parser;

import java.io.File;
import java.io.IOException;
import junit.framework.Test;

import org.eclipse.jdt.core.tests.util.CompilerTestSetup;

@SuppressWarnings({ "rawtypes" })
public class LambdaExpressionSyntaxTest extends AbstractSyntaxTreeTest {

	private static String  jsr335TestScratchArea = "c:\\Jsr335TestScratchArea";
	private static String referenceCompiler = "C:\\jdk-7-ea-bin-b75-windows-i586-30_oct_2009\\jdk7\\bin\\javac.exe"; // TODO: Patch when RI becomes available.

	public static Class testClass() {
		return LambdaExpressionSyntaxTest.class;
	}
	public void initialize(CompilerTestSetup setUp) {
		super.initialize(setUp);
	}
	public static Test suite() {
		return buildMinimalComplianceTestSuite(testClass(), F_1_8);
	}

	public LambdaExpressionSyntaxTest(String testName){
		super(testName, referenceCompiler, jsr335TestScratchArea);
		if (referenceCompiler != null) {
			File f = new File(jsr335TestScratchArea);
			if (!f.exists()) {
				f.mkdir();
			}
			CHECK_ALL |= CHECK_JAVAC_PARSER;
		}
	}

	static {
		//		TESTS_NAMES = new String[] { "test0012" };
		//		TESTS_NUMBERS = new int[] { 133, 134, 135 };
		if (!(new File(referenceCompiler).exists())) {
			referenceCompiler = null;
			jsr335TestScratchArea = null;
		}
	}
	// type elided, unparenthesized parameter + expression body lambda in casting context.
	public void test0001() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        System.out.println(((I) x -> x * x).square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    System.out.println(((I) (<no type> x) -> (x * x)).square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0001", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda as initializer.
	public void test0002() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        I i =  x -> x * x;\n" +
				"        System.out.println(i.square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = (<no type> x) -> (x * x);\n" + 
				"    System.out.println(i.square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0002", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda as initializer, full lambda is parenthesized.
	public void test0003() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        I i =  ((((x -> x * x))));\n" +
				"        System.out.println(i.square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = (((((<no type> x) -> (x * x)))));\n" + 
				"    System.out.println(i.square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0003", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda as RHS of assignment, full lambda is parenthesized.
	public void test0004() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        I i;\n" +
				"        i =  (x -> x * x);\n" +
				"        System.out.println(i.square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i;\n" + 
				"    i = ((<no type> x) -> (x * x));\n" + 
				"    System.out.println(i.square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0004", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda in return statement, full lambda is parenthesized.
	public void test0005() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    static I getI() {\n" +
				"        return (x -> x * x);\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        I i = getI();\n" +
				"        System.out.println(i.square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  static I getI() {\n" + 
				"    return ((<no type> x) -> (x * x));\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = getI();\n" + 
				"    System.out.println(i.square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0005", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda in conditional expression.
	public void test0006() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        I i = args == null ? x -> x * x : x -> x * x * x;\n" +
				"        System.out.println(i.square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = ((args == null) ? (<no type> x) -> (x * x) : (<no type> x) -> ((x * x) * x));\n" + 
				"    System.out.println(i.square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0006", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda in message send.
	public void test0007() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    static void foo(I i1, I i2) {\n" +
				"        System.out.println(i1.square(10));\n" +
				"        System.out.println(i2.square(10));\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        foo(x -> x * x, x -> x * x * x);\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  static void foo(I i1, I i2) {\n" + 
				"    System.out.println(i1.square(10));\n" + 
				"    System.out.println(i2.square(10));\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    foo((<no type> x) -> (x * x), (<no type> x) -> ((x * x) * x));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0007", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda in constructor call.
	public void test0008() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    X (I i1, I i2) {\n" +
				"        System.out.println(i1.square(10));\n" +
				"        System.out.println(i2.square(10));\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        new X(x -> x * x, x -> x * x * x);\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  X(I i1, I i2) {\n" + 
				"    super();\n" + 
				"    System.out.println(i1.square(10));\n" + 
				"    System.out.println(i2.square(10));\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    new X((<no type> x) -> (x * x), (<no type> x) -> ((x * x) * x));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0008", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda in lambda.
	public void test0009() throws IOException {
		String source = 
				"interface I {\n" +
				"    I square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"      System.out.println (((I) a->b->c->d->e->f->g-> null).square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  I square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    System.out.println(((I) (<no type> a) -> (<no type> b) -> (<no type> c) -> (<no type> d) -> (<no type> e) -> (<no type> f) -> (<no type> g) -> null).square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0009", expectedUnitToString);
	}
	// type elided, unparenthesized parameter + expression body lambda in an initializer block
	public void test00010() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    static I i = x -> x * x;\n" +
				"    {\n" +
				"        i = x -> x * x * x;\n" +
				"    }\n" +
				"    static {\n" +
				"        i = x -> x * x * x;\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  static I i = (<no type> x) -> (x * x);\n" + 
				"  {\n" + 
				"    i = (<no type> x) -> ((x * x) * x);\n" + 
				"  }\n" + 
				"  static {\n" + 
				"    i = (<no type> x) -> ((x * x) * x);\n" + 
				"  }\n" + 
				"  <clinit>() {\n" + 
				"  }\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test00010", expectedUnitToString);
	}
	// type elided, parenthesized parameter + expression body lambda in casting context.
	public void test0011() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        System.out.println(((I) (x) -> x * x).square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    System.out.println(((I) (<no type> x) -> (x * x)).square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0011", expectedUnitToString);
	}
	// Normal & minimal parameter list + expression body lambda in assignment context.
	public void test0012() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        I i = (int x) -> x * x;\n" +
				"        System.out.println(i.square(10));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = (int x) -> (x * x);\n" + 
				"    System.out.println(i.square(10));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0012", expectedUnitToString);
	}
	// Normal parameter list, with modifiers & annotations  + expression body lambda in invocation context.
	public void test0013() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int x);\n" +
				"}\n" +
				"public class X {\n" +
				"    @interface Positive {}\n" +
				"    static void foo(I i1, I i2) {\n" +
				"        System.out.println(i1.square(10));\n" +
				"        System.out.println(i2.square(10));\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        foo((final int x) -> x * x, (final @Positive int x) -> x * x * x);\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  @interface Positive {\n" + 
				"  }\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  static void foo(I i1, I i2) {\n" + 
				"    System.out.println(i1.square(10));\n" + 
				"    System.out.println(i2.square(10));\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    foo((final int x) -> (x * x), (final @Positive int x) -> ((x * x) * x));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0013", expectedUnitToString);
	}
	// Vararg parameter list, with modifiers & annotations + expression body lambda in message send context.
	public void test0014() throws IOException {
		String source = 
				"interface I {\n" +
				"    int square(int ... x);\n" +
				"}\n" +
				"public class X {\n" +
				"    @interface Positive {}\n" +
				"    static void foo(I i1, I i2) {\n" +
				"        System.out.println(i1.square(10));\n" +
				"        System.out.println(i2.square(10));\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        foo((final int ... x) -> 10, (final @Positive int [] x) -> 20);\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int square(int... x);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  @interface Positive {\n" + 
				"  }\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  static void foo(I i1, I i2) {\n" + 
				"    System.out.println(i1.square(10));\n" + 
				"    System.out.println(i2.square(10));\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    foo((final int... x) -> 10, (final @Positive int[] x) -> 20);\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0014", expectedUnitToString);
	}
	// multi parameter type elided list + expression body lambda in return statement.
	public void test0015() throws IOException {
		String source = 
				"interface I {\n" +
				"    int product(int x, int y);\n" +
				"}\n" +
				"public class X {\n" +
				"    static I getI() {\n" +
				"        return ((x, y) -> x * y);\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        I i = getI();\n" +
				"        System.out.println(i.product(5, 6));\n" +
				"    }\n" +
				"};\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int product(int x, int y);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  static I getI() {\n" + 
				"    return ((<no type> x, <no type> y) -> (x * y));\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = getI();\n" + 
				"    System.out.println(i.product(5, 6));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0015", expectedUnitToString);
	}
	// multi parameter type specified list + block body lambda in return statement.
	public void test0016() throws IOException {
		String source = 
				"interface I {\n" +
				"    int product(int x, int y);\n" +
				"}\n" +
				"public class X {\n" +
				"    static I getI() {\n" +
				"        return (int x, int y) -> { return x * y; };\n" +
				"    }\n" +
				"    public static void main(String [] args) {\n" +
				"        I i = getI();\n" +
				"        System.out.println(i.product(5, 6));\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  int product(int x, int y);\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  static I getI() {\n" + 
				"    return (int x, int y) -> {\n" + 
				"  return (x * y);\n" + 
				"};\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    I i = getI();\n" + 
				"    System.out.println(i.product(5, 6));\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0016", expectedUnitToString);
	}
	// noarg + block body lambda 
	public void test0017() throws IOException {
		String source = 
				"interface I {\n" +
				"    String noarg();\n" +
				"}\n" +
				"public class X {\n" +
				"    public static void main(String [] args) {\n" +
				"        System.out.println( ((I) () -> { return \"noarg\"; }).noarg());\n" +
				"    }\n" +
				"}\n";

		String expectedUnitToString = 
				"interface I {\n" + 
				"  String noarg();\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"  public static void main(String[] args) {\n" + 
				"    System.out.println(((I) () -> {\n" + 
				"  return \"noarg\";\n" + 
				"}).noarg());\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0017", expectedUnitToString);
	}
	// Assorted tests.
	public void test0018() throws IOException {
		String source = 
				"interface I {\n" +
				"    void foo();\n" +
				"}\n" +
				"\n" +
				"interface J {\n" +
				"    int foo();\n" +
				"}\n" +
				"public class X {\n" +
				"  I i1 = ()->{}; \n" +
				"  J j1 = ()->0;\n" +
				"  J j2 = ()->{ return 0; };\n" +
				"  I i2 = ()->{ System.gc(); };\n" +
				"  J j3 = ()->{\n" +
				"    if (true) return 0;\n" +
				"    else {\n" +
				"      int r = 12;\n" +
				"      for (int i = 1; i < 8; i++)\n" +
				"        r += i;\n" +
				"      return r;\n" +
				"    }\n" +
				"  };\n" +
				"}\n";
		String expectedUnitToString = 
				"interface I {\n" + 
				"  void foo();\n" + 
				"}\n" + 
				"interface J {\n" + 
				"  int foo();\n" + 
				"}\n" + 
				"public class X {\n" + 
				"  I i1 = () ->   {\n" + 
				"  };\n" + 
				"  J j1 = () -> 0;\n" + 
				"  J j2 = () ->   {\n" + 
				"    return 0;\n" + 
				"  };\n" + 
				"  I i2 = () ->   {\n" + 
				"    System.gc();\n" + 
				"  };\n" + 
				"  J j3 = () ->   {\n" + 
				"    if (true)\n" + 
				"        return 0;\n" + 
				"    else\n" + 
				"        {\n" + 
				"          int r = 12;\n" + 
				"          for (int i = 1;; (i < 8); i ++) \n" + 
				"            r += i;\n" + 
				"          return r;\n" + 
				"        }\n" + 
				"  };\n" + 
				"  public X() {\n" + 
				"    super();\n" + 
				"  }\n" + 
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0018", expectedUnitToString);
	}

	// like test0001() but body expression is an assignment
	public void test0019() throws IOException {
		String source = 
				"interface I {\n" +
						"    int square(int x);\n" +
						"}\n" +
						"public class X {\n" +
						"    int y;\n" +
						"    public static void main(String [] args) {\n" +
						"        System.out.println(((I) x -> y = x * x ).square(10));\n" +
						"    }\n" +
						"}\n";
		
		String expectedUnitToString = 
				"interface I {\n" + 
						"  int square(int x);\n" + 
						"}\n" + 
						"public class X {\n" + 
						"  int y;\n" +
						"  public X() {\n" + 
						"    super();\n" + 
						"  }\n" + 
						"  public static void main(String[] args) {\n" + 
						"    System.out.println(((I) (<no type> x) -> y = (x * x)).square(10));\n" + 
						"  }\n" + 
						"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "test0019", expectedUnitToString);
	}
	
	// Coverage:  exercise this condition in Parser.consumeExpression():
	//   if (this.valueLambdaNestDepth >= 0 && this.stateStackLengthStack[this.valueLambdaNestDepth] == this.stateStackTop - 1)
	// make sure we see a (true && false) combination
	public void testNestedLambda01() throws IOException {
		String source = 
				"public class C {\n" +
				"	I foo() {\n" +
				"		return (i1, i2) -> 	(String x1, String x2) -> { \n" +
				"								return x1+x2; \n" + // here end-of-expression does not finish the type-eliding lambda (i1,i2)->...
				"							};\n" +
				"	}\n" +
				"}\n" +
				"\n" +
				"interface I {\n" +
				"	String doit(String s1, String s2);\n" +
				"}\n";
		String expectedUnitToString = 
				"public class C {\n" +
				"  public C() {\n" +
				"    super();\n" +
				"  }\n" +
				"  I foo() {\n" +
				"    return (<no type> i1, <no type> i2) -> (String x1, String x2) -> {\n" +
				"  return (x1 + x2);\n" +
				"};\n" +
				"  }\n" +
				"}\n" +
				"interface I {\n" +
				"  String doit(String s1, String s2);\n" +
				"}\n";
		checkParse(CHECK_PARSER | CHECK_JAVAC_PARSER , source.toCharArray(), null, "testNestedLambda01", expectedUnitToString);
	}
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385132
	public void test385132() throws IOException {
		String source = "->";
		String expectedErrorString = 
				"----------\n" +
				"1. ERROR in test385132 (at line 1)\n" +
				"	->\n" +
				"	^^\n" +
				"Syntax error on token \"->\", delete this token\n" +
				"----------\n";
				
		checkParse(CHECK_PARSER , source.toCharArray(), expectedErrorString, "test385132", null);
	}
}
