/*******************************************************************************
 * Copyright (c) 2019, 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;

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);
	}

	public void acceptAnonymousClass(ClassInstanceCreation 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(toString(problemMarker));
					}
				}

				private String toString(IMarker marker) {
					return marker.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
				}

				@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) {
		return String.join(String.valueOf('/'), names);
	}

	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;
		}

		private boolean needToQualify(SimpleName node) {
			if (node.getParent() instanceof QualifiedName || node.getParent() instanceof QualifiedType) {
				return false;
			}
			return true;
		}
		@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())) {
							if (needToQualify(node)) {
								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 = allocateNewVariable(declaringClass, LOCAL_VAR_PREFIX.concat("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 = allocateNewVariable(thisType, LOCAL_VAR_PREFIX.concat("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);
		}
	}

}
