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

		private boolean isParentInLocalBinding(ASTNode parent) {
			if (parent instanceof QualifiedName) {
				// this will avoid unwanted upward traversals
				if (isLocalBinding(((QualifiedName) parent).getQualifier().resolveBinding())) {
					return true;
				}
				// traverse upstream to see if a parent is already handled
				return isParentInLocalBinding(parent.getParent());
			}
			return false;
		}

		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();
			// when having code like arr.length the length is identified as a field variable. But since the arr is
			// already pushed as a variable we don't need to handle length here. So if we have chained field access like
			// obj.f1.f2 we will only push the obj as a variable.
			if (!isLocalBinding(binding) && !isParentInLocalBinding(node.getParent())) {
				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);
		}
	}

}
