diff --git a/org.eclipse.jdt.debug.tests/java8/EvalTest18.java b/org.eclipse.jdt.debug.tests/java8/EvalTest18.java
index b7c82cb..02e72ba 100644
--- a/org.eclipse.jdt.debug.tests/java8/EvalTest18.java
+++ b/org.eclipse.jdt.debug.tests/java8/EvalTest18.java
@@ -19,17 +19,5 @@
 	public static void main(String[] args) {
 		List<String> strings = Arrays.asList("One", "Two", "Three");
 		System.out.println("Count of strings in stream from array =" + strings.stream().count());
-		nextMain();
 	}
-	
-	public static void nextMain() {
-		int someInt = 22; List<Integer> l = Arrays.asList(1,2,3,4);
-		
-		System.out.println("Just some int = " + someInt);
-		
-		for (int i : l ) {
-			System.out.println("i = " + i);
-		}
-	}
-	
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/java8/FunctionalCaptureTest18.java b/org.eclipse.jdt.debug.tests/java8/FunctionalCaptureTest18.java
deleted file mode 100644
index 32ef5ca..0000000
--- a/org.eclipse.jdt.debug.tests/java8/FunctionalCaptureTest18.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2020 Jesper Steen Møller and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Jesper Steen Møller - initial API and implementation
- *******************************************************************************/
-
-import java.util.Objects;
-import java.util.function.Function;
-
-public class FunctionalCaptureTest18 {
-	
-	FunctionalCaptureTest18(int field) {
-		publicField = field;
-	}
-	
-	public static void main(String[] args) {
-		new FunctionalCaptureTest18(1).runAssertions(1);
-	}
-
-	static <I, O> O assertFunctionalExpression(Function<I, O> functional, I input, O expected) {
-		O result = functional.apply(input);
-		if (!Objects.equals(result, expected)) {
-			throw new RuntimeException("Expected " + expected + ", got " + result);
-		}
-		return result;
-	}
-
-	@Override
-	public int hashCode() {
-		return 1992;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj || obj == null)
-			return false;
-		return getClass() == obj.getClass();
-	}
-
-	final public int publicField;
-	private int privateField = 2;
-
-	public static int publicStaticField = 3;
-	private static int privateStaticField = 4;
-
-	public Integer publicMethod() {
-		return 5;
-	}
-	private Integer privateMethod() {
-		return 6;
-	}
-	public int publicArgMethod(int i) {
-		return i + 6;
-	}
-	private int privateArgMethod(int i) {
-		return i + 7;
-	}
-	public static int publicStaticMethod(int i) {
-		return i - 8;
-	}
-	private static int privateStaticMethod(int i) {
-		return i - 9;
-	}
-	
-	public void runAssertions(int parameter /* = 1 */) {
-		int localConstI = -3;
-		System.out.println("Go!");
-		/* CHECK EXPRESSIONS BELOW */
-		/* Nothing captured */
-		assertFunctionalExpression(n -> -3, 42, -3);
-		assertFunctionalExpression(n -> n / 2 - 7, 10, -2);
-
-		/* Capture locals */
-		/* But not yet on project's types */
-		assertFunctionalExpression(n -> n + localConstI, 2, -1);
-		assertFunctionalExpression(n -> n - parameter, parameter, 0);
-
-		/* Capture instance fields */
-		/* But not yet on project's types */
-		assertFunctionalExpression(n -> n - publicField, 2, 1);/* SKIP */
-		assertFunctionalExpression(n -> n - privateField, 4, 2);/* SKIP */
-		
-		/* Capture static fields */
-		/* But not yet on project's types */
-		assertFunctionalExpression(n -> n - publicStaticField, 6, 3);/* SKIP */
-		assertFunctionalExpression(n -> n - privateStaticField, 8, 4);/* SKIP */
-
-		/* Evaluate unbound method references */
-		assertFunctionalExpression(FunctionalCaptureTest18::publicMethod, this, 5);/* SKIP */
-		assertFunctionalExpression(FunctionalCaptureTest18::privateMethod, this, 6);/* SKIP */
-
-		/* Evaluate instance method references */
-		assertFunctionalExpression("Hello, "::concat, "World", "Hello, World");
-		/* But not yet on project's types */
-		assertFunctionalExpression(this::publicArgMethod, 1, 7);/* SKIP */
-		assertFunctionalExpression(this::privateArgMethod, 1, 8);/* SKIP */
-
-		/* Evaluate static method references */
-		assertFunctionalExpression(Integer::valueOf, "16", 16);
-		/* But not yet on project's types */
-		assertFunctionalExpression(FunctionalCaptureTest18::publicStaticMethod, 17, 9);/* SKIP */
-		assertFunctionalExpression(FunctionalCaptureTest18::privateStaticMethod, 19, 10);/* SKIP */
-
-		/* Capture methods */
-		assertFunctionalExpression(s -> Integer.valueOf(s, 16), "0B", 11);
-		/* But not yet on project's types */
-		assertFunctionalExpression(obj -> obj.publicMethod() + 7, this, 12);/* SKIP */
-		assertFunctionalExpression(obj -> this.privateMethod() + 7, this, 13);/* SKIP */
-		assertFunctionalExpression(obj -> obj.publicMethod() + 9, this, 14);/* SKIP */
-		assertFunctionalExpression(obj -> this.privateMethod() + 9, this, 15);/* SKIP */
-
-		/* Constructor references */
-		assertFunctionalExpression(String::new, new char[] { 'a','b','c' }, "abc");
-		/* But not yet on project's types */
-		assertFunctionalExpression(FunctionalCaptureTest18::new, 42, new FunctionalCaptureTest18(42));/* SKIP */
-
-		/* END OF TESTS */
-		System.out.println("OK");
-	}
-}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
index ea193de..9a3e826 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -169,7 +169,6 @@
 import org.osgi.service.prefs.BackingStoreException;
 
 import com.sun.jdi.InternalException;
-import com.sun.jdi.InvocationException;
 
 import junit.framework.TestCase;
 
@@ -457,7 +456,6 @@
 	        if (!loaded18) {
 	        	jp = createProject(ONE_EIGHT_PROJECT_NAME, JavaProjectHelper.TEST_1_8_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false);
 	    		cfgs.add(createLaunchConfiguration(jp, "EvalTest18"));
-	    		cfgs.add(createLaunchConfiguration(jp, "FunctionalCaptureTest18"));
 	    		cfgs.add(createLaunchConfiguration(jp, "EvalTestIntf18"));
 				cfgs.add(createLaunchConfiguration(jp, "EvalIntfSuperDefault"));
 				cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest18"));
@@ -2847,10 +2845,10 @@
 			}
 			IEvaluationResult result = listener.getResult();
 			assertNotNull("The evaluation should have result: ", result);
-			assertNull("Evaluation of '" + snippet + "' should not have exception : " + findCause(result.getException()), result.getException());
+			assertNull("The evaluation should not have exception : " + result.getException(), result.getException());
 
 			String firstError = result.hasErrors() ? result.getErrorMessages()[0] : "";
-			assertFalse("The evaluation of '\" + snippet + \"'  should not have errors : " + firstError, result.hasErrors());
+			assertFalse("The evaluation should not have errors : " + firstError, result.hasErrors());
 			return listener.getResult().getValue();
 		}
 		finally {
@@ -2858,17 +2856,6 @@
 		}
 	}
 
-	private static Object findCause(DebugException problem) {
-		if (problem == null) {
-			return null;
-		}
-		Throwable cause = problem.getCause();
-		if (cause instanceof InvocationException) {
-			return ((InvocationException)cause).exception().toString();
-		}
-		return cause;
-	}
-
 	/**
 	 * @return true if the UI event loop should be proicessed during wait operations on UI thread
 	 */
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java8Tests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java8Tests.java
index 9353f40..9c14ddd 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java8Tests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java8Tests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014, 2020 Jesper S. Møller and others.
+ * Copyright (c) 2014, 2015 Jesper S. Møller and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -17,7 +17,6 @@
 package org.eclipse.jdt.debug.tests.eval;
 
 import org.eclipse.debug.core.model.IValue;
-import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
 import org.eclipse.jdt.debug.core.IJavaThread;
@@ -130,115 +129,4 @@
 			terminateAndRemove(thread);
 		}
 	}
-
-	/**
-	 * Evaluates a snippet containing a lambda
-	 *
-	 * @throws Exception
-	 */
-	public void testEvalLambda() throws Exception {
-		IJavaThread thread = null;
-		try {
-			String type = "EvalTest18";
-			IJavaLineBreakpoint bp = createLineBreakpoint(28, type);
-			assertNotNull("should have created breakpoint", bp);
-			thread = launchToBreakpoint(type);
-			assertNotNull("The program did not suspend", thread);
-			String snippet = "l.stream().filter(i -> i > 2).count()";
-			IValue result = doEval(thread, snippet);
-			assertEquals("2", result.getValueString());
-		} finally {
-			removeAllBreakpoints();
-			terminateAndRemove(thread);
-		}
-	}
-
-	/**
-	 * Evaluates a snippet containing a lambda referencing a variable in a loop
-	 *
-	 * @throws Exception
-	 */
-	public void testEvalLambdaInLoop() throws Exception {
-		IJavaThread thread = null;
-		try {
-			String type = "EvalTest18";
-			IJavaLineBreakpoint bp = createLineBreakpoint(31, type);
-			assertNotNull("should have created breakpoint", bp);
-			thread = launchToBreakpoint(type);
-			assertNotNull("The program did not suspend", thread);
-			String snippet = "l.stream().filter(j -> j > i+1).count()";
-			IValue result = doEval(thread, snippet);
-			assertEquals("2", result.getValueString());
-		} finally {
-			removeAllBreakpoints();
-			terminateAndRemove(thread);
-		}
-	}
-
-	/**
-	 * Evaluates a snippet containing a method reference
-	 *
-	 * @throws Exception
-	 */
-	public void testEvalMethodReference() throws Exception {
-		IJavaThread thread = null;
-		try {
-			String type = "EvalTest18";
-			IJavaLineBreakpoint bp = createLineBreakpoint(28, type);
-			assertNotNull("should have created breakpoint", bp);
-			thread = launchToBreakpoint(type);
-			assertNotNull("The program did not suspend", thread);
-			String snippet = "l.stream().mapToInt(Integer::bitCount).sum()";
-			IValue result = doEval(thread, snippet);
-			assertEquals("5", result.getValueString());
-		} finally {
-			removeAllBreakpoints();
-			terminateAndRemove(thread);
-		}
-	}
-
-	/**
-	 * Evaluates a snippet containing a method reference
-	 *
-	 * @throws Exception
-	 */
-	public void testContextEvaluations() throws Exception {
-		IJavaThread thread = null;
-		try {
-			String type = "FunctionalCaptureTest18";
-			ICompilationUnit cu = getType(type).getCompilationUnit();
-			String[] lines = new String(cu.getBuffer().getCharacters()).split("\n");
-
-			int i = 0;
-			for (; i < lines.length; ++i) {
-				if (lines[i].contains("/* CHECK EXPRESSIONS BELOW */")) break;
-			}
-			assertTrue("Missing source marker", i < lines.length);
-			IJavaLineBreakpoint bp = createLineBreakpoint(i, type);
-			assertNotNull("should have created breakpoint", bp);
-			thread = launchToBreakpoint(type);
-			assertNotNull("The program did not suspend", thread);
-			
-			for (; i < lines.length; ++i) {
-				String line = lines[i];
-				
-				if (line.contains("/* END OF TESTS */")) break; 
-				if (line.trim().startsWith("/") || line.trim().isEmpty()) continue; // Comment, just skip it
-				if (line.contains("/* SKIP */")) continue;
-				
-				int lastSemicolon = line.lastIndexOf(';');
-				assertTrue(lastSemicolon > 1);
-				String snippet = line.substring(0,  lastSemicolon).trim();
-				//System.out.println("*******************: " + snippet);
-				IValue result = doEval(thread, snippet);
-				assertNotNull(result);
-				//System.out.println(">>>>>>>>>>>>>>>>>>>: " + result.getReferenceTypeName());
-			}
-			
-		} finally {
-			removeAllBreakpoints();
-			terminateAndRemove(thread);
-		}
-	}
-
 }
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ExpressionBinder.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ExpressionBinder.java
deleted file mode 100644
index af86d6d..0000000
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ExpressionBinder.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.eclipse.jdt.internal.debug.eval;
-
-import org.eclipse.jdt.core.dom.IVariableBinding;
-
-public interface ExpressionBinder {
-	// Record and register the binding specified
-	void bind(IVariableBinding bind, String asVariableName);
-}
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluator.java
deleted file mode 100644
index 02224b9..0000000
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluator.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*******************************************************************************
-
- * Copyright (c) 2019 Jesper Steen Møller and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Jesper Steen Møller - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.debug.eval;
-
-import static org.eclipse.jdt.internal.eval.EvaluationConstants.LOCAL_VAR_PREFIX;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.model.IVariable;
-import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
-import org.eclipse.jdt.debug.core.IJavaArray;
-import org.eclipse.jdt.debug.core.IJavaArrayType;
-import org.eclipse.jdt.debug.core.IJavaClassObject;
-import org.eclipse.jdt.debug.core.IJavaClassType;
-import org.eclipse.jdt.debug.core.IJavaDebugTarget;
-import org.eclipse.jdt.debug.core.IJavaFieldVariable;
-import org.eclipse.jdt.debug.core.IJavaObject;
-import org.eclipse.jdt.debug.core.IJavaReferenceType;
-import org.eclipse.jdt.debug.core.IJavaThread;
-import org.eclipse.jdt.debug.core.IJavaType;
-import org.eclipse.jdt.debug.core.IJavaValue;
-import org.eclipse.jdt.debug.core.IJavaVariable;
-import org.eclipse.jdt.debug.core.JDIDebugModel;
-import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
-import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
-import org.eclipse.jdt.internal.debug.core.model.JDIValue;
-
-import com.sun.jdi.InvocationException;
-import com.sun.jdi.ObjectReference;
-
-/**
- * An evaluation engine that deploys class files to a debuggee by using Unsafe through the JDWP.
- */
-
-public class RemoteEvaluator {
-
-	private final LinkedHashMap<String, byte[]> classFiles;
-
-	private final String codeSnippetClassName;
-
-	private final List<String> variableNames;
-
-	private IJavaClassObject loadedClass = null;
-
-	/**
-	 * Constructs a new evaluation engine for the given VM in the context of the specified project. Class files required for the evaluation will be
-	 * deployed to the specified directory (which must be on the class path of the VM in order for evaluation to work).
-	 *
-	 * @param codeSnippetClassName
-	 * @param classFiles2
-	 * @param variableNames
-	 */
-	public RemoteEvaluator(LinkedHashMap<String, byte[]> classFiles, String codeSnippetClassName, List<String> variableNames) {
-		this.classFiles = classFiles;
-		this.codeSnippetClassName = codeSnippetClassName.replace('.', '/');
-		this.variableNames = variableNames;
-	}
-
-	private IJavaClassObject loadTheClasses(IJavaThread theThread) throws DebugException {
-
-		if (loadedClass != null) {
-			return loadedClass;
-		}
-
-		JDIDebugTarget debugTarget = ((JDIDebugTarget) theThread.getDebugTarget());
-		IJavaClassType unsafeClass = (IJavaClassType) findType("sun.misc.Unsafe", debugTarget); //$NON-NLS-1$
-
-		// IJavaValue[] getDeclaredFieldArgs = new IJavaValue[] { getDebugTarget().newValue("theUnsafe") }; //$NON-NLS-1$
-		IJavaFieldVariable theField = unsafeClass.getField("theUnsafe"); //$NON-NLS-1$
-		IJavaObject theUnsafe = (IJavaObject) theField.getValue();
-
-		// IJavaValue[] setAccessibleArgs = new IJavaValue[] { getDebugTarget().newValue(true) };
-		// theField.sendMessage(
-		// "setAccessible", "(Z)V", setAccessibleArgs, getThread(), false); //$NON-NLS-2$ //$NON-NLS-1$
-
-		// IJavaValue[] getArgs = new IJavaValue[] { getDebugTarget().newValue(null) };
-		// IJavaObject theUnsafe = (IJavaObject) theField
-		// .sendMessage(
-		// "get", "()Ljava/lang/Object;", getArgs, getThread(), false); //$NON-NLS-2$ //$NON-NLS-1$
-
-		IJavaClassObject theMainClass = null;
-
-		IJavaReferenceType byteArrayType = findType("byte[]", debugTarget);//$NON-NLS-1$
-
-		for (Map.Entry<String, byte[]> entry : classFiles.entrySet()) {
-			String className = entry.getKey();
-
-			IJavaReferenceType existingClass = tryLoadType(className, debugTarget);
-			if (existingClass != null) {
-				if (codeSnippetClassName.equals(className)) {
-					theMainClass = existingClass.getClassObject();
-				}
-			} else {
-				byte[] classBytes = entry.getValue();
-				IJavaArray byteArray = ((IJavaArrayType) byteArrayType).newInstance(classBytes.length);
-
-				IJavaValue[] debugClassBytes = new IJavaValue[classBytes.length];
-				for (int ix = 0; ix < classBytes.length; ++ix) {
-					debugClassBytes[ix] = ((JDIDebugTarget) theThread.getDebugTarget()).newValue(classBytes[ix]);
-				}
-				byteArray.setValues(debugClassBytes);
-				IJavaValue[] defineClassArgs = new IJavaValue[] {
-						debugTarget.newValue(className),
-						byteArray, // classBytes,
-						debugTarget.newValue(0), debugTarget.newValue(classBytes.length), debugTarget.nullValue(), // classloader
-						debugTarget.nullValue() // protection domain
-				};
-				IJavaClassObject theClass = (IJavaClassObject) theUnsafe.sendMessage("defineClass", "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", defineClassArgs, theThread, false); //$NON-NLS-1$//$NON-NLS-2$
-				if (codeSnippetClassName.equals(className)) {
-					theMainClass = theClass;
-				}
-			}
-		}
-		return theMainClass;
-	}
-
-	private IJavaReferenceType findType(String typeName, IJavaDebugTarget debugTarget) throws DebugException {
-		IJavaReferenceType theClass = tryLoadType(typeName, debugTarget);
-		if (theClass == null) {
-			// unable to load the class
-			throw new DebugException(
-					new Status(
-							IStatus.ERROR,
-							JDIDebugModel.getPluginIdentifier(),
-							DebugException.REQUEST_FAILED,
-							EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_instantiate_code_snippet_class__11,
-							null));
-		}
-		return theClass;
-	}
-
-	private IJavaReferenceType tryLoadType(String typeName, IJavaDebugTarget debugTarget) throws DebugException {
-		IJavaReferenceType clazz = null;
-		IJavaType[] types = debugTarget.getJavaTypes(typeName);
-		if (types != null && types.length > 0) {
-			clazz = (IJavaReferenceType) types[0];
-		}
-		return clazz;
-	}
-
-	/**
-	 * Initializes the value of instance variables in the 'code snippet object' that are used as place-holders for free variables and 'this' in the
-	 * current stack frame.
-	 *
-	 * @param object
-	 *            instance of code snippet class that will be run
-	 * @param boundValues
-	 *            popped values which should be injected into the code snippet object.
-	 * @exception DebugException
-	 *                if an exception is thrown accessing the given object
-	 */
-	protected void initializeFreeVars(IJavaObject object, IJavaValue boundValues[]) throws DebugException {
-		if (boundValues.length != this.variableNames.size()) {
-			throw new DebugException(new Status(IStatus.ERROR, JDIDebugModel.getPluginIdentifier(), DebugException.REQUEST_FAILED, EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_initialize_local_variables__4, null));
-		}
-
-		for (int i = 0; i < boundValues.length; ++i) {
-			IJavaVariable field = object.getField(new String(LOCAL_VAR_PREFIX) + this.variableNames.get(i), false);
-			if (field != null) {
-				IJavaValue bound = boundValues[i];
-				field.setValue(bound);
-			} else {
-				// System.out.print(Arrays.asList(((IJavaReferenceType) object.getJavaType()).getAllFieldNames()));
-				throw new DebugException(new Status(IStatus.ERROR, JDIDebugModel.getPluginIdentifier(), DebugException.REQUEST_FAILED, EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_initialize_local_variables__4, null));
-			}
-		}
-	}
-
-	/**
-	 * Constructs and returns a new instance of the specified class on the
-	 * target VM.
-	 *
-	 * @param className
-	 *            fully qualified class name
-	 * @return a new instance on the target, as an <code>IJavaValue</code>
-	 * @exception DebugException
-	 *                if creation fails
-	 */
-	protected IJavaObject newInstance(IJavaThread theThread) throws DebugException {
-		IJavaDebugTarget debugTarget = ((IJavaDebugTarget) theThread.getDebugTarget());
-
-		IJavaObject object = null;
-		IJavaClassObject clazz = loadTheClasses(theThread);
-		if (clazz == null) {
-			// The class is not loaded on the target VM.
-			// Force the load of the class.
-			IJavaType[] types = debugTarget.getJavaTypes("java.lang.Class"); //$NON-NLS-1$
-			IJavaClassType classClass = null;
-			if (types != null && types.length > 0) {
-				classClass = (IJavaClassType) types[0];
-			}
-			if (classClass == null) {
-				// unable to load the class
-				throw new DebugException(
-						new Status(
-								IStatus.ERROR,
-								JDIDebugModel.getPluginIdentifier(),
-								DebugException.REQUEST_FAILED,
-								EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_instantiate_code_snippet_class__11,
-								null));
-			}
-			IJavaValue[] args = new IJavaValue[] { debugTarget.newValue(
-					this.codeSnippetClassName) };
-			IJavaObject classObject = (IJavaObject) classClass
-					.sendMessage(
-							"forName", "(Ljava/lang/String;)Ljava/lang/Class;", args, theThread); //$NON-NLS-2$ //$NON-NLS-1$
-			object = (IJavaObject) classObject
-					.sendMessage(
-							"newInstance", "()Ljava/lang/Object;", null, theThread, false); //$NON-NLS-2$ //$NON-NLS-1$
-		} else {
-			object = (IJavaObject) clazz.sendMessage("newInstance", "()Ljava/lang/Object;", null, theThread, false); //$NON-NLS-2$ //$NON-NLS-1$
-			// object = clazz.newInstance("<init>", null, theThread); //$NON-NLS-1$
-		}
-		return object;
-	}
-
-	/**
-	 * Interprets and returns the result of the running the snippet class file.
-	 * The type of the result is described by an instance of
-	 * <code>java.lang.Class</code>. The value is interpreted based on the
-	 * result type.
-	 * <p>
-	 * Objects as well as primitive data types (boolean, int, etc.), have class
-	 * objects, which are created by the VM. If the class object represents a
-	 * primitive data type, then the associated value is stored in an instance
-	 * of its "object" class. For example, when the result type is the class
-	 * object for <code>int</code>, the result object is an instance of
-	 * <code>java.lang.Integer</code>, and the actual <code>int</code> is stored
-	 * in the </code>intValue()</code>. When the result type is the class object
-	 * for <code>java.lang.Integer</code> the result object is an instance of
-	 * <code>java.lang.Integer</code>, to be interpreted as a
-	 * <code>java.lang.Integer</code>.
-	 * </p>
-	 *
-	 * @param resultType
-	 *            the class of the result
-	 * @param resultValue
-	 *            the value of the result, to be interpreted based on
-	 *            resultType
-	 * @return the result of running the code snippet class file
-	 */
-	protected IJavaValue convertResult(IJavaDebugTarget debugTarget, IJavaClassObject resultType,
-			IJavaValue result) throws DebugException {
-		if (resultType == null) {
-			// there was an exception or compilation problem - no result
-			return null;
-		}
-
-		// check the type of the result - if a primitive type, convert it
-		String sig = resultType.getInstanceType().getSignature();
-		if (sig.equals("V") || sig.equals("Lvoid;")) { //$NON-NLS-2$ //$NON-NLS-1$
-			// void
-			return debugTarget.voidValue();
-		}
-
-		if (result.getJavaType() == null) {
-			// null result
-			return result;
-		}
-
-		if (sig.length() == 1) {
-			// primitive type - find the instance variable with the
-			// signature of the result type we are looking for
-			IVariable[] vars = result.getVariables();
-			IJavaVariable var = null;
-			for (IVariable var2 : vars) {
-				IJavaVariable jv = (IJavaVariable) var2;
-				if (!jv.isStatic() && jv.getSignature().equals(sig)) {
-					var = jv;
-					break;
-				}
-			}
-			if (var != null) {
-				return (IJavaValue) var.getValue();
-			}
-		} else {
-			// an object
-			return result;
-		}
-		throw new DebugException(
-				new Status(
-						IStatus.ERROR,
-						JDIDebugModel.getPluginIdentifier(),
-						DebugException.REQUEST_FAILED,
-						EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___internal_error_retreiving_result__17,
-						null));
-	}
-
-	/**
-	 * Returns a copy of the type name with '$' replaced by '.', or returns
-	 * <code>null</code> if the given type name refers to an anonymous inner
-	 * class.
-	 *
-	 * @param typeName
-	 *            a fully qualified type name
-	 * @return a copy of the type name with '$' replaced by '.', or returns
-	 *         <code>null</code> if the given type name refers to an anonymous
-	 *         inner class.
-	 */
-	protected String getTranslatedTypeName(String typeName) {
-		int index = typeName.lastIndexOf('$');
-		if (index == -1) {
-			return typeName;
-		}
-		if (index + 1 > typeName.length()) {
-			// invalid name
-			return typeName;
-		}
-		String last = typeName.substring(index + 1);
-		try {
-			Integer.parseInt(last);
-			return null;
-		} catch (NumberFormatException e) {
-			return typeName.replace('$', '.');
-		}
-	}
-
-	/**
-	 * Returns an array of simple type names that are part of the given type's
-	 * qualified name. For example, if the given name is <code>x.y.A$B</code>,
-	 * an array with <code>["A", "B"]</code> is returned.
-	 *
-	 * @param typeName
-	 *            fully qualified type name
-	 * @return array of nested type names
-	 */
-	protected String[] getNestedTypeNames(String typeName) {
-		int index = typeName.lastIndexOf('.');
-		if (index >= 0) {
-			typeName = typeName.substring(index + 1);
-		}
-		index = typeName.indexOf('$');
-		ArrayList<String> list = new ArrayList<>(1);
-		while (index >= 0) {
-			list.add(typeName.substring(0, index));
-			typeName = typeName.substring(index + 1);
-			index = typeName.indexOf('$');
-		}
-		list.add(typeName);
-		return list.toArray(new String[list.size()]);
-	}
-
-	/**
-	/**
-	 * Returns the name of the code snippet to instantiate to run the current
-	 * evaluation.
-	 *
-	 * @return the name of the deployed code snippet to instantiate and run
-	 */
-	protected String getCodeSnippetClassName() {
-		return codeSnippetClassName;
-	}
-
-	public IJavaValue evaluate(IJavaThread theThread, IJavaValue[] args) throws DebugException {
-		IJavaObject codeSnippetInstance = null;
-		IJavaDebugTarget debugTarget = ((IJavaDebugTarget) theThread.getDebugTarget());
-		try {
-			codeSnippetInstance = newInstance(theThread);
-			initializeFreeVars(codeSnippetInstance, args);
-			codeSnippetInstance.sendMessage(ICodeSnippetRequestor.RUN_METHOD, "()V", null, theThread, false); //$NON-NLS-1$
-
-			// now retrieve the description of the result
-			IVariable[] fields = codeSnippetInstance.getVariables();
-			IJavaVariable resultValue = null;
-			IJavaVariable resultType = null;
-			for (IVariable field : fields) {
-				if (field.getName().equals(ICodeSnippetRequestor.RESULT_TYPE_FIELD)) {
-					resultType = (IJavaVariable) field;
-				}
-				if (field.getName().equals(ICodeSnippetRequestor.RESULT_VALUE_FIELD)) {
-					resultValue = (IJavaVariable) field;
-				}
-			}
-			IJavaValue result = convertResult(debugTarget, (IJavaClassObject) resultType.getValue(), (IJavaValue) resultValue.getValue());
-			return result;
-		} catch (DebugException e) {
-			Throwable underlyingException = e.getStatus().getException();
-			if (underlyingException instanceof InvocationException) {
-				ObjectReference theException = ((InvocationException) underlyingException).exception();
-				if (theException != null) {
-					try {
-						try {
-							IJavaObject v = (IJavaObject) JDIValue.createValue((JDIDebugTarget) debugTarget, theException);
-							v.sendMessage("printStackTrace", "()V", null, theThread, false); //$NON-NLS-2$ //$NON-NLS-1$
-						} catch (DebugException de) {
-							JDIDebugPlugin.log(de);
-						}
-					} catch (RuntimeException re) {
-						JDIDebugPlugin.log(re);
-					}
-				}
-			}
-			throw e;
-		}
-	}
-
-	public int getVariableCount() {
-		return this.variableNames.size();
-	}
-
-	public String getVariableName(int i) {
-		return this.variableNames.get(i);
-	}
-}
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java
deleted file mode 100644
index acc9761..0000000
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java
+++ /dev/null
@@ -1,2064 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2019 Jesper Steen Møller and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Jesper Steen Møller - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.debug.eval;
-
-import static org.eclipse.jdt.internal.eval.EvaluationConstants.LOCAL_VAR_PREFIX;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.dom.*;
-import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
-
-/**
- * A builder for a reuseable expression evaluator against a runnng VM.
- */
-
-@SuppressWarnings("rawtypes")
-public class RemoteEvaluatorBuilder {
-
-	private IJavaProject javaProject;
-	private ExpressionBinder binder;
-	private String enclosingTypeName;
-	private boolean isStatic;
-	private boolean isConstructor;
-	private List<String> argumentNames = new ArrayList<>();
-	private List<String> argumentTypeNames = new ArrayList<>();
-
-	/**
-	 * The names and bytecodes of the code snippet class to instantiate
-	 */
-	private LinkedHashMap<String, byte[]> classFiles = new LinkedHashMap<>();
-
-	/**
-	 * The name of the code snippet class to instantiate
-	 */
-	private String codeSnippetClassName = null;
-	private String snippet = null;
-
-	public RemoteEvaluatorBuilder(IJavaProject javaProject, ExpressionBinder binder, String enclosingTypeName, boolean isStatic, boolean isConstructor) {
-		this.javaProject = javaProject;
-		this.binder = binder;
-		this.enclosingTypeName = enclosingTypeName;
-		this.isStatic = isStatic;
-		this.isConstructor = isConstructor;
-	}
-
-	public void acceptLambda(LambdaExpression lambda, ITypeBinding expectedResult) {
-		acceptFunctionalExpression(lambda, expectedResult);
-	}
-
-	public void acceptMethodReference(MethodReference node, ITypeBinding expectedResult) {
-		acceptFunctionalExpression(node, expectedResult);
-	}
-
-	private void acceptFunctionalExpression(Expression node, ITypeBinding expectedResult) {
-		FunctionalEvalVisitor visitor = new FunctionalEvalVisitor();
-		node.accept(visitor);
-		String castExpression = "(" + expectedResult.getQualifiedName() + ")"; //$NON-NLS-1$//$NON-NLS-2$
-		this.snippet = castExpression + "(" + visitor.buffer.toString() + ")"; //$NON-NLS-1$//$NON-NLS-2$
-	}
-
-	public String getSnippet() {
-		return snippet;
-	}
-
-	private static Object EVALUATE_CODE_SNIPPET_LOCK = new Object();
-
-	public RemoteEvaluator build() throws JavaModelException {
-
-		List<String> boundVariableNames = getVariableNames();
-		List<String> boundVariableTypeNames = getVariableTypeNames();
-
-		List<String> errors = new ArrayList<>();
-		IType enclosingType = this.javaProject.findType(enclosingTypeName);
-
-		synchronized (EVALUATE_CODE_SNIPPET_LOCK) {
-			this.javaProject.newEvaluationContext().evaluateCodeSnippet(this.snippet, boundVariableTypeNames.toArray(new String[boundVariableNames.size()]), boundVariableNames.toArray(new String[boundVariableNames.size()]), new int[boundVariableNames.size()], enclosingType, isStatic, isConstructor, new ICodeSnippetRequestor() {
-
-				@Override
-				public void acceptProblem(IMarker problemMarker, String fragmentSource, int fragmentKind) {
-					errors.add(problemMarker.toString());
-				}
-
-				@Override
-				public boolean acceptClassFiles(byte[][] classFileBytes, String[][] classFileCompoundNames, String mainCodeSnippetClassName) {
-					for (int i = 0; i < classFileCompoundNames.length; ++i) {
-						String className = makeClassName(classFileCompoundNames[i]);
-						classFiles.put(className, classFileBytes[i]);
-					}
-					if (mainCodeSnippetClassName != null) {
-						setCodeSnippetClassName(mainCodeSnippetClassName);
-					}
-					return true;
-				}
-			}, null);
-		}
-
-		if (!errors.isEmpty()) {
-			//LE//$NON-NLS-1$
-			//LE//$NON-NLS-1$
-			throw new RuntimeException(errors.toString());
-		}
-
-		return new RemoteEvaluator(classFiles, codeSnippetClassName, getVariableNames());
-	}
-
-	private void setCodeSnippetClassName(String codeSnippetClassName) {
-		this.codeSnippetClassName = codeSnippetClassName;
-	}
-
-	private static String makeClassName(String[] names) {
-		StringBuilder sb = new StringBuilder();
-		for (int j = 0; j < names.length; j++) {
-			if (j > 0) {
-				sb.append('/');
-			}
-			sb.append(names[j]);
-		}
-		return sb.toString();
-	}
-
-	public List<String> getVariableTypeNames() {
-		return Collections.unmodifiableList(argumentTypeNames);
-	}
-
-	public List<String> getVariableNames() {
-		return Collections.unmodifiableList(argumentNames);
-	}
-
-	public String allocateNewVariable(IVariableBinding binding) {
-		String varName = "bound$" + argumentNames.size(); //$NON-NLS-1$
-		argumentNames.add(varName);
-		argumentTypeNames.add(binding.getType().getQualifiedName());
-		return varName;
-	}
-
-	public IJavaProject getJavaProject() {
-		return javaProject;
-	}
-
-	public String getEnclosingTypeName() {
-		return enclosingTypeName;
-	}
-
-	public boolean isStatic() {
-		return isStatic;
-	}
-
-	/**
-	 * Internal synonym for {@link MethodDeclaration#getReturnType()}. Use to alleviate deprecation warnings.
-	 *
-	 * @deprecated
-	 * @since 3.4
-	 */
-	@Deprecated
-	private static Type getReturnType(MethodDeclaration node) {
-		return node.getReturnType();
-	}
-
-	/**
-	 * Internal synonym for {@link TypeDeclaration#getSuperclass()}. Use to alleviate deprecation warnings.
-	 *
-	 * @deprecated
-	 * @since 3.4
-	 */
-	@Deprecated
-	private static Name getSuperclass(TypeDeclaration node) {
-		return node.getSuperclass();
-	}
-
-	/**
-	 * Internal synonym for {@link TypeDeclarationStatement#getTypeDeclaration()}. Use to alleviate deprecation warnings.
-	 *
-	 * @deprecated
-	 * @since 3.4
-	 */
-	@Deprecated
-	private static TypeDeclaration getTypeDeclaration(TypeDeclarationStatement node) {
-		return node.getTypeDeclaration();
-	}
-
-	/**
-	 * Internal synonym for {@link MethodDeclaration#thrownExceptions()}. Use to alleviate deprecation warnings.
-	 *
-	 * @deprecated
-	 * @since 3.10
-	 */
-	@Deprecated
-	private static List<?> thrownExceptions(MethodDeclaration node) {
-		return node.thrownExceptions();
-	}
-
-	private class FunctionalEvalVisitor extends ASTVisitor {
-
-		/**
-		 * The string buffer into which the serialized representation of the AST is written.
-		 */
-		protected StringBuilder buffer = new StringBuilder();
-
-		/**
-		 * Returns the string accumulated in the visit.
-		 *
-		 * @return the serialized
-		 */
-		// public String getResult() {
-		// return buffer.toString();
-		// }
-
-		// public Map<String, ITypeBinding> getCaptures() {
-		// return Collections.emptyMap();
-		// }
-
-		private int indent = 2;
-
-		private Map<IBinding, String> localBindings = new HashMap<>();
-
-		public FunctionalEvalVisitor() {
-		}
-
-		boolean isLocalBinding(IBinding binding) {
-			return localBindings.containsKey(binding);
-		}
-
-		void addLocalBinding(IBinding binding, String name) {
-			localBindings.put(binding, name);
-		}
-
-		void printIndent() {
-			for (int i = 0; i < indent; i++) {
-				buffer.append("  ");//$NON-NLS-1$
-			}
-		}
-
-		/**
-		 * Internal synonym for {@link AST#JLS2}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 */
-		@Deprecated
-		private static final int JLS2 = AST.JLS2;
-
-		/**
-		 * Internal synonym for {@link AST#JLS3}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 */
-		@Deprecated
-		private static final int JLS3 = AST.JLS3;
-
-		/**
-		 * Internal synonym for {@link AST#JLS4}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 */
-		@Deprecated
-		private static final int JLS4 = AST.JLS4;
-
-		/**
-		 * Internal synonym for {@link AST#JLS8}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 */
-		@Deprecated
-		private static final int JLS8 = AST.JLS8;
-
-		/**
-		 * Internal synonym for {@link AST#JLS9}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 */
-		@Deprecated
-		private static final int JLS9 = AST.JLS9;
-
-		/**
-		 * Internal synonym for {@link ClassInstanceCreation#getName()}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 */
-		@Deprecated
-		private Name getName(ClassInstanceCreation node) {
-			return node.getName();
-		}
-
-		/**
-		 * Appends the text representation of the given modifier flags, followed by a single space. Used for JLS2 modifiers.
-		 *
-		 * @param modifiers
-		 *            the modifier flags
-		 */
-		void printModifiers(int modifiers) {
-			if (Modifier.isPublic(modifiers)) {
-				buffer.append("public ");//$NON-NLS-1$
-			}
-			if (Modifier.isProtected(modifiers)) {
-				buffer.append("protected ");//$NON-NLS-1$
-			}
-			if (Modifier.isPrivate(modifiers)) {
-				buffer.append("private ");//$NON-NLS-1$
-			}
-			if (Modifier.isStatic(modifiers)) {
-				buffer.append("static ");//$NON-NLS-1$
-			}
-			if (Modifier.isAbstract(modifiers)) {
-				buffer.append("abstract ");//$NON-NLS-1$
-			}
-			if (Modifier.isFinal(modifiers)) {
-				buffer.append("final ");//$NON-NLS-1$
-			}
-			if (Modifier.isSynchronized(modifiers)) {
-				buffer.append("synchronized ");//$NON-NLS-1$
-			}
-			if (Modifier.isVolatile(modifiers)) {
-				buffer.append("volatile ");//$NON-NLS-1$
-			}
-			if (Modifier.isNative(modifiers)) {
-				buffer.append("native ");//$NON-NLS-1$
-			}
-			if (Modifier.isStrictfp(modifiers)) {
-				buffer.append("strictfp ");//$NON-NLS-1$
-			}
-			if (Modifier.isTransient(modifiers)) {
-				buffer.append("transient ");//$NON-NLS-1$
-			}
-		}
-
-		/**
-		 * Appends the text representation of the given modifier flags, followed by a single space. Used for 3.0 modifiers and annotations.
-		 *
-		 * @param ext
-		 *            the list of modifier and annotation nodes (element type: <code>IExtendedModifiers</code>)
-		 */
-		void printModifiers(List ext) {
-			for (Iterator it = ext.iterator(); it.hasNext();) {
-				ASTNode p = (ASTNode) it.next();
-				p.accept(this);
-				buffer.append(" ");//$NON-NLS-1$
-			}
-		}
-
-		private void printTypes(List<Type> types, String prefix) {
-			if (types.size() > 0) {
-				buffer.append(" " + prefix + " ");//$NON-NLS-1$ //$NON-NLS-2$
-				Type type = types.get(0);
-				type.accept(this);
-				for (int i = 1, l = types.size(); i < l; ++i) {
-					buffer.append(","); //$NON-NLS-1$
-					type = types.get(0);
-					type.accept(this);
-				}
-			}
-		}
-
-		/**
-		 * reference node helper function that is common to all the difference reference nodes.
-		 *
-		 * @param typeArguments
-		 *            list of type arguments
-		 */
-		private void visitReferenceTypeArguments(List typeArguments) {
-			buffer.append("::");//$NON-NLS-1$
-			if (!typeArguments.isEmpty()) {
-				buffer.append('<');
-				for (Iterator it = typeArguments.iterator(); it.hasNext();) {
-					Type t = (Type) it.next();
-					t.accept(this);
-					if (it.hasNext()) {
-						buffer.append(',');
-					}
-				}
-				buffer.append('>');
-			}
-		}
-
-		private void visitTypeAnnotations(AnnotatableType node) {
-			if (node.getAST().apiLevel() >= JLS8) {
-				visitAnnotationsList(node.annotations());
-			}
-		}
-
-		private void visitAnnotationsList(List annotations) {
-			for (Iterator it = annotations.iterator(); it.hasNext();) {
-				Annotation annotation = (Annotation) it.next();
-				annotation.accept(this);
-				buffer.append(' ');
-			}
-		}
-
-		/**
-		 * Internal synonym for {@link TypeDeclaration#superInterfaces()}. Use to alleviate deprecation warnings.
-		 *
-		 * @deprecated
-		 * @since 3.4
-		 */
-		@Deprecated
-		private List superInterfaces(TypeDeclaration node) {
-			return node.superInterfaces();
-		}
-
-		@Override
-		public boolean visit(AnnotationTypeDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printIndent();
-			printModifiers(node.modifiers());
-			buffer.append("@interface ");//$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append(" {");//$NON-NLS-1$
-			for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) {
-				BodyDeclaration d = (BodyDeclaration) it.next();
-				d.accept(this);
-			}
-			buffer.append("}\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(AnnotationTypeMemberDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printIndent();
-			printModifiers(node.modifiers());
-			node.getType().accept(this);
-			buffer.append(" ");//$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append("()");//$NON-NLS-1$
-			if (node.getDefault() != null) {
-				buffer.append(" default ");//$NON-NLS-1$
-				node.getDefault().accept(this);
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(AnonymousClassDeclaration node) {
-			buffer.append("{\n");//$NON-NLS-1$
-			indent++;
-			for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) {
-				BodyDeclaration b = (BodyDeclaration) it.next();
-				b.accept(this);
-			}
-			indent--;
-			printIndent();
-			buffer.append("}\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ArrayAccess node) {
-			node.getArray().accept(this);
-			buffer.append("[");//$NON-NLS-1$
-			node.getIndex().accept(this);
-			buffer.append("]");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ArrayCreation node) {
-			buffer.append("new ");//$NON-NLS-1$
-			ArrayType at = node.getType();
-			int dims = at.getDimensions();
-			Type elementType = at.getElementType();
-			elementType.accept(this);
-			for (Iterator it = node.dimensions().iterator(); it.hasNext();) {
-				buffer.append("[");//$NON-NLS-1$
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				buffer.append("]");//$NON-NLS-1$
-				dims--;
-			}
-			// add empty "[]" for each extra array dimension
-			for (int i = 0; i < dims; i++) {
-				buffer.append("[]");//$NON-NLS-1$
-			}
-			if (node.getInitializer() != null) {
-				node.getInitializer().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(ArrayInitializer node) {
-			buffer.append("{");//$NON-NLS-1$
-			for (Iterator it = node.expressions().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append("}");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ArrayType node) {
-			if (node.getAST().apiLevel() < JLS8) {
-				visitComponentType(node);
-				buffer.append("[]");//$NON-NLS-1$
-			} else {
-				node.getElementType().accept(this);
-				List dimensions = node.dimensions();
-				int size = dimensions.size();
-				for (int i = 0; i < size; i++) {
-					Dimension aDimension = (Dimension) dimensions.get(i);
-					aDimension.accept(this);
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(AssertStatement node) {
-			printIndent();
-			buffer.append("assert ");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			if (node.getMessage() != null) {
-				buffer.append(" : ");//$NON-NLS-1$
-				node.getMessage().accept(this);
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(Assignment node) {
-			node.getLeftHandSide().accept(this);
-			buffer.append(node.getOperator().toString());
-			node.getRightHandSide().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(Block node) {
-			buffer.append("{\n");//$NON-NLS-1$
-			indent++;
-			for (Iterator it = node.statements().iterator(); it.hasNext();) {
-				Statement s = (Statement) it.next();
-				s.accept(this);
-			}
-			indent--;
-			printIndent();
-			buffer.append("}\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(BlockComment node) {
-			printIndent();
-			buffer.append("/* */");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(BooleanLiteral node) {
-			if (node.booleanValue() == true) {
-				buffer.append("true");//$NON-NLS-1$
-			} else {
-				buffer.append("false");//$NON-NLS-1$
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(BreakStatement node) {
-			printIndent();
-			buffer.append("break");//$NON-NLS-1$
-			if (node.getLabel() != null) {
-				buffer.append(" ");//$NON-NLS-1$
-				node.getLabel().accept(this);
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(CastExpression node) {
-			buffer.append("(");//$NON-NLS-1$
-			node.getType().accept(this);
-			buffer.append(")");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(CatchClause node) {
-			buffer.append("catch (");//$NON-NLS-1$
-			node.getException().accept(this);
-			buffer.append(") ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(CharacterLiteral node) {
-			buffer.append(node.getEscapedValue());
-			return false;
-		}
-
-		@Override
-		public boolean visit(ClassInstanceCreation node) {
-			if (node.getExpression() != null) {
-				node.getExpression().accept(this);
-				buffer.append(".");//$NON-NLS-1$
-			}
-			buffer.append("new ");//$NON-NLS-1$
-			if (node.getAST().apiLevel() == JLS2) {
-				getName(node).accept(this);
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (!node.typeArguments().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeArguments().iterator(); it.hasNext();) {
-						Type t = (Type) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-				node.getType().accept(this);
-			}
-			buffer.append("(");//$NON-NLS-1$
-			for (Iterator it = node.arguments().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-			if (node.getAnonymousClassDeclaration() != null) {
-				node.getAnonymousClassDeclaration().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(CompilationUnit node) {
-			if (node.getAST().apiLevel() >= JLS9) {
-				if (node.getModule() != null) {
-					node.getModule().accept(this);
-				}
-			}
-			if (node.getPackage() != null) {
-				node.getPackage().accept(this);
-			}
-			for (Iterator it = node.imports().iterator(); it.hasNext();) {
-				ImportDeclaration d = (ImportDeclaration) it.next();
-				d.accept(this);
-			}
-			for (Iterator it = node.types().iterator(); it.hasNext();) {
-				AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next();
-				d.accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(ConditionalExpression node) {
-			node.getExpression().accept(this);
-			buffer.append(" ? ");//$NON-NLS-1$
-			node.getThenExpression().accept(this);
-			buffer.append(" : ");//$NON-NLS-1$
-			node.getElseExpression().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(ConstructorInvocation node) {
-			printIndent();
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (!node.typeArguments().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeArguments().iterator(); it.hasNext();) {
-						Type t = (Type) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-			}
-			buffer.append("this(");//$NON-NLS-1$
-			for (Iterator it = node.arguments().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(");\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ContinueStatement node) {
-			printIndent();
-			buffer.append("continue");//$NON-NLS-1$
-			if (node.getLabel() != null) {
-				buffer.append(" ");//$NON-NLS-1$
-				node.getLabel().accept(this);
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(CreationReference node) {
-			node.getType().accept(this);
-			visitReferenceTypeArguments(node.typeArguments());
-			buffer.append("new");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(Dimension node) {
-			List annotations = node.annotations();
-			if (annotations.size() > 0) {
-				buffer.append(' ');
-			}
-			visitAnnotationsList(annotations);
-			buffer.append("[]"); //$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(DoStatement node) {
-			printIndent();
-			buffer.append("do ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			buffer.append(" while (");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(");\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(EmptyStatement node) {
-			printIndent();
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(EnhancedForStatement node) {
-			printIndent();
-			buffer.append("for (");//$NON-NLS-1$
-			node.getParameter().accept(this);
-			buffer.append(" : ");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(") ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(EnumConstantDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printIndent();
-			printModifiers(node.modifiers());
-			node.getName().accept(this);
-			if (!node.arguments().isEmpty()) {
-				buffer.append("(");//$NON-NLS-1$
-				for (Iterator it = node.arguments().iterator(); it.hasNext();) {
-					Expression e = (Expression) it.next();
-					e.accept(this);
-					if (it.hasNext()) {
-						buffer.append(",");//$NON-NLS-1$
-					}
-				}
-				buffer.append(")");//$NON-NLS-1$
-			}
-			if (node.getAnonymousClassDeclaration() != null) {
-				node.getAnonymousClassDeclaration().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(EnumDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printIndent();
-			printModifiers(node.modifiers());
-			buffer.append("enum ");//$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append(" ");//$NON-NLS-1$
-			if (!node.superInterfaceTypes().isEmpty()) {
-				buffer.append("implements ");//$NON-NLS-1$
-				for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext();) {
-					Type t = (Type) it.next();
-					t.accept(this);
-					if (it.hasNext()) {
-						buffer.append(", ");//$NON-NLS-1$
-					}
-				}
-				buffer.append(" ");//$NON-NLS-1$
-			}
-			buffer.append("{");//$NON-NLS-1$
-			for (Iterator it = node.enumConstants().iterator(); it.hasNext();) {
-				EnumConstantDeclaration d = (EnumConstantDeclaration) it.next();
-				d.accept(this);
-				// enum constant declarations do not include punctuation
-				if (it.hasNext()) {
-					// enum constant declarations are separated by commas
-					buffer.append(", ");//$NON-NLS-1$
-				}
-			}
-			if (!node.bodyDeclarations().isEmpty()) {
-				buffer.append("; ");//$NON-NLS-1$
-				for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) {
-					BodyDeclaration d = (BodyDeclaration) it.next();
-					d.accept(this);
-					// other body declarations include trailing punctuation
-				}
-			}
-			buffer.append("}\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ExportsDirective node) {
-			return visit(node, "exports"); //$NON-NLS-1$
-		}
-
-		@Override
-		public boolean visit(ExpressionMethodReference node) {
-			node.getExpression().accept(this);
-			visitReferenceTypeArguments(node.typeArguments());
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(ExpressionStatement node) {
-			printIndent();
-			node.getExpression().accept(this);
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(FieldAccess node) {
-			node.getExpression().accept(this);
-			buffer.append(".");//$NON-NLS-1$
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(FieldDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printIndent();
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-			}
-			node.getType().accept(this);
-			buffer.append(" ");//$NON-NLS-1$
-			for (Iterator it = node.fragments().iterator(); it.hasNext();) {
-				VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
-				f.accept(this);
-				if (it.hasNext()) {
-					buffer.append(", ");//$NON-NLS-1$
-				}
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ForStatement node) {
-			printIndent();
-			buffer.append("for (");//$NON-NLS-1$
-			for (Iterator it = node.initializers().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(", ");//$NON-NLS-1$
-				}
-			}
-			buffer.append("; ");//$NON-NLS-1$
-			if (node.getExpression() != null) {
-				node.getExpression().accept(this);
-			}
-			buffer.append("; ");//$NON-NLS-1$
-			for (Iterator it = node.updaters().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(", ");//$NON-NLS-1$
-				}
-			}
-			buffer.append(") ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(IfStatement node) {
-			printIndent();
-			buffer.append("if (");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(") ");//$NON-NLS-1$
-			node.getThenStatement().accept(this);
-			if (node.getElseStatement() != null) {
-				buffer.append(" else ");//$NON-NLS-1$
-				node.getElseStatement().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(ImportDeclaration node) {
-			printIndent();
-			buffer.append("import ");//$NON-NLS-1$
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (node.isStatic()) {
-					buffer.append("static ");//$NON-NLS-1$
-				}
-			}
-			node.getName().accept(this);
-			if (node.isOnDemand()) {
-				buffer.append(".*");//$NON-NLS-1$
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(InfixExpression node) {
-			node.getLeftOperand().accept(this);
-			buffer.append(' '); // for cases like x= i - -1; or x= i++ + ++i;
-			buffer.append(node.getOperator().toString());
-			buffer.append(' ');
-			node.getRightOperand().accept(this);
-			final List extendedOperands = node.extendedOperands();
-			if (extendedOperands.size() != 0) {
-				buffer.append(' ');
-				for (Iterator it = extendedOperands.iterator(); it.hasNext();) {
-					buffer.append(node.getOperator().toString()).append(' ');
-					Expression e = (Expression) it.next();
-					e.accept(this);
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(Initializer node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-			}
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(InstanceofExpression node) {
-			node.getLeftOperand().accept(this);
-			buffer.append(" instanceof ");//$NON-NLS-1$
-			node.getRightOperand().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(IntersectionType node) {
-			for (Iterator it = node.types().iterator(); it.hasNext();) {
-				Type t = (Type) it.next();
-				t.accept(this);
-				if (it.hasNext()) {
-					buffer.append(" & "); //$NON-NLS-1$
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(Javadoc node) {
-			printIndent();
-			buffer.append("/** ");//$NON-NLS-1$
-			for (Iterator it = node.tags().iterator(); it.hasNext();) {
-				ASTNode e = (ASTNode) it.next();
-				e.accept(this);
-			}
-			buffer.append("\n */\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(LabeledStatement node) {
-			printIndent();
-			node.getLabel().accept(this);
-			buffer.append(": ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(LambdaExpression node) {
-			boolean hasParentheses = node.hasParentheses();
-			if (hasParentheses) {
-				buffer.append('(');
-			}
-			for (Iterator it = node.parameters().iterator(); it.hasNext();) {
-				VariableDeclaration v = (VariableDeclaration) it.next();
-				v.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			if (hasParentheses) {
-				buffer.append(')');
-			}
-			buffer.append(" -> "); //$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(LineComment node) {
-			buffer.append("//\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(MarkerAnnotation node) {
-			buffer.append("@");//$NON-NLS-1$
-			node.getTypeName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(MemberRef node) {
-			if (node.getQualifier() != null) {
-				node.getQualifier().accept(this);
-			}
-			buffer.append("#");//$NON-NLS-1$
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(MemberValuePair node) {
-			node.getName().accept(this);
-			buffer.append("=");//$NON-NLS-1$
-			node.getValue().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(MethodDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printIndent();
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-				if (!node.typeParameters().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeParameters().iterator(); it.hasNext();) {
-						TypeParameter t = (TypeParameter) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-			}
-			if (!node.isConstructor()) {
-				if (node.getAST().apiLevel() == JLS2) {
-					getReturnType(node).accept(this);
-				} else {
-					if (node.getReturnType2() != null) {
-						node.getReturnType2().accept(this);
-					} else {
-						// methods really ought to have a return type
-						buffer.append("void");//$NON-NLS-1$
-					}
-				}
-				buffer.append(" ");//$NON-NLS-1$
-			}
-			node.getName().accept(this);
-			buffer.append("(");//$NON-NLS-1$
-			if (node.getAST().apiLevel() >= JLS8) {
-				Type receiverType = node.getReceiverType();
-				if (receiverType != null) {
-					receiverType.accept(this);
-					buffer.append(' ');
-					SimpleName qualifier = node.getReceiverQualifier();
-					if (qualifier != null) {
-						qualifier.accept(this);
-						buffer.append('.');
-					}
-					buffer.append("this"); //$NON-NLS-1$
-					if (node.parameters().size() > 0) {
-						buffer.append(',');
-					}
-				}
-			}
-			for (Iterator it = node.parameters().iterator(); it.hasNext();) {
-				SingleVariableDeclaration v = (SingleVariableDeclaration) it.next();
-				v.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-			int size = node.getExtraDimensions();
-			if (node.getAST().apiLevel() >= JLS8) {
-				List dimensions = node.extraDimensions();
-				for (int i = 0; i < size; i++) {
-					visit((Dimension) dimensions.get(i));
-				}
-			} else {
-				for (int i = 0; i < size; i++) {
-					buffer.append("[]"); //$NON-NLS-1$
-				}
-			}
-			if (node.getAST().apiLevel() < JLS8) {
-				if (!thrownExceptions(node).isEmpty()) {
-					buffer.append(" throws ");//$NON-NLS-1$
-					for (Iterator it = thrownExceptions(node).iterator(); it.hasNext();) {
-						Name n = (Name) it.next();
-						n.accept(this);
-						if (it.hasNext()) {
-							buffer.append(", ");//$NON-NLS-1$
-						}
-					}
-					buffer.append(" ");//$NON-NLS-1$
-				}
-			} else {
-				if (!node.thrownExceptionTypes().isEmpty()) {
-					buffer.append(" throws ");//$NON-NLS-1$
-					for (Iterator it = node.thrownExceptionTypes().iterator(); it.hasNext();) {
-						Type n = (Type) it.next();
-						n.accept(this);
-						if (it.hasNext()) {
-							buffer.append(", ");//$NON-NLS-1$
-						}
-					}
-					buffer.append(" ");//$NON-NLS-1$
-				}
-			}
-			if (node.getBody() == null) {
-				buffer.append(";\n");//$NON-NLS-1$
-			} else {
-				node.getBody().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(MethodInvocation node) {
-			if (node.getExpression() != null) {
-				node.getExpression().accept(this);
-				buffer.append(".");//$NON-NLS-1$
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (!node.typeArguments().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeArguments().iterator(); it.hasNext();) {
-						Type t = (Type) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-			}
-			node.getName().accept(this);
-			buffer.append("(");//$NON-NLS-1$
-			for (Iterator it = node.arguments().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(MethodRef node) {
-			if (node.getQualifier() != null) {
-				node.getQualifier().accept(this);
-			}
-			buffer.append("#");//$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append("(");//$NON-NLS-1$
-			for (Iterator it = node.parameters().iterator(); it.hasNext();) {
-				MethodRefParameter e = (MethodRefParameter) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(MethodRefParameter node) {
-			node.getType().accept(this);
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (node.isVarargs()) {
-					buffer.append("...");//$NON-NLS-1$
-				}
-			}
-			if (node.getName() != null) {
-				buffer.append(" ");//$NON-NLS-1$
-				node.getName().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(Modifier node) {
-			buffer.append(node.getKeyword().toString());
-			return false;
-		}
-
-		@Override
-		public boolean visit(ModuleDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			printModifiers(node.annotations());
-			if (node.isOpen()) {
-				buffer.append("open "); //$NON-NLS-1$
-			}
-			buffer.append("module"); //$NON-NLS-1$
-			buffer.append(" "); //$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append(" {\n"); //$NON-NLS-1$
-			indent++;
-			for (ModuleDirective stmt : (List<ModuleDirective>) node.moduleStatements()) {
-				stmt.accept(this);
-			}
-			indent--;
-			buffer.append("}"); //$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		/*
-		 * @see ASTVisitor#visit(ModuleModifier)
-		 *
-		 * @since 3.14
-		 */
-		public boolean visit(ModuleModifier node) {
-			buffer.append(node.getKeyword().toString());
-			return false;
-		}
-
-		private boolean visit(ModulePackageAccess node, String keyword) {
-			printIndent();
-			buffer.append(keyword);
-			buffer.append(" ");//$NON-NLS-1$
-			node.getName().accept(this);
-			printTypes(node.modules(), "to"); //$NON-NLS-1$
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(NameQualifiedType node) {
-			node.getQualifier().accept(this);
-			buffer.append('.');
-			visitTypeAnnotations(node);
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(NormalAnnotation node) {
-			buffer.append("@");//$NON-NLS-1$
-			node.getTypeName().accept(this);
-			buffer.append("(");//$NON-NLS-1$
-			for (Iterator it = node.values().iterator(); it.hasNext();) {
-				MemberValuePair p = (MemberValuePair) it.next();
-				p.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(NullLiteral node) {
-			buffer.append("null");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(NumberLiteral node) {
-			buffer.append(node.getToken());
-			return false;
-		}
-
-		@Override
-		public boolean visit(OpensDirective node) {
-			return visit(node, "opens"); //$NON-NLS-1$
-		}
-
-		@Override
-		public boolean visit(PackageDeclaration node) {
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (node.getJavadoc() != null) {
-					node.getJavadoc().accept(this);
-				}
-				for (Iterator it = node.annotations().iterator(); it.hasNext();) {
-					Annotation p = (Annotation) it.next();
-					p.accept(this);
-					buffer.append(" ");//$NON-NLS-1$
-				}
-			}
-			printIndent();
-			buffer.append("package ");//$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ParameterizedType node) {
-			node.getType().accept(this);
-			buffer.append("<");//$NON-NLS-1$
-			for (Iterator it = node.typeArguments().iterator(); it.hasNext();) {
-				Type t = (Type) it.next();
-				t.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(">");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ParenthesizedExpression node) {
-			buffer.append("(");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(")");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(PostfixExpression node) {
-			node.getOperand().accept(this);
-			buffer.append(node.getOperator().toString());
-			return false;
-		}
-
-		@Override
-		public boolean visit(PrefixExpression node) {
-			buffer.append(node.getOperator().toString());
-			node.getOperand().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(PrimitiveType node) {
-			visitTypeAnnotations(node);
-			buffer.append(node.getPrimitiveTypeCode().toString());
-			return false;
-		}
-
-		@Override
-		public boolean visit(ProvidesDirective node) {
-			printIndent();
-			buffer.append("provides");//$NON-NLS-1$
-			buffer.append(" ");//$NON-NLS-1$
-			node.getName().accept(this);
-			printTypes(node.implementations(), "with"); //$NON-NLS-1$
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(QualifiedName node) {
-			node.getQualifier().accept(this);
-			buffer.append(".");//$NON-NLS-1$
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(QualifiedType node) {
-			node.getQualifier().accept(this);
-			buffer.append(".");//$NON-NLS-1$
-			visitTypeAnnotations(node);
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(RequiresDirective node) {
-			printIndent();
-			buffer.append("requires");//$NON-NLS-1$
-			buffer.append(" ");//$NON-NLS-1$
-			printModifiers(node.modifiers());
-			node.getName().accept(this);
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ReturnStatement node) {
-			printIndent();
-			buffer.append("return");//$NON-NLS-1$
-			if (node.getExpression() != null) {
-				buffer.append(" ");//$NON-NLS-1$
-				node.getExpression().accept(this);
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(SimpleName node) {
-			IBinding binding = node.resolveBinding();
-			if (!isLocalBinding(binding)) {
-				if (binding instanceof IVariableBinding) {
-					IVariableBinding vb = ((IVariableBinding) binding);
-					Object constant = vb.getConstantValue();
-					if (constant != null) {
-						buffer.append(constant);
-						return false;
-					}
-					if (!vb.isField()) {
-						String newVarName = new String(LOCAL_VAR_PREFIX) + allocateNewVariable((IVariableBinding) binding);
-						binder.bind((IVariableBinding) binding, newVarName);
-						buffer.append("this."); //$NON-NLS-1$
-						buffer.append(newVarName);
-						return false;
-					}
-				}
-			}
-
-			buffer.append(node.getIdentifier());
-			return false;
-		}
-
-		@Override
-		public boolean visit(SimpleType node) {
-			visitTypeAnnotations(node);
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(SingleMemberAnnotation node) {
-			buffer.append("@");//$NON-NLS-1$
-			node.getTypeName().accept(this);
-			buffer.append("(");//$NON-NLS-1$
-			node.getValue().accept(this);
-			buffer.append(")");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(SingleVariableDeclaration node) {
-			printIndent();
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-			}
-			node.getType().accept(this);
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (node.isVarargs()) {
-					if (node.getAST().apiLevel() >= JLS8) {
-						List annotations = node.varargsAnnotations();
-						if (annotations.size() > 0) {
-							buffer.append(' ');
-						}
-						visitAnnotationsList(annotations);
-					}
-					buffer.append("...");//$NON-NLS-1$
-				}
-			}
-			buffer.append(" ");//$NON-NLS-1$
-			node.getName().accept(this);
-			int size = node.getExtraDimensions();
-			if (node.getAST().apiLevel() >= JLS8) {
-				List dimensions = node.extraDimensions();
-				for (int i = 0; i < size; i++) {
-					visit((Dimension) dimensions.get(i));
-				}
-			} else {
-				for (int i = 0; i < size; i++) {
-					buffer.append("[]"); //$NON-NLS-1$
-				}
-			}
-			if (node.getInitializer() != null) {
-				buffer.append("=");//$NON-NLS-1$
-				node.getInitializer().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(StringLiteral node) {
-			buffer.append(node.getEscapedValue());
-			return false;
-		}
-
-		@Override
-		public boolean visit(SuperConstructorInvocation node) {
-			printIndent();
-			if (node.getExpression() != null) {
-				node.getExpression().accept(this);
-				buffer.append(".");//$NON-NLS-1$
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (!node.typeArguments().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeArguments().iterator(); it.hasNext();) {
-						Type t = (Type) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-			}
-			buffer.append("super(");//$NON-NLS-1$
-			for (Iterator it = node.arguments().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(");\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(SuperFieldAccess node) {
-			if (node.getQualifier() != null) {
-				node.getQualifier().accept(this);
-				buffer.append(".");//$NON-NLS-1$
-			}
-			buffer.append("super.");//$NON-NLS-1$
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(SuperMethodInvocation node) {
-			if (node.getQualifier() != null) {
-				node.getQualifier().accept(this);
-				buffer.append(".");//$NON-NLS-1$
-			}
-			buffer.append("super.");//$NON-NLS-1$
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (!node.typeArguments().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeArguments().iterator(); it.hasNext();) {
-						Type t = (Type) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-			}
-			node.getName().accept(this);
-			buffer.append("(");//$NON-NLS-1$
-			for (Iterator it = node.arguments().iterator(); it.hasNext();) {
-				Expression e = (Expression) it.next();
-				e.accept(this);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-			return false;
-		}
-
-		/*
-		 * @see ASTVisitor#visit(SuperMethodReference)
-		 *
-		 * @since 3.10
-		 */
-		@Override
-		public boolean visit(SuperMethodReference node) {
-			if (node.getQualifier() != null) {
-				node.getQualifier().accept(this);
-				buffer.append('.');
-			}
-			buffer.append("super");//$NON-NLS-1$
-			visitReferenceTypeArguments(node.typeArguments());
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(SwitchCase node) {
-			if ((node.getAST().isPreviewEnabled())) {
-				if (node.isDefault()) {
-					buffer.append("default");//$NON-NLS-1$
-					buffer.append(node.isSwitchLabeledRule() ? " ->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
-				} else {
-					buffer.append("case ");//$NON-NLS-1$
-					for (Iterator it = node.expressions().iterator(); it.hasNext();) {
-						Expression t = (Expression) it.next();
-						t.accept(this);
-						buffer.append(it.hasNext() ? ", " : //$NON-NLS-1$
-								node.isSwitchLabeledRule() ? " ->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
-					}
-				}
-			} else {
-				if (node.isDefault()) {
-					buffer.append("default :\n");//$NON-NLS-1$
-				} else {
-					buffer.append("case ");//$NON-NLS-1$
-					getSwitchExpression(node).accept(this);
-					buffer.append(":\n");//$NON-NLS-1$
-				}
-			}
-			indent++; // decremented in visit(SwitchStatement)
-			return false;
-		}
-
-		/**
-		 * @deprecated
-		 */
-		@Deprecated
-		private Expression getSwitchExpression(SwitchCase node) {
-			return node.getExpression();
-		}
-
-		private void visitSwitchNode(ASTNode node) {
-			buffer.append("switch (");//$NON-NLS-1$
-			if (node instanceof SwitchExpression) {
-				((SwitchExpression) node).getExpression().accept(this);
-			} else if (node instanceof SwitchStatement) {
-				((SwitchStatement) node).getExpression().accept(this);
-			}
-			buffer.append(") ");//$NON-NLS-1$
-			buffer.append("{\n");//$NON-NLS-1$
-			indent++;
-			if (node instanceof SwitchExpression) {
-				for (Iterator it = ((SwitchExpression) node).statements().iterator(); it.hasNext();) {
-					Statement s = (Statement) it.next();
-					s.accept(this);
-					indent--; // incremented in visit(SwitchCase)
-				}
-			} else if (node instanceof SwitchStatement) {
-				for (Iterator it = ((SwitchStatement) node).statements().iterator(); it.hasNext();) {
-					Statement s = (Statement) it.next();
-					s.accept(this);
-					indent--; // incremented in visit(SwitchCase)
-				}
-			}
-			indent--;
-			printIndent();
-			buffer.append("}\n");//$NON-NLS-1$
-
-		}
-
-		@Override
-		public boolean visit(SwitchExpression node) {
-			visitSwitchNode(node);
-			return false;
-		}
-
-		@Override
-		public boolean visit(SwitchStatement node) {
-			visitSwitchNode(node);
-			return false;
-		}
-
-		@Override
-		public boolean visit(SynchronizedStatement node) {
-			buffer.append("synchronized (");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(") ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(TagElement node) {
-			return false;
-		}
-
-		@Override
-		public boolean visit(TextBlock node) {
-			buffer.append(node.getEscapedValue());
-			return false;
-		}
-
-		@Override
-		public boolean visit(TextElement node) {
-			buffer.append(node.getText());
-			return false;
-		}
-
-		@Override
-		public boolean visit(ThisExpression node) {
-			if (node.getQualifier() != null) {
-				node.getQualifier().accept(this);
-				buffer.append(".");//$NON-NLS-1$
-			}
-			buffer.append("this");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(ThrowStatement node) {
-			printIndent();
-			buffer.append("throw ");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(TryStatement node) {
-			printIndent();
-			buffer.append("try ");//$NON-NLS-1$
-			if (node.getAST().apiLevel() >= JLS4) {
-				List resources = node.resources();
-				if (!resources.isEmpty()) {
-					buffer.append('(');
-					for (Iterator it = resources.iterator(); it.hasNext();) {
-						Expression variable = (Expression) it.next();
-						variable.accept(this);
-						if (it.hasNext()) {
-							buffer.append(';');
-						}
-					}
-					buffer.append(')');
-				}
-			}
-			node.getBody().accept(this);
-			buffer.append(" ");//$NON-NLS-1$
-			for (Iterator it = node.catchClauses().iterator(); it.hasNext();) {
-				CatchClause cc = (CatchClause) it.next();
-				cc.accept(this);
-			}
-			if (node.getFinally() != null) {
-				buffer.append(" finally ");//$NON-NLS-1$
-				node.getFinally().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(TypeDeclaration node) {
-			if (node.getJavadoc() != null) {
-				node.getJavadoc().accept(this);
-			}
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-			}
-			buffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$
-			node.getName().accept(this);
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (!node.typeParameters().isEmpty()) {
-					buffer.append("<");//$NON-NLS-1$
-					for (Iterator it = node.typeParameters().iterator(); it.hasNext();) {
-						TypeParameter t = (TypeParameter) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(",");//$NON-NLS-1$
-						}
-					}
-					buffer.append(">");//$NON-NLS-1$
-				}
-			}
-			buffer.append(" ");//$NON-NLS-1$
-			if (node.getAST().apiLevel() == JLS2) {
-				if (getSuperclass(node) != null) {
-					buffer.append("extends ");//$NON-NLS-1$
-					getSuperclass(node).accept(this);
-					buffer.append(" ");//$NON-NLS-1$
-				}
-				if (!superInterfaces(node).isEmpty()) {
-					buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
-					for (Iterator it = superInterfaces(node).iterator(); it.hasNext();) {
-						Name n = (Name) it.next();
-						n.accept(this);
-						if (it.hasNext()) {
-							buffer.append(", ");//$NON-NLS-1$
-						}
-					}
-					buffer.append(" ");//$NON-NLS-1$
-				}
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				if (node.getSuperclassType() != null) {
-					buffer.append("extends ");//$NON-NLS-1$
-					node.getSuperclassType().accept(this);
-					buffer.append(" ");//$NON-NLS-1$
-				}
-				if (!node.superInterfaceTypes().isEmpty()) {
-					buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
-					for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext();) {
-						Type t = (Type) it.next();
-						t.accept(this);
-						if (it.hasNext()) {
-							buffer.append(", ");//$NON-NLS-1$
-						}
-					}
-					buffer.append(" ");//$NON-NLS-1$
-				}
-			}
-			buffer.append("{\n");//$NON-NLS-1$
-			indent++;
-			for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) {
-				BodyDeclaration d = (BodyDeclaration) it.next();
-				d.accept(this);
-			}
-			indent--;
-			printIndent();
-			buffer.append("}\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(TypeDeclarationStatement node) {
-			if (node.getAST().apiLevel() == JLS2) {
-				getTypeDeclaration(node).accept(this);
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				node.getDeclaration().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(TypeLiteral node) {
-			node.getType().accept(this);
-			buffer.append(".class");//$NON-NLS-1$
-			return false;
-		}
-
-		/*
-		 * @see ASTVisitor#visit(TypeMethodReference)
-		 *
-		 * @since 3.10
-		 */
-		@Override
-		public boolean visit(TypeMethodReference node) {
-			node.getType().accept(this);
-			visitReferenceTypeArguments(node.typeArguments());
-			node.getName().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(TypeParameter node) {
-			if (node.getAST().apiLevel() >= JLS8) {
-				printModifiers(node.modifiers());
-			}
-			node.getName().accept(this);
-			if (!node.typeBounds().isEmpty()) {
-				buffer.append(" extends ");//$NON-NLS-1$
-				for (Iterator it = node.typeBounds().iterator(); it.hasNext();) {
-					Type t = (Type) it.next();
-					t.accept(this);
-					if (it.hasNext()) {
-						buffer.append(" & ");//$NON-NLS-1$
-					}
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(UnionType node) {
-			for (Iterator it = node.types().iterator(); it.hasNext();) {
-				Type t = (Type) it.next();
-				t.accept(this);
-				if (it.hasNext()) {
-					buffer.append('|');
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(UsesDirective node) {
-			printIndent();
-			buffer.append("uses");//$NON-NLS-1$
-			buffer.append(" ");//$NON-NLS-1$
-			node.getName().accept(this);
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(VariableDeclarationExpression node) {
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-			}
-			node.getType().accept(this);
-			buffer.append(" ");//$NON-NLS-1$
-			for (Iterator it = node.fragments().iterator(); it.hasNext();) {
-				VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
-				f.accept(this);
-				if (it.hasNext()) {
-					buffer.append(", ");//$NON-NLS-1$
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(VariableDeclarationFragment node) {
-			addLocalBinding(node.resolveBinding(), node.getName().getIdentifier());
-
-			buffer.append(node.getName().getIdentifier());
-			int size = node.getExtraDimensions();
-			if (node.getAST().apiLevel() >= JLS8) {
-				List dimensions = node.extraDimensions();
-				for (int i = 0; i < size; i++) {
-					visit((Dimension) dimensions.get(i));
-				}
-			} else {
-				for (int i = 0; i < size; i++) {
-					buffer.append("[]");//$NON-NLS-1$
-				}
-			}
-			if (node.getInitializer() != null) {
-				buffer.append("=");//$NON-NLS-1$
-				node.getInitializer().accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(VariableDeclarationStatement node) {
-			printIndent();
-			if (node.getAST().apiLevel() == JLS2) {
-				printModifiers(node.getModifiers());
-			}
-			if (node.getAST().apiLevel() >= JLS3) {
-				printModifiers(node.modifiers());
-			}
-			node.getType().accept(this);
-			buffer.append(" ");//$NON-NLS-1$
-			for (Iterator it = node.fragments().iterator(); it.hasNext();) {
-				VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
-				f.accept(this);
-				if (it.hasNext()) {
-					buffer.append(", ");//$NON-NLS-1$
-				}
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		@Override
-		public boolean visit(WhileStatement node) {
-			printIndent();
-			buffer.append("while (");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			buffer.append(") ");//$NON-NLS-1$
-			node.getBody().accept(this);
-			return false;
-		}
-
-		@Override
-		public boolean visit(WildcardType node) {
-			visitTypeAnnotations(node);
-			buffer.append("?");//$NON-NLS-1$
-			Type bound = node.getBound();
-			if (bound != null) {
-				if (node.isUpperBound()) {
-					buffer.append(" extends ");//$NON-NLS-1$
-				} else {
-					buffer.append(" super ");//$NON-NLS-1$
-				}
-				bound.accept(this);
-			}
-			return false;
-		}
-
-		@Override
-		public boolean visit(YieldStatement node) {
-			if ((node.getAST().isPreviewEnabled()) && node.isImplicit() && node.getExpression() == null) {
-				return false;
-			}
-			printIndent();
-			buffer.append("yield"); //$NON-NLS-1$
-			if (node.getExpression() != null) {
-				buffer.append(" ");//$NON-NLS-1$
-				node.getExpression().accept(this);
-			}
-			buffer.append(";\n");//$NON-NLS-1$
-			return false;
-		}
-
-		/**
-		 * @deprecated
-		 */
-		@Deprecated
-		private void visitComponentType(ArrayType node) {
-			node.getComponentType().accept(this);
-		}
-	}
-
-}
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
index 7a50653..8139dcb 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
@@ -625,7 +625,7 @@
 		}
 
 		ASTInstructionCompiler visitor = new ASTInstructionCompiler(
-				mapper.getSnippetStart(), snippet, getJavaProject());
+				mapper.getSnippetStart(), snippet);
 		unit.accept(visitor);
 
 		return visitor.getInstructions();
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
index 4cd2d89..f226440 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
@@ -24,15 +24,10 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jdt.core.Flags;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.core.dom.*;
 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
-import org.eclipse.jdt.internal.debug.eval.ExpressionBinder;
-import org.eclipse.jdt.internal.debug.eval.RemoteEvaluator;
-import org.eclipse.jdt.internal.debug.eval.RemoteEvaluatorBuilder;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.AndAssignmentOperator;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.AndOperator;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAllocation;
@@ -92,7 +87,6 @@
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushType;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemainderAssignmentOperator;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemainderOperator;
-import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemoteOperator;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ReturnInstruction;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RightShiftAssignmentOperator;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RightShiftOperator;
@@ -159,17 +153,14 @@
 	// internal index used to create unique variable name
 	private int fUniqueIdIndex = 0;
 
-	private IJavaProject fJavaProject;
-
 	/**
 	 * Create a new AST instruction compiler
 	 */
-	public ASTInstructionCompiler(int startPosition, String snippet, IJavaProject javaProject) {
+	public ASTInstructionCompiler(int startPosition, String snippet) {
 		fStartPosition = startPosition;
 		fInstructions = new InstructionSequence(snippet);
 		fStack = new Stack<>();
 		fCompleteInstructions = new ArrayList<>();
-		fJavaProject = javaProject;
 	}
 
 	/**
@@ -232,7 +223,6 @@
 				((CompoundInstruction) instruction).setEnd(fCounter);
 			}
 			fInstructions.add(instruction);
-			//System.out.println("Added: " + instruction.toString()); //$NON-NLS-1$
 			verbose("Add " + instruction.toString()); //$NON-NLS-1$
 		}
 	}
@@ -2161,15 +2151,8 @@
 		if (!isActive()) {
 			return true;
 		}
-		RemoteEvaluatorBuilder builder = makeBuilder(node);
-		builder.acceptMethodReference(node, node.resolveTypeBinding());
-		try {
-			RemoteEvaluator remoteEvaluator = builder.build();
-			push(new RemoteOperator(builder.getSnippet(), node.getStartPosition(), remoteEvaluator));
-			storeInstruction();
-		} catch (JavaModelException e) {
-			addErrorMessage(e.getMessage());
-		}
+		setHasError(true);
+		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Reference_expressions_cannot_be_used_in_an_evaluation_expression);
 		return false;
 	}
 
@@ -2368,56 +2351,11 @@
 		if (!isActive()) {
 			return true;
 		}
-
-		RemoteEvaluatorBuilder builder = makeBuilder(node);
-		builder.acceptMethodReference(node, node.resolveTypeBinding());
-		try {
-			RemoteEvaluator remoteEvaluator = builder.build();
-			push(new RemoteOperator(builder.getSnippet(), node.getStartPosition(), remoteEvaluator));
-			storeInstruction();
-		} catch (JavaModelException e) {
-			addErrorMessage(e.getMessage());
-		}
-
+		setHasError(true);
+		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Reference_expressions_cannot_be_used_in_an_evaluation_expression);
 		return false;
 	}
 
-	private RemoteEvaluatorBuilder makeBuilder(ASTNode node) {
-		RemoteEvaluatorBuilder builder = new RemoteEvaluatorBuilder(fJavaProject, new ExpressionBinder() {
-			@Override
-			public void bind(IVariableBinding variableBinding, String asVariableName) {
-				String variableId = variableBinding.getName();
-				ITypeBinding declaringTypeBinding = variableBinding.getDeclaringClass();
-				if (variableBinding.isField()) {
-					if (Modifier.isStatic(variableBinding.getModifiers())) {
-						push(new PushStaticFieldVariable(variableId, getTypeName(declaringTypeBinding), fCounter));
-					} else {
-						push(new PushFieldVariable(variableId, getTypeSignature(declaringTypeBinding), fCounter));
-						push(new PushThis(getEnclosingLevel(node, declaringTypeBinding)));
-						storeInstruction();
-					}
-				} else {
-					push(new PushLocalVariable(variableId));
-				}
-				storeInstruction();
-			}
-		}, getEnclosingClass(node).getQualifiedName(), false, false);
-		return builder;
-	}
-
-	private ITypeBinding getEnclosingClass(ASTNode node) {
-		while (node != null) {
-			if (node instanceof MethodDeclaration) {
-				return ((MethodDeclaration) node).resolveBinding().getDeclaringClass();
-			}
-			if (node instanceof TypeDeclaration) {
-				return ((TypeDeclaration) node).resolveBinding();
-			}
-			node = node.getParent();
-		}
-		return null;
-	}
-
 	/**
 	 * @see ASTVisitor#visit(ExpressionStatement)
 	 */
@@ -2924,19 +2862,10 @@
 		if (!isActive()) {
 			return true;
 		}
-
-		RemoteEvaluatorBuilder builder = makeBuilder(node);
-		builder.acceptLambda(node, node.resolveTypeBinding());
-		try {
-			RemoteEvaluator remoteEvaluator = builder.build();
-			push(new RemoteOperator(builder.getSnippet(), node.getStartPosition(), remoteEvaluator));
-			storeInstruction();
-		} catch (JavaModelException e) {
-			addErrorMessage(e.getMessage());
-		}
+		setHasError(true);
+		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Lambda_expressions_cannot_be_used_in_an_evaluation_expression);
 		return false;
 	}
-
 	/*
 	 * (non-Javadoc)
 	 *
@@ -4319,17 +4248,8 @@
 		if (!isActive()) {
 			return true;
 		}
-
-		RemoteEvaluatorBuilder builder = makeBuilder(node);
-		builder.acceptMethodReference(node, node.resolveTypeBinding());
-		try {
-			RemoteEvaluator remoteEvaluator = builder.build();
-			push(new RemoteOperator(builder.getSnippet(), node.getStartPosition(), remoteEvaluator));
-			storeInstruction();
-		} catch (JavaModelException e) {
-			addErrorMessage(e.getMessage());
-		}
-
+		setHasError(true);
+		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Reference_expressions_cannot_be_used_in_an_evaluation_expression);
 		return false;
 	}
 
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.java
index 9d92c16..b97de5f 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.java
@@ -29,7 +29,6 @@
 	public static String AssignmentOperator_operator_1;
 	public static String Cast_ClassCastException__Cannot_cast__0__as__1___1;
 	public static String Cast_cast_3;
-	public static String Run_Remote_1;
 	public static String ConditionalJump_conditional_jump_1;
 	public static String Constructor_constructor__1;
 	public static String LocalVariableCreation_create_local_variable__0___1___1;
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.properties b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.properties
index 15f1260..ed26ba7 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.properties
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/InstructionsEvaluationMessages.properties
@@ -24,7 +24,6 @@
 Cast_cast_3=cast
 ConditionalJump_conditional_jump_1=conditional jump
 Constructor_constructor__1=constructor
-Run_Remote_1=run remote code
 LocalVariableCreation_create_local_variable__0___1___1=Create local variable {1} {0}
 DivideAssignmentOperator_operator_1='/=\' operator
 DivideOperator_Divide_by_zero_1=Divide by zero
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/RemoteOperator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/RemoteOperator.java
deleted file mode 100644
index c47f065..0000000
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/RemoteOperator.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2020, Jesper Steen Møller and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Jesper Steen Møller - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.debug.eval.ast.instructions;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.debug.core.IJavaValue;
-import org.eclipse.jdt.internal.debug.eval.RemoteEvaluator;
-
-/**
- * Invokes a method on a object in a class injected into the debug target. The arguments are on the stack in reverse order, followed by the type.
- * Pushes the result onto the stack
- */
-public class RemoteOperator extends CompoundInstruction {
-
-	private RemoteEvaluator fEvaluator;
-	private String fSignature;
-
-	public RemoteOperator(String body, int start, RemoteEvaluator evaluator) {
-		super(start);
-		fSignature = body;
-		fEvaluator = evaluator;
-	}
-
-	@Override
-	public void execute() throws CoreException {
-		int variableCount = fEvaluator.getVariableCount();
-		IJavaValue[] args = new IJavaValue[variableCount];
-		// args are in reverse order
-		for (int i = variableCount - 1; i >= 0; i--) {
-			args[i] = popValue();
-		}
-		IJavaValue result = fEvaluator.evaluate(this.getContext().getThread(), args);
-		push(result);
-	}
-
-	@Override
-	public String toString() {
-		return InstructionsEvaluationMessages.Run_Remote_1
-				+ fSignature;
-	}
-
-}
