/*******************************************************************************
 * 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.core.eval.ICodeSnippetRequestor.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.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
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;
import org.eclipse.jdt.core.eval.IEvaluationContext;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.eval.ast.engine.EvaluationEngineMessages;

/**
 * A builder for a reuseable expression evaluator against a runnng VM.
 */

@SuppressWarnings("rawtypes")
public class RemoteEvaluatorBuilder {

	private IJavaProject javaProject;
	private ExpressionBinder binder;
	private final String enclosingTypeName;
	private final String packageName;
	private final boolean isStatic;
	private final boolean isConstructor;
	private final List<String> argumentNames = new ArrayList<>();
	private final 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;
	private final ITypeBinding enclosingClass;

	public RemoteEvaluatorBuilder(IJavaProject javaProject, ExpressionBinder binder, ITypeBinding enclosingClass, boolean isStatic, boolean isConstructor) {
		this.javaProject = javaProject;
		this.binder = binder;
		this.enclosingClass = enclosingClass;
		this.enclosingTypeName = enclosingClass.getQualifiedName();
		this.packageName = enclosingClass.getPackage().getName();
		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, DebugException {

		List<String> boundVariableNames = getVariableNames();
		List<String> boundVariableTypeNames = getVariableTypeNames();

		List<String> errors = new ArrayList<>();
		IType enclosingType = this.javaProject.findType(enclosingTypeName);

		if (enclosingType == null) {
			throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), EvaluationEngineMessages.ASTInstructionCompiler_Functional_expressions_cannot_be_evaluated_inside_local_and_or_anonymous_classes));
		}

		synchronized (EVALUATE_CODE_SNIPPET_LOCK) {
			IEvaluationContext context = this.javaProject.newEvaluationContext();
			if (!packageName.startsWith("java.")) { //$NON-NLS-1$
				context.setPackageName(this.packageName);
			}
			// System.out.println(this.snippet);
			context.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) {
					if (problemMarker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) >= IMarker.SEVERITY_ERROR) {
						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()) {
			throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), errors.toString()));
		}

		return new RemoteEvaluator(classFiles, codeSnippetClassName, getVariableNames(), enclosingType.getFullyQualifiedName('$'));
	}

	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(ITypeBinding binding, String hint) {
		String varName = hint + "$" + argumentNames.size(); //$NON-NLS-1$
		argumentNames.add(varName);
		argumentTypeNames.add(binding.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();

		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) {
			/* TODO: Make tricks here when we access fields where we have non-public access */
			ITypeBinding instanceType = node.getExpression().resolveTypeBinding();
			if (instanceType.isAssignmentCompatible(RemoteEvaluatorBuilder.this.enclosingClass)) {
				node.getExpression().accept(this);
				buffer.append(".");//$NON-NLS-1$ */
				buffer.append(node.getName().getIdentifier());
				return false;
			}
			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$
			} else {
				String newVarName = new String(LOCAL_VAR_PREFIX) + allocateNewVariable(node.resolveMethodBinding().getDeclaringClass(), "this"); //$NON-NLS-1$
				binder.bindThis(RemoteEvaluatorBuilder.this.enclosingClass, newVarName);
				// buffer.append("this."); //$NON-NLS-1$
				buffer.append(newVarName);
				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);
					// For future optimization: Check for duplicates, so same value is only bound once
					if (vb.isField()) {
						if (Modifier.isStatic(vb.getModifiers())) {
							ITypeBinding declaringClass = vb.getDeclaringClass();
							buffer.append(declaringClass.getQualifiedName());
							buffer.append("."); //$NON-NLS-1$
							buffer.append(node.getIdentifier());

						} else {
							// TODO: Fix this to use same method as visit(FieldAccess)
							ITypeBinding declaringClass = vb.getDeclaringClass();
							String newVarName = new String(LOCAL_VAR_PREFIX) + allocateNewVariable(declaringClass, "this"); //$NON-NLS-1$
							binder.bindThis(declaringClass, newVarName);
							// buffer.append("this."); //$NON-NLS-1$
							buffer.append(newVarName);
							buffer.append("."); //$NON-NLS-1$
							buffer.append(node.getIdentifier());
						}
					} else {
						String newVarName = new String(LOCAL_VAR_PREFIX) + allocateNewVariable(vb.getType(), node.getIdentifier());
						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) {
			ITypeBinding thisType = node.resolveTypeBinding();

			String newVarName = new String(LOCAL_VAR_PREFIX) + allocateNewVariable(thisType, "this"); //$NON-NLS-1$
			binder.bindThis(thisType, newVarName);
			// buffer.append("this."); //$NON-NLS-1$
			buffer.append(newVarName);
			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);
		}
	}

}
