/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation 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
 * 
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.dom;

import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jdt.core.dom.*;

public class ASTFlattener extends GenericVisitor {
/*
 * XXX: Keep in sync with org.eclipse.jdt.internal.core.dom.NaiveASTFlattener:
 * Rename NaiveASTFlattener#buffer to fBuffer, compare with this class, focus on structural changes
 */

	/**
	 * @deprecated to avoid deprecation warnings
	 */
	@Deprecated
	private static final int JLS3= AST.JLS3;
	/**
	 * @deprecated to avoid deprecation warnings
	 */
	@Deprecated
	private static final int JLS4= AST.JLS4;
	/**
	 * @deprecated to avoid deprecation warnings
	 */
	@Deprecated
	private static final int JLS8= AST.JLS8;
	/**
	 * @deprecated to avoid deprecation warnings
	 */
	@Deprecated
	private static final int JLS9= AST.JLS9;

	private static final int JLS13= AST.JLS13;

	/**
	 * The string buffer into which the serialized representation of the AST is
	 * written.
	 */
	protected StringBuffer fBuffer;

	/**
	 * Creates a new AST printer.
	 */
	public ASTFlattener() {
		this.fBuffer= new StringBuffer();
	}

	/**
	 * Returns the string accumulated in the visit.
	 *
	 * @return the serialized
	 */
	public String getResult() {
		return this.fBuffer.toString();
	}

	/**
	 * Resets this printer so that it can be used again.
	 */
	public void reset() {
		this.fBuffer.setLength(0);
	}

	public static String asString(ASTNode node) {
		Assert.isTrue(node.getAST().apiLevel() == IASTSharedValues.SHARED_AST_LEVEL);

		ASTFlattener flattener= new ASTFlattener();
		node.accept(flattener);
		return flattener.getResult();
	}


	@Override
	protected boolean visitNode(ASTNode node) {
		Assert.isTrue(false, "No implementation to flatten node: " + node.toString()); //$NON-NLS-1$
		return false;
	}

	/**
	 * 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>IExtendedModifier</code>)
	 */
	private void printModifiers(List<IExtendedModifier> ext) {
		for (Iterator<IExtendedModifier> it= ext.iterator(); it.hasNext();) {
			ASTNode p= (ASTNode) it.next();
			p.accept(this);
			this.fBuffer.append(" ");//$NON-NLS-1$
		}
	}

	private void printTypes(List<Type> types, String prefix) {
		if (types.size() > 0) {
			this.fBuffer.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) {
				this.fBuffer.append(","); //$NON-NLS-1$
				type = types.get(0);
				type.accept(this);
			}
		}
	}

	private void printReferenceTypeArguments(List<Type> typeArguments) {
		this.fBuffer.append("::");//$NON-NLS-1$
		if (!typeArguments.isEmpty()) {
			this.fBuffer.append('<');
			for (Iterator<Type> it = typeArguments.iterator(); it.hasNext(); ) {
				Type t = it.next();
				t.accept(this);
				if (it.hasNext()) {
					this.fBuffer.append(',');
				}
			}
			this.fBuffer.append('>');
		}
	}
	
	void printTypeAnnotations(AnnotatableType node) {
		if (node.getAST().apiLevel() >= JLS8) {
			printAnnotationsList(node.annotations());
		}
	}

	void printAnnotationsList(List<? extends Annotation> annotations) {
		for (Iterator<? extends Annotation> it = annotations.iterator(); it.hasNext(); ) {
			Annotation annotation = it.next();
			annotation.accept(this);
			this.fBuffer.append(' ');
		}
	}

	/**
	 * @param node node
	 * @return component type
	 * @deprecated to avoid deprecation warning
	 */
	@Deprecated
	private static Type getComponentType(ArrayType node) {
		return node.getComponentType();
	}

	/**
	 * @param node node
	 * @return thrown exception names
	 * @deprecated to avoid deprecation warning
	 */
	@Deprecated
	private static List<Name> getThrownExceptions(MethodDeclaration node) {
		return node.thrownExceptions();
	}

	/*
	 * @see ASTVisitor#visit(AnnotationTypeDeclaration)
	 * @since 3.0
	 */
	@Override
	public boolean visit(AnnotationTypeDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		printModifiers(node.modifiers());
		this.fBuffer.append("@interface ");//$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append(" {");//$NON-NLS-1$
		for (Iterator<BodyDeclaration> it= node.bodyDeclarations().iterator(); it.hasNext();) {
			BodyDeclaration d= it.next();
			d.accept(this);
		}
		this.fBuffer.append("}");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration)
	 * @since 3.0
	 */
	@Override
	public boolean visit(AnnotationTypeMemberDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		printModifiers(node.modifiers());
		node.getType().accept(this);
		this.fBuffer.append(" ");//$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append("()");//$NON-NLS-1$
		if (node.getDefault() != null) {
			this.fBuffer.append(" default ");//$NON-NLS-1$
			node.getDefault().accept(this);
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(AnonymousClassDeclaration)
	 */
	@Override
	public boolean visit(AnonymousClassDeclaration node) {
		this.fBuffer.append("{");//$NON-NLS-1$
		List<BodyDeclaration> bodyDeclarations= node.bodyDeclarations();
		for (Iterator<BodyDeclaration> it= bodyDeclarations.iterator(); it.hasNext();) {
			BodyDeclaration b= it.next();
			b.accept(this);
		}
		this.fBuffer.append("}");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ArrayAccess)
	 */
	@Override
	public boolean visit(ArrayAccess node) {
		node.getArray().accept(this);
		this.fBuffer.append("[");//$NON-NLS-1$
		node.getIndex().accept(this);
		this.fBuffer.append("]");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ArrayCreation)
	 */
	@Override
	public boolean visit(ArrayCreation node) {
		this.fBuffer.append("new ");//$NON-NLS-1$
		ArrayType at= node.getType();
		int dims= at.getDimensions();
		Type elementType= at.getElementType();
		elementType.accept(this);
		for (Iterator<Expression> it= node.dimensions().iterator(); it.hasNext();) {
			this.fBuffer.append("[");//$NON-NLS-1$
			Expression e= it.next();
			e.accept(this);
			this.fBuffer.append("]");//$NON-NLS-1$
			dims--;
		}
		// add empty "[]" for each extra array dimension
		for (int i= 0; i < dims; i++) {
			this.fBuffer.append("[]");//$NON-NLS-1$
		}
		if (node.getInitializer() != null) {
			node.getInitializer().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ArrayInitializer)
	 */
	@Override
	public boolean visit(ArrayInitializer node) {
		this.fBuffer.append("{");//$NON-NLS-1$
		for (Iterator<Expression> it= node.expressions().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append("}");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ArrayType)
	 */
	@Override
	public boolean visit(ArrayType node) {
		if (node.getAST().apiLevel() < JLS8) {
			getComponentType(node).accept(this);
			this.fBuffer.append("[]");//$NON-NLS-1$
		} else {
			node.getElementType().accept(this);
			List<Dimension> dimensions = node.dimensions();
			for (int i = 0; i < dimensions.size() ; i++) {
				Dimension dimension = dimensions.get(i);
				dimension.accept(this);
			}
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(AssertStatement)
	 */
	@Override
	public boolean visit(AssertStatement node) {
		this.fBuffer.append("assert ");//$NON-NLS-1$
		node.getExpression().accept(this);
		if (node.getMessage() != null) {
			this.fBuffer.append(" : ");//$NON-NLS-1$
			node.getMessage().accept(this);
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(Assignment)
	 */
	@Override
	public boolean visit(Assignment node) {
		node.getLeftHandSide().accept(this);
		this.fBuffer.append(node.getOperator().toString());
		node.getRightHandSide().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(Block)
	 */
	@Override
	public boolean visit(Block node) {
		this.fBuffer.append("{");//$NON-NLS-1$
		for (Iterator<Statement> it= node.statements().iterator(); it.hasNext();) {
			Statement s= it.next();
			s.accept(this);
		}
		this.fBuffer.append("}");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(BlockComment)
	 * @since 3.0
	 */
	@Override
	public boolean visit(BlockComment node) {
		this.fBuffer.append("/* */");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(BooleanLiteral)
	 */
	@Override
	public boolean visit(BooleanLiteral node) {
		if (node.booleanValue() == true) {
			this.fBuffer.append("true");//$NON-NLS-1$
		} else {
			this.fBuffer.append("false");//$NON-NLS-1$
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(BreakStatement)
	 */
	@Override
	public boolean visit(BreakStatement node) {
		this.fBuffer.append("break");//$NON-NLS-1$
		if (node.getLabel() != null) {
			this.fBuffer.append(" ");//$NON-NLS-1$
			node.getLabel().accept(this);
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(CastExpression)
	 */
	@Override
	public boolean visit(CastExpression node) {
		this.fBuffer.append("(");//$NON-NLS-1$
		node.getType().accept(this);
		this.fBuffer.append(")");//$NON-NLS-1$
		node.getExpression().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(CatchClause)
	 */
	@Override
	public boolean visit(CatchClause node) {
		this.fBuffer.append("catch (");//$NON-NLS-1$
		node.getException().accept(this);
		this.fBuffer.append(") ");//$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(CharacterLiteral)
	 */
	@Override
	public boolean visit(CharacterLiteral node) {
		this.fBuffer.append(node.getEscapedValue());
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ClassInstanceCreation)
	 */
	@Override
	public boolean visit(ClassInstanceCreation node) {
		if (node.getExpression() != null) {
			node.getExpression().accept(this);
			this.fBuffer.append(".");//$NON-NLS-1$
		}
		this.fBuffer.append("new ");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS3) {
			if (!node.typeArguments().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) {
					Type t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(">");//$NON-NLS-1$
			}
			node.getType().accept(this);
		}
		this.fBuffer.append("(");//$NON-NLS-1$
		for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(")");//$NON-NLS-1$
		if (node.getAnonymousClassDeclaration() != null) {
			node.getAnonymousClassDeclaration().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(CompilationUnit)
	 */
	@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<ImportDeclaration> it= node.imports().iterator(); it.hasNext();) {
			ImportDeclaration d= it.next();
			d.accept(this);
		}
		for (Iterator<AbstractTypeDeclaration> it= node.types().iterator(); it.hasNext();) {
			AbstractTypeDeclaration d= it.next();
			d.accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ConditionalExpression)
	 */
	@Override
	public boolean visit(ConditionalExpression node) {
		node.getExpression().accept(this);
		this.fBuffer.append("?");//$NON-NLS-1$
		node.getThenExpression().accept(this);
		this.fBuffer.append(":");//$NON-NLS-1$
		node.getElseExpression().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ConstructorInvocation)
	 */
	@Override
	public boolean visit(ConstructorInvocation node) {
		if (node.getAST().apiLevel() >= JLS3) {
			if (!node.typeArguments().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) {
					Type t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(">");//$NON-NLS-1$
			}
		}
		this.fBuffer.append("this(");//$NON-NLS-1$
		for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(");");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ContinueStatement)
	 */
	@Override
	public boolean visit(ContinueStatement node) {
		this.fBuffer.append("continue");//$NON-NLS-1$
		if (node.getLabel() != null) {
			this.fBuffer.append(" ");//$NON-NLS-1$
			node.getLabel().accept(this);
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}
	
	/*
	 * @see ASTVisitor#visit(CreationReference)
	 */
	@Override
	public boolean visit(CreationReference node) {
		node.getType().accept(this);
		printReferenceTypeArguments(node.typeArguments());
		this.fBuffer.append("new");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(Dimension)
	 */
	@Override
	public boolean visit(Dimension node) {
		this.fBuffer.append(" ");//$NON-NLS-1$
		printAnnotationsList(node.annotations());
		this.fBuffer.append("[]"); //$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(DoStatement)
	 */
	@Override
	public boolean visit(DoStatement node) {
		this.fBuffer.append("do ");//$NON-NLS-1$
		node.getBody().accept(this);
		this.fBuffer.append(" while (");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(");");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(EmptyStatement)
	 */
	@Override
	public boolean visit(EmptyStatement node) {
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(EnhancedForStatement)
	 * @since 3.0
	 */
	@Override
	public boolean visit(EnhancedForStatement node) {
		this.fBuffer.append("for (");//$NON-NLS-1$
		node.getParameter().accept(this);
		this.fBuffer.append(" : ");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(") ");//$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(EnumConstantDeclaration)
	 * @since 3.0
	 */
	@Override
	public boolean visit(EnumConstantDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		printModifiers(node.modifiers());
		node.getName().accept(this);
		if (!node.arguments().isEmpty()) {
			this.fBuffer.append("(");//$NON-NLS-1$
			for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) {
				Expression e= it.next();
				e.accept(this);
				if (it.hasNext()) {
					this.fBuffer.append(",");//$NON-NLS-1$
				}
			}
			this.fBuffer.append(")");//$NON-NLS-1$
		}
		if (node.getAnonymousClassDeclaration() != null) {
			node.getAnonymousClassDeclaration().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(EnumDeclaration)
	 * @since 3.0
	 */
	@Override
	public boolean visit(EnumDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		printModifiers(node.modifiers());
		this.fBuffer.append("enum ");//$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append(" ");//$NON-NLS-1$
		if (!node.superInterfaceTypes().isEmpty()) {
			this.fBuffer.append("implements ");//$NON-NLS-1$
			for (Iterator<Type> it= node.superInterfaceTypes().iterator(); it.hasNext();) {
				Type t= it.next();
				t.accept(this);
				if (it.hasNext()) {
					this.fBuffer.append(", ");//$NON-NLS-1$
				}
			}
			this.fBuffer.append(" ");//$NON-NLS-1$
		}
		this.fBuffer.append("{");//$NON-NLS-1$
		for (Iterator<EnumConstantDeclaration> it = node.enumConstants().iterator(); it.hasNext(); ) {
			EnumConstantDeclaration d = it.next();
			d.accept(this);
			// enum constant declarations do not include punctuation
			if (it.hasNext()) {
				// enum constant declarations are separated by commas
				this.fBuffer.append(", ");//$NON-NLS-1$
			}
		}
		if (!node.bodyDeclarations().isEmpty()) {
			this.fBuffer.append("; ");//$NON-NLS-1$
			for (Iterator<BodyDeclaration> it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
				BodyDeclaration d = it.next();
				d.accept(this);
				// other body declarations include trailing punctuation
			}
		}
		this.fBuffer.append("}");//$NON-NLS-1$
		return false;
	}

	@Override
	public boolean visit(ExportsDirective node) {
		return visit(node, "exports"); //$NON-NLS-1$
	}

	/*
	 * @see ASTVisitor#visit(ExpressionMethodReference)
	 */
	@Override
	public boolean visit(ExpressionMethodReference node) {
		node.getExpression().accept(this);
		printReferenceTypeArguments(node.typeArguments());
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ExpressionStatement)
	 */
	@Override
	public boolean visit(ExpressionStatement node) {
		node.getExpression().accept(this);
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(FieldAccess)
	 */
	@Override
	public boolean visit(FieldAccess node) {
		node.getExpression().accept(this);
		this.fBuffer.append(".");//$NON-NLS-1$
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(FieldDeclaration)
	 */
	@Override
	public boolean visit(FieldDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		if (node.getAST().apiLevel() >= JLS3) {
			printModifiers(node.modifiers());
		}
		node.getType().accept(this);
		this.fBuffer.append(" ");//$NON-NLS-1$
		for (Iterator<VariableDeclarationFragment> it= node.fragments().iterator(); it.hasNext();) {
			VariableDeclarationFragment f= it.next();
			f.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(", ");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ForStatement)
	 */
	@Override
	public boolean visit(ForStatement node) {
		this.fBuffer.append("for (");//$NON-NLS-1$
		for (Iterator<Expression> it= node.initializers().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
		}
		this.fBuffer.append("; ");//$NON-NLS-1$
		if (node.getExpression() != null) {
			node.getExpression().accept(this);
		}
		this.fBuffer.append("; ");//$NON-NLS-1$
		for (Iterator<Expression> it= node.updaters().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
		}
		this.fBuffer.append(") ");//$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(IfStatement)
	 */
	@Override
	public boolean visit(IfStatement node) {
		this.fBuffer.append("if (");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(") ");//$NON-NLS-1$
		node.getThenStatement().accept(this);
		if (node.getElseStatement() != null) {
			this.fBuffer.append(" else ");//$NON-NLS-1$
			node.getElseStatement().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ImportDeclaration)
	 */
	@Override
	public boolean visit(ImportDeclaration node) {
		this.fBuffer.append("import ");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS3) {
			if (node.isStatic()) {
				this.fBuffer.append("static ");//$NON-NLS-1$
			}
		}
		node.getName().accept(this);
		if (node.isOnDemand()) {
			this.fBuffer.append(".*");//$NON-NLS-1$
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(InfixExpression)
	 */
	@Override
	public boolean visit(InfixExpression node) {
		node.getLeftOperand().accept(this);
		this.fBuffer.append(' '); // for cases like x= i - -1; or x= i++ + ++i;
		this.fBuffer.append(node.getOperator().toString());
		this.fBuffer.append(' ');
		node.getRightOperand().accept(this);
		final List<Expression>extendedOperands = node.extendedOperands();
		if (extendedOperands.size() != 0) {
			this.fBuffer.append(' ');
			for (Iterator<Expression> it = extendedOperands.iterator(); it.hasNext(); ) {
				this.fBuffer.append(node.getOperator().toString()).append(' ');
				Expression e = it.next();
				e.accept(this);
			}
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(Initializer)
	 */
	@Override
	public boolean visit(Initializer node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		if (node.getAST().apiLevel() >= JLS3) {
			printModifiers(node.modifiers());
		}
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(InstanceofExpression)
	 */
	@Override
	public boolean visit(InstanceofExpression node) {
		node.getLeftOperand().accept(this);
		this.fBuffer.append(" instanceof ");//$NON-NLS-1$
		node.getRightOperand().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(IntersectionType)
	 */
	@Override
	public boolean visit(IntersectionType node) {
		for (Iterator<Type> it = node.types().iterator(); it.hasNext(); ) {
			Type t = it.next();
			t.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(" & "); //$NON-NLS-1$
			}
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(Javadoc)
	 */
	@Override
	public boolean visit(Javadoc node) {
		this.fBuffer.append("/** ");//$NON-NLS-1$
		for (Iterator<TagElement> it= node.tags().iterator(); it.hasNext();) {
			ASTNode e= it.next();
			e.accept(this);
		}
		this.fBuffer.append("\n */");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(LabeledStatement)
	 */
	@Override
	public boolean visit(LabeledStatement node) {
		node.getLabel().accept(this);
		this.fBuffer.append(": ");//$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(LambdaExpression)
	 */
	@Override
	public boolean visit(LambdaExpression node) {
		boolean hasParentheses= node.hasParentheses();
		if (hasParentheses)
			this.fBuffer.append('(');
		for (Iterator<? extends VariableDeclaration> it= node.parameters().iterator(); it.hasNext(); ) {
			VariableDeclaration v= it.next();
			v.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		if (hasParentheses)
			this.fBuffer.append(')');
		this.fBuffer.append(" -> "); //$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(LineComment)
	 * @since 3.0
	 */
	@Override
	public boolean visit(LineComment node) {
		this.fBuffer.append("//\n");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MarkerAnnotation)
	 * @since 3.0
	 */
	@Override
	public boolean visit(MarkerAnnotation node) {
		this.fBuffer.append("@");//$NON-NLS-1$
		node.getTypeName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MemberRef)
	 * @since 3.0
	 */
	@Override
	public boolean visit(MemberRef node) {
		if (node.getQualifier() != null) {
			node.getQualifier().accept(this);
		}
		this.fBuffer.append("#");//$NON-NLS-1$
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MemberValuePair)
	 * @since 3.0
	 */
	@Override
	public boolean visit(MemberValuePair node) {
		node.getName().accept(this);
		this.fBuffer.append("=");//$NON-NLS-1$
		node.getValue().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MethodRef)
	 * @since 3.0
	 */
	@Override
	public boolean visit(MethodRef node) {
		if (node.getQualifier() != null) {
			node.getQualifier().accept(this);
		}
		this.fBuffer.append("#");//$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append("(");//$NON-NLS-1$
		for (Iterator<MethodRefParameter> it= node.parameters().iterator(); it.hasNext();) {
			MethodRefParameter e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(")");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MethodRefParameter)
	 * @since 3.0
	 */
	@Override
	public boolean visit(MethodRefParameter node) {
		node.getType().accept(this);
		if (node.getAST().apiLevel() >= JLS3) {
			if (node.isVarargs()) {
				this.fBuffer.append("...");//$NON-NLS-1$
			}
		}
		if (node.getName() != null) {
			this.fBuffer.append(" ");//$NON-NLS-1$
			node.getName().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MethodDeclaration)
	 */
	@Override
	public boolean visit(MethodDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		if (node.getAST().apiLevel() >= JLS3) {
			printModifiers(node.modifiers());
			if (!node.typeParameters().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<TypeParameter> it= node.typeParameters().iterator(); it.hasNext();) {
					TypeParameter t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(", ");//$NON-NLS-1$
					}
				}
				this.fBuffer.append("> ");//$NON-NLS-1$
			}
		}
		if (!node.isConstructor()) {
			if (node.getReturnType2() != null) {
				node.getReturnType2().accept(this);
			} else {
				// methods really ought to have a return type
				this.fBuffer.append("void");//$NON-NLS-1$
			}
			this.fBuffer.append(" ");//$NON-NLS-1$
		}
		node.getName().accept(this);
		this.fBuffer.append("(");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS8) {
			Type receiverType= node.getReceiverType();
			if (receiverType != null) {
				receiverType.accept(this);
				this.fBuffer.append(' ');
				SimpleName qualifier= node.getReceiverQualifier();
				if (qualifier != null) {
					qualifier.accept(this);
					this.fBuffer.append('.');
				}
				this.fBuffer.append("this"); //$NON-NLS-1$
				if (node.parameters().size() > 0) {
					this.fBuffer.append(',');
				}
			}
		}
		for (Iterator<SingleVariableDeclaration> it= node.parameters().iterator(); it.hasNext();) {
			SingleVariableDeclaration v= it.next();
			v.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(", ");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(")");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS8) {
			List<Dimension> dimensions = node.extraDimensions();
			for (Iterator<Dimension> it= dimensions.iterator(); it.hasNext(); ) {
				Dimension e= it.next();
				e.accept(this);
			}
		} else {
			for (int i= 0; i < node.getExtraDimensions(); i++) {
				this.fBuffer.append("[]"); //$NON-NLS-1$
			}
		}
		List<? extends ASTNode> thrownExceptions= node.getAST().apiLevel() >= JLS8 ? node.thrownExceptionTypes() : getThrownExceptions(node);
		if (!thrownExceptions.isEmpty()) {
			this.fBuffer.append(" throws ");//$NON-NLS-1$
			for (Iterator<? extends ASTNode> it= thrownExceptions.iterator(); it.hasNext();) {
				ASTNode n = it.next();
				n.accept(this);
				if (it.hasNext()) {
					this.fBuffer.append(", ");//$NON-NLS-1$
				}
			}
			this.fBuffer.append(" ");//$NON-NLS-1$
		}
		if (node.getBody() == null) {
			this.fBuffer.append(";");//$NON-NLS-1$
		} else {
			node.getBody().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(MethodInvocation)
	 */
	@Override
	public boolean visit(MethodInvocation node) {
		if (node.getExpression() != null) {
			node.getExpression().accept(this);
			this.fBuffer.append(".");//$NON-NLS-1$
		}
		if (node.getAST().apiLevel() >= JLS3) {
			if (!node.typeArguments().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) {
					Type t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(">");//$NON-NLS-1$
			}
		}
		node.getName().accept(this);
		this.fBuffer.append("(");//$NON-NLS-1$
		for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(")");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(Modifier)
	 * @since 3.0
	 */
	@Override
	public boolean visit(Modifier node) {
		this.fBuffer.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())
			this.fBuffer.append("open "); //$NON-NLS-1$
		this.fBuffer.append("module"); //$NON-NLS-1$
		this.fBuffer.append(" "); //$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append(" {\n"); //$NON-NLS-1$
		for (ModuleDirective stmt : (List<ModuleDirective>)node.moduleStatements()) {
			stmt.accept(this);
		}
		this.fBuffer.append("}"); //$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ModuleModifier)
	 * @since 3.14
	 */
	@Override
	public boolean visit(ModuleModifier node) {
		this.fBuffer.append(node.getKeyword().toString());
		return false;
	}

	private boolean visit(ModulePackageAccess node, String keyword) {
		this.fBuffer.append(keyword);
		this.fBuffer.append(" ");//$NON-NLS-1$
		node.getName().accept(this);
		printTypes(node.modules(), "to"); //$NON-NLS-1$
		this.fBuffer.append(";\n");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(NameQualifiedType)
	 */
	@Override
	public boolean visit(NameQualifiedType node) {
		node.getQualifier().accept(this);
		this.fBuffer.append('.');
		printTypeAnnotations(node);
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(NormalAnnotation)
	 * @since 3.0
	 */
	@Override
	public boolean visit(NormalAnnotation node) {
		this.fBuffer.append("@");//$NON-NLS-1$
		node.getTypeName().accept(this);
		this.fBuffer.append("(");//$NON-NLS-1$
		for (Iterator<MemberValuePair> it= node.values().iterator(); it.hasNext();) {
			MemberValuePair p= it.next();
			p.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(")");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(NullLiteral)
	 */
	@Override
	public boolean visit(NullLiteral node) {
		this.fBuffer.append("null");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(NumberLiteral)
	 */
	@Override
	public boolean visit(NumberLiteral node) {
		this.fBuffer.append(node.getToken());
		return false;
	}

	@Override
	public boolean visit(OpensDirective node) {
		return visit(node, "opens"); //$NON-NLS-1$
	}

	/*
	 * @see ASTVisitor#visit(PackageDeclaration)
	 */
	@Override
	public boolean visit(PackageDeclaration node) {
		if (node.getAST().apiLevel() >= JLS3) {
			if (node.getJavadoc() != null) {
				node.getJavadoc().accept(this);
			}
			for (Iterator<Annotation> it= node.annotations().iterator(); it.hasNext();) {
				Annotation p= it.next();
				p.accept(this);
				this.fBuffer.append(" ");//$NON-NLS-1$
			}
		}
		this.fBuffer.append("package ");//$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ParameterizedType)
	 * @since 3.0
	 */
	@Override
	public boolean visit(ParameterizedType node) {
		node.getType().accept(this);
		this.fBuffer.append("<");//$NON-NLS-1$
		for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) {
			Type t= it.next();
			t.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(">");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ParenthesizedExpression)
	 */
	@Override
	public boolean visit(ParenthesizedExpression node) {
		this.fBuffer.append("(");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(")");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(PostfixExpression)
	 */
	@Override
	public boolean visit(PostfixExpression node) {
		node.getOperand().accept(this);
		this.fBuffer.append(node.getOperator().toString());
		return false;
	}

	/*
	 * @see ASTVisitor#visit(PrefixExpression)
	 */
	@Override
	public boolean visit(PrefixExpression node) {
		this.fBuffer.append(node.getOperator().toString());
		node.getOperand().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(PrimitiveType)
	 */
	@Override
	public boolean visit(PrimitiveType node) {
		printTypeAnnotations(node);
		this.fBuffer.append(node.getPrimitiveTypeCode().toString());
		return false;
	}

	@Override
	public boolean visit(ProvidesDirective node) {
		this.fBuffer.append("provides");//$NON-NLS-1$
		this.fBuffer.append(" ");//$NON-NLS-1$
		node.getName().accept(this);
		printTypes(node.implementations(), "with"); //$NON-NLS-1$
		this.fBuffer.append(";\n");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(QualifiedName)
	 */
	@Override
	public boolean visit(QualifiedName node) {
		node.getQualifier().accept(this);
		this.fBuffer.append(".");//$NON-NLS-1$
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(QualifiedType)
	 * @since 3.0
	 */
	@Override
	public boolean visit(QualifiedType node) {
		node.getQualifier().accept(this);
		this.fBuffer.append(".");//$NON-NLS-1$
		printTypeAnnotations(node);
		node.getName().accept(this);
		return false;
	}

	@Override
	public boolean visit(RequiresDirective node) {
		this.fBuffer.append("requires");//$NON-NLS-1$
		this.fBuffer.append(" ");//$NON-NLS-1$
		printModifiers(node.modifiers());
		node.getName().accept(this);
		this.fBuffer.append(";\n");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ReturnStatement)
	 */
	@Override
	public boolean visit(ReturnStatement node) {
		this.fBuffer.append("return");//$NON-NLS-1$
		if (node.getExpression() != null) {
			this.fBuffer.append(" ");//$NON-NLS-1$
			node.getExpression().accept(this);
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SimpleName)
	 */
	@Override
	public boolean visit(SimpleName node) {
		this.fBuffer.append(node.getIdentifier());
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SimpleType)
	 */
	@Override
	public boolean visit(SimpleType node) {
		printTypeAnnotations(node);
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SingleMemberAnnotation)
	 * @since 3.0
	 */
	@Override
	public boolean visit(SingleMemberAnnotation node) {
		this.fBuffer.append("@");//$NON-NLS-1$
		node.getTypeName().accept(this);
		this.fBuffer.append("(");//$NON-NLS-1$
		node.getValue().accept(this);
		this.fBuffer.append(")");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SingleVariableDeclaration)
	 */
	@Override
	public boolean visit(SingleVariableDeclaration node) {
		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) {
					this.fBuffer.append(' ');
					List<Annotation> annotations= node.varargsAnnotations();
					printAnnotationsList(annotations);
				}
				this.fBuffer.append("...");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(" ");//$NON-NLS-1$
		node.getName().accept(this);
		if (node.getAST().apiLevel() >= JLS8) {
			List<Dimension> dimensions = node.extraDimensions();
			for (Iterator<Dimension> it= dimensions.iterator(); it.hasNext(); ) {
				Dimension e= it.next();
				e.accept(this);
			}
		} else {
			for (int i= 0; i < node.getExtraDimensions(); i++) {
				this.fBuffer.append("[]"); //$NON-NLS-1$
			}
		}
		if (node.getInitializer() != null) {
			this.fBuffer.append("=");//$NON-NLS-1$
			node.getInitializer().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(StringLiteral)
	 */
	@Override
	public boolean visit(StringLiteral node) {
		this.fBuffer.append(node.getEscapedValue());
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SuperConstructorInvocation)
	 */
	@Override
	public boolean visit(SuperConstructorInvocation node) {
		if (node.getExpression() != null) {
			node.getExpression().accept(this);
			this.fBuffer.append(".");//$NON-NLS-1$
		}
		if (node.getAST().apiLevel() >= JLS3) {
			if (!node.typeArguments().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) {
					Type t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(">");//$NON-NLS-1$
			}
		}
		this.fBuffer.append("super(");//$NON-NLS-1$
		for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(");");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SuperFieldAccess)
	 */
	@Override
	public boolean visit(SuperFieldAccess node) {
		if (node.getQualifier() != null) {
			node.getQualifier().accept(this);
			this.fBuffer.append(".");//$NON-NLS-1$
		}
		this.fBuffer.append("super.");//$NON-NLS-1$
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SuperMethodInvocation)
	 */
	@Override
	public boolean visit(SuperMethodInvocation node) {
		if (node.getQualifier() != null) {
			node.getQualifier().accept(this);
			this.fBuffer.append(".");//$NON-NLS-1$
		}
		this.fBuffer.append("super.");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS3) {
			if (!node.typeArguments().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) {
					Type t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(">");//$NON-NLS-1$
			}
		}
		node.getName().accept(this);
		this.fBuffer.append("(");//$NON-NLS-1$
		for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) {
			Expression e= it.next();
			e.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(",");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(")");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(SuperMethodReference)
	 */
	@Override
	public boolean visit(SuperMethodReference node) {
		if (node.getQualifier() != null) {
			node.getQualifier().accept(this);
			this.fBuffer.append('.');
		}
		this.fBuffer.append("super");//$NON-NLS-1$
		printReferenceTypeArguments(node.typeArguments());
		node.getName().accept(this);
		return false;
	}

	@Override
	public boolean visit(SwitchCase node) {
		if (node.getAST().isPreviewEnabled()) {
			if (node.isDefault()) {
				this.fBuffer.append("default");//$NON-NLS-1$
				this.fBuffer.append(node.isSwitchLabeledRule() ? " ->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
			} else {
				this.fBuffer.append("case ");//$NON-NLS-1$
				for (Iterator<Expression> it= node.expressions().iterator(); it.hasNext();) {
					Expression t= it.next();
					t.accept(this);
					this.fBuffer.append(it.hasNext() ? ", " : //$NON-NLS-1$
							node.isSwitchLabeledRule() ? " ->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		} else {
			if (node.isDefault()) {
				this.fBuffer.append("default :\n");//$NON-NLS-1$
			} else {
				this.fBuffer.append("case ");//$NON-NLS-1$
				node.getExpression().accept(this);
				this.fBuffer.append(":\n");//$NON-NLS-1$
			}
		}
		return false;
	}

	@Override
	public boolean visit(YieldStatement node) {
		if (node.getAST().apiLevel() == JLS13 && node.isImplicit() && node.getExpression() == null) {
			return false;
		}
		this.fBuffer.append("yield"); //$NON-NLS-1$
		if (node.getExpression() != null) {
			this.fBuffer.append(" ");//$NON-NLS-1$
			node.getExpression().accept(this);
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	@Override
	public boolean visit(SwitchStatement node) {
		visitSwitchNode(node);
		return false;
	}
	
	@Override
	public boolean visit(SwitchExpression node) {
		visitSwitchNode(node);
		return false;
	}

	private void visitSwitchNode(ASTNode node) {
		this.fBuffer.append("switch (");//$NON-NLS-1$
		if (node instanceof SwitchExpression) {
			((SwitchExpression) node).getExpression().accept(this);
		} else if (node instanceof SwitchStatement) {
			((SwitchStatement) node).getExpression().accept(this);
		}
		this.fBuffer.append(") ");//$NON-NLS-1$
		this.fBuffer.append("{\n");//$NON-NLS-1$
		if (node instanceof SwitchExpression) {
			for (Iterator<Statement> it= ((SwitchExpression) node).statements().iterator(); it.hasNext();) {
				Statement s= it.next();
				s.accept(this);
			}
		} else if (node instanceof SwitchStatement) {
			for (Iterator<Statement> it= ((SwitchStatement) node).statements().iterator(); it.hasNext();) {
				Statement s= it.next();
				s.accept(this);
			}
		}
		this.fBuffer.append("}\n");//$NON-NLS-1$
	}

	/*
	 * @see ASTVisitor#visit(SynchronizedStatement)
	 */
	@Override
	public boolean visit(SynchronizedStatement node) {
		this.fBuffer.append("synchronized (");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(") ");//$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TagElement)
	 * @since 3.0
	 */
	@Override
	public boolean visit(TagElement node) {
		if (node.isNested()) {
			// nested tags are always enclosed in braces
			this.fBuffer.append("{");//$NON-NLS-1$
		} else {
			// top-level tags always begin on a new line
			this.fBuffer.append("\n * ");//$NON-NLS-1$
		}
		boolean previousRequiresWhiteSpace= false;
		if (node.getTagName() != null) {
			this.fBuffer.append(node.getTagName());
			previousRequiresWhiteSpace= true;
		}
		boolean previousRequiresNewLine= false;
		for (Iterator<? extends ASTNode> it= node.fragments().iterator(); it.hasNext();) {
			ASTNode e= it.next();
			// assume text elements include necessary leading and trailing whitespace
			// but Name, MemberRef, MethodRef, and nested TagElement do not include white space
			boolean currentIncludesWhiteSpace= (e instanceof TextElement);
			if (previousRequiresNewLine && currentIncludesWhiteSpace) {
				this.fBuffer.append("\n * ");//$NON-NLS-1$
			}
			previousRequiresNewLine= currentIncludesWhiteSpace;
			// add space if required to separate
			if (previousRequiresWhiteSpace && !currentIncludesWhiteSpace) {
				this.fBuffer.append(" "); //$NON-NLS-1$
			}
			e.accept(this);
			previousRequiresWhiteSpace= !currentIncludesWhiteSpace && !(e instanceof TagElement);
		}
		if (node.isNested()) {
			this.fBuffer.append("}");//$NON-NLS-1$
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TextElement)
	 * @since 3.0
	 */
	@Override
	public boolean visit(TextElement node) {
		this.fBuffer.append(node.getText());
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ThisExpression)
	 */
	@Override
	public boolean visit(ThisExpression node) {
		if (node.getQualifier() != null) {
			node.getQualifier().accept(this);
			this.fBuffer.append(".");//$NON-NLS-1$
		}
		this.fBuffer.append("this");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(ThrowStatement)
	 */
	@Override
	public boolean visit(ThrowStatement node) {
		this.fBuffer.append("throw ");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TryStatement)
	 */
	@Override
	public boolean visit(TryStatement node) {
		this.fBuffer.append("try ");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS4) {
			if (!node.resources().isEmpty()) {
				this.fBuffer.append("(");//$NON-NLS-1$
				for (Iterator<Expression> it= node.resources().iterator(); it.hasNext();) {
					Expression var= it.next();
					var.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(") ");//$NON-NLS-1$
			}
		}
		node.getBody().accept(this);
		this.fBuffer.append(" ");//$NON-NLS-1$
		for (Iterator<CatchClause> it= node.catchClauses().iterator(); it.hasNext();) {
			CatchClause cc= it.next();
			cc.accept(this);
		}
		if (node.getFinally() != null) {
			this.fBuffer.append("finally ");//$NON-NLS-1$
			node.getFinally().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TypeDeclaration)
	 */
	@Override
	public boolean visit(TypeDeclaration node) {
		if (node.getJavadoc() != null) {
			node.getJavadoc().accept(this);
		}
		if (node.getAST().apiLevel() >= JLS3) {
			printModifiers(node.modifiers());
		}
		this.fBuffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$
		node.getName().accept(this);
		if (node.getAST().apiLevel() >= JLS3) {
			if (!node.typeParameters().isEmpty()) {
				this.fBuffer.append("<");//$NON-NLS-1$
				for (Iterator<TypeParameter> it= node.typeParameters().iterator(); it.hasNext();) {
					TypeParameter t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(",");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(">");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(" ");//$NON-NLS-1$
		if (node.getAST().apiLevel() >= JLS3) {
			if (node.getSuperclassType() != null) {
				this.fBuffer.append("extends ");//$NON-NLS-1$
				node.getSuperclassType().accept(this);
				this.fBuffer.append(" ");//$NON-NLS-1$
			}
			if (!node.superInterfaceTypes().isEmpty()) {
				this.fBuffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
				for (Iterator<Type> it= node.superInterfaceTypes().iterator(); it.hasNext();) {
					Type t= it.next();
					t.accept(this);
					if (it.hasNext()) {
						this.fBuffer.append(", ");//$NON-NLS-1$
					}
				}
				this.fBuffer.append(" ");//$NON-NLS-1$
			}
		}
		this.fBuffer.append("{");//$NON-NLS-1$
		BodyDeclaration prev= null;
		for (Iterator<BodyDeclaration> it= node.bodyDeclarations().iterator(); it.hasNext();) {
			BodyDeclaration d= it.next();
			if (prev instanceof EnumConstantDeclaration) {
				// enum constant declarations do not include punctuation
				if (d instanceof EnumConstantDeclaration) {
					// enum constant declarations are separated by commas
					this.fBuffer.append(", ");//$NON-NLS-1$
				} else {
					// semicolon separates last enum constant declaration from
					// first class body declarations
					this.fBuffer.append("; ");//$NON-NLS-1$
				}
			}
			d.accept(this);
			prev= d;
		}
		this.fBuffer.append("}");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TypeDeclarationStatement)
	 */
	@Override
	public boolean visit(TypeDeclarationStatement node) {
		if (node.getAST().apiLevel() >= JLS3) {
			node.getDeclaration().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TypeLiteral)
	 */
	@Override
	public boolean visit(TypeLiteral node) {
		node.getType().accept(this);
		this.fBuffer.append(".class");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TypeMethodReference)
	 */
	@Override
	public boolean visit(TypeMethodReference node) {
		node.getType().accept(this);
		printReferenceTypeArguments(node.typeArguments());
		node.getName().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(TypeParameter)
	 * @since 3.0
	 */
	@Override
	public boolean visit(TypeParameter node) {
		printModifiers(node.modifiers());
		node.getName().accept(this);
		if (!node.typeBounds().isEmpty()) {
			this.fBuffer.append(" extends ");//$NON-NLS-1$
			for (Iterator<Type> it= node.typeBounds().iterator(); it.hasNext();) {
				Type t= it.next();
				t.accept(this);
				if (it.hasNext()) {
					this.fBuffer.append(" & ");//$NON-NLS-1$
				}
			}
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(UnionType)
	 */
	@Override
	public boolean visit(UnionType node) {
		for (Iterator<Type> it= node.types().iterator(); it.hasNext();) {
			Type t= it.next();
			t.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append("|");//$NON-NLS-1$
			}
		}
		return false;
	}

	@Override
	public boolean visit(UsesDirective node) {
		this.fBuffer.append("uses");//$NON-NLS-1$
		this.fBuffer.append(" ");//$NON-NLS-1$
		node.getName().accept(this);
		this.fBuffer.append(";\n");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(VariableDeclarationExpression)
	 */
	@Override
	public boolean visit(VariableDeclarationExpression node) {
		if (node.getAST().apiLevel() >= JLS3) {
			printModifiers(node.modifiers());
		}
		node.getType().accept(this);
		this.fBuffer.append(" ");//$NON-NLS-1$
		for (Iterator<VariableDeclarationFragment> it= node.fragments().iterator(); it.hasNext();) {
			VariableDeclarationFragment f= it.next();
			f.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(", ");//$NON-NLS-1$
			}
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(VariableDeclarationFragment)
	 */
	@Override
	public boolean visit(VariableDeclarationFragment node) {
		node.getName().accept(this);
		if (node.getAST().apiLevel() >= JLS8) {
			List<Dimension> dimensions = node.extraDimensions();
			for (Iterator<Dimension> it= dimensions.iterator(); it.hasNext(); ) {
				Dimension e= it.next();
				e.accept(this);
			}
		} else {
			for (int i= 0; i < node.getExtraDimensions(); i++) {
				this.fBuffer.append("[]"); //$NON-NLS-1$
			}
		}
		if (node.getInitializer() != null) {
			this.fBuffer.append("=");//$NON-NLS-1$
			node.getInitializer().accept(this);
		}
		return false;
	}

	/*
	 * @see ASTVisitor#visit(VariableDeclarationStatement)
	 */
	@Override
	public boolean visit(VariableDeclarationStatement node) {
		if (node.getAST().apiLevel() >= JLS3) {
			printModifiers(node.modifiers());
		}
		node.getType().accept(this);
		this.fBuffer.append(" ");//$NON-NLS-1$
		for (Iterator<VariableDeclarationFragment> it= node.fragments().iterator(); it.hasNext();) {
			VariableDeclarationFragment f= it.next();
			f.accept(this);
			if (it.hasNext()) {
				this.fBuffer.append(", ");//$NON-NLS-1$
			}
		}
		this.fBuffer.append(";");//$NON-NLS-1$
		return false;
	}

	/*
	 * @see ASTVisitor#visit(WhileStatement)
	 */
	@Override
	public boolean visit(WhileStatement node) {
		this.fBuffer.append("while (");//$NON-NLS-1$
		node.getExpression().accept(this);
		this.fBuffer.append(") ");//$NON-NLS-1$
		node.getBody().accept(this);
		return false;
	}

	/*
	 * @see ASTVisitor#visit(WildcardType)
	 * @since 3.0
	 */
	@Override
	public boolean visit(WildcardType node) {
		printTypeAnnotations(node);
		this.fBuffer.append("?");//$NON-NLS-1$
		Type bound= node.getBound();
		if (bound != null) {
			if (node.isUpperBound()) {
				this.fBuffer.append(" extends ");//$NON-NLS-1$
			} else {
				this.fBuffer.append(" super ");//$NON-NLS-1$
			}
			bound.accept(this);
		}
		return false;
	}

}
