/*******************************************************************************
 * Copyright (c) 2014, 2019 Mateusz Matela 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/
 *
 * 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.
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
 *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] IndexOutOfBoundsException in TokenManager - https://bugs.eclipse.org/462945
 *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] follow up bug for comments - https://bugs.eclipse.org/458208
 *     IBM Corporation - DOM AST changes for JEP 354
 *******************************************************************************/
package org.eclipse.jdt.internal.formatter;

import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ArrayAccess;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.AssertStatement;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.BaseCallMessageSend;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CallinMappingDeclaration;
import org.eclipse.jdt.core.dom.CalloutMappingDeclaration;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.CreationReference;
import org.eclipse.jdt.core.dom.Dimension;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EmptyStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.ExportsDirective;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionMethodReference;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.GuardPredicateDeclaration;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.IntersectionType;
import org.eclipse.jdt.core.dom.LabeledStatement;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.MethodSpec;
import org.eclipse.jdt.core.dom.ModuleDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.OpensDirective;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.ParameterMapping;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.RoleTypeDeclaration;
import org.eclipse.jdt.core.dom.ProvidesDirective;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.SuperMethodReference;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchExpression;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.SynchronizedStatement;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeMethodReference;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.UnionType;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.core.dom.WildcardType;
import org.eclipse.jdt.core.dom.WithinStatement;
import org.eclipse.jdt.core.dom.YieldStatement;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;

public class SpacePreparator extends ASTVisitor {

	private static final Map<Operator, Predicate<DefaultCodeFormatterOptions>> SPACE_BEFORE_OPERATOR;
	private static final Map<Operator, Predicate<DefaultCodeFormatterOptions>> SPACE_AFTER_OPERATOR;

	static {
		Map<Operator, Predicate<DefaultCodeFormatterOptions>> spaceBeforeOperator = new HashMap<>();
		Map<Operator, Predicate<DefaultCodeFormatterOptions>> spaceAfterOperator = new HashMap<>();
		for (Operator op : Arrays.asList(Operator.TIMES, Operator.DIVIDE, Operator.REMAINDER)) {
			spaceBeforeOperator.put(op, o -> o.insert_space_before_multiplicative_operator);
			spaceAfterOperator.put(op, o -> o.insert_space_after_multiplicative_operator);
		}
		for (Operator op : Arrays.asList(Operator.PLUS, Operator.MINUS)) {
			spaceBeforeOperator.put(op, o -> o.insert_space_before_additive_operator);
			spaceAfterOperator.put(op, o -> o.insert_space_after_additive_operator);
		}
		for (Operator op : Arrays.asList(Operator.LEFT_SHIFT, Operator.RIGHT_SHIFT_SIGNED,
				Operator.RIGHT_SHIFT_UNSIGNED)) {
			spaceBeforeOperator.put(op, o -> o.insert_space_before_shift_operator);
			spaceAfterOperator.put(op, o -> o.insert_space_after_shift_operator);
		}
		for (Operator op : Arrays.asList(Operator.LESS, Operator.GREATER, Operator.LESS_EQUALS,
				Operator.GREATER_EQUALS, Operator.EQUALS, Operator.NOT_EQUALS)) {
			spaceBeforeOperator.put(op, o -> o.insert_space_before_relational_operator);
			spaceAfterOperator.put(op, o -> o.insert_space_after_relational_operator);
		}
		for (Operator op : Arrays.asList(Operator.AND, Operator.XOR, Operator.OR)) {
			spaceBeforeOperator.put(op, o -> o.insert_space_before_bitwise_operator);
			spaceAfterOperator.put(op, o -> o.insert_space_after_bitwise_operator);
		}
		for (Operator op : Arrays.asList(Operator.CONDITIONAL_AND, Operator.CONDITIONAL_OR)) {
			spaceBeforeOperator.put(op, o -> o.insert_space_before_logical_operator);
			spaceAfterOperator.put(op, o -> o.insert_space_after_logical_operator);
		}
		SPACE_BEFORE_OPERATOR = Collections.unmodifiableMap(spaceBeforeOperator);
		SPACE_AFTER_OPERATOR = Collections.unmodifiableMap(spaceAfterOperator);
	}

	TokenManager tm;
	private DefaultCodeFormatterOptions options;

	public SpacePreparator(TokenManager tokenManager, DefaultCodeFormatterOptions options) {
		this.tm = tokenManager;
		this.options = options;
	}

	@Override
	public boolean preVisit2(ASTNode node) {
		boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
		return !isMalformed;
	}

	@Override
	public boolean visit(PackageDeclaration node) {
		handleSemicolon(node);
		return true;
	}

	@Override
	public boolean visit(ImportDeclaration node) {
		handleSemicolon(node);
		return true;
	}

	@Override
	public boolean visit(TypeDeclaration node) {
		if (node.getName().getStartPosition() == -1)
			return true; // this is a fake type created by parsing in class body mode

		handleToken(node.getName(), TokenNameIdentifier, true, false);

		List<TypeParameter> typeParameters = node.typeParameters();
		handleTypeParameters(typeParameters);

		if (!node.isInterface() && !node.superInterfaceTypes().isEmpty()) {
			// fix for: class A<E> extends ArrayList<String>implements Callable<String>
			handleToken(node.getName(), TokenNameimplements, true, false);
		}

		handleToken(node.getName(), TokenNameLBRACE,
				this.options.insert_space_before_opening_brace_in_type_declaration, false);
		handleCommas(node.superInterfaceTypes(), this.options.insert_space_before_comma_in_superinterfaces,
				this.options.insert_space_after_comma_in_superinterfaces);
		return true;
	}

	@Override
	public boolean visit(EnumDeclaration node) {
		handleToken(node.getName(), TokenNameLBRACE,
				this.options.insert_space_before_opening_brace_in_enum_declaration, false);
		handleCommas(node.superInterfaceTypes(), this.options.insert_space_before_comma_in_superinterfaces,
				this.options.insert_space_after_comma_in_superinterfaces);
		handleCommas(node.enumConstants(), this.options.insert_space_before_comma_in_enum_declarations,
				this.options.insert_space_after_comma_in_enum_declarations);
		return true;
	}

	@Override
	public boolean visit(EnumConstantDeclaration node) {
		List<Expression> arguments = node.arguments();
		Token openingParen = null;
		if (!arguments.isEmpty()) {
			openingParen = this.tm.firstTokenIn(node, TokenNameLPAREN);
			if (this.options.insert_space_after_opening_paren_in_enum_constant)
				openingParen.spaceAfter();
			handleTokenAfter(arguments.get(arguments.size() - 1), TokenNameRPAREN,
					this.options.insert_space_before_closing_paren_in_enum_constant, false);
		} else {
			// look for empty parenthesis, may not be there
			int from = this.tm.firstIndexIn(node.getName(), TokenNameIdentifier) + 1;
			AnonymousClassDeclaration classDeclaration = node.getAnonymousClassDeclaration();
			int to = classDeclaration != null ? this.tm.firstIndexBefore(classDeclaration, -1)
					: this.tm.lastIndexIn(node, -1); 
			for (int i = from; i <= to; i++) {
				if (this.tm.get(i).tokenType == TokenNameLPAREN) {
					openingParen = this.tm.get(i);
					if (this.options.insert_space_between_empty_parens_in_enum_constant)
						openingParen.spaceAfter();
					break;
				}
			}
		}
		if (openingParen != null && this.options.insert_space_before_opening_paren_in_enum_constant)
			openingParen.spaceBefore();
		handleCommas(arguments, this.options.insert_space_before_comma_in_enum_constant_arguments,
				this.options.insert_space_after_comma_in_enum_constant_arguments);
		return true;
	}

	@Override
	public boolean visit(AnonymousClassDeclaration node) {
		boolean spaceBeforeOpenBrace = this.options.insert_space_before_opening_brace_in_anonymous_type_declaration;
		if (node.getParent() instanceof EnumConstantDeclaration)
			spaceBeforeOpenBrace = this.options.insert_space_before_opening_brace_in_enum_constant;
		handleToken(node, TokenNameLBRACE, spaceBeforeOpenBrace, false);
		return true;
	}

	@Override
	public boolean visit(MethodDeclaration node) {
		handleToken(node.getName(), TokenNameIdentifier, true, false);

		boolean spaceBeforeOpenParen = node.isConstructor()
				? this.options.insert_space_before_opening_paren_in_constructor_declaration
				: this.options.insert_space_before_opening_paren_in_method_declaration;
		boolean spaceAfterOpenParen = node.isConstructor()
				? this.options.insert_space_after_opening_paren_in_constructor_declaration
				: this.options.insert_space_after_opening_paren_in_method_declaration;
		boolean spaceBetweenEmptyParens = node.isConstructor()
				? this.options.insert_space_between_empty_parens_in_constructor_declaration
				: this.options.insert_space_between_empty_parens_in_method_declaration;
		if (handleEmptyParens(node.getName(), spaceBetweenEmptyParens)) {
			handleToken(node.getName(), TokenNameLPAREN, spaceBeforeOpenParen, false);
		} else {
			handleToken(node.getName(), TokenNameLPAREN, spaceBeforeOpenParen, spaceAfterOpenParen);

			boolean spaceBeforeCloseParen = node.isConstructor()
					? this.options.insert_space_before_closing_paren_in_constructor_declaration
					: this.options.insert_space_before_closing_paren_in_method_declaration;
			if (spaceBeforeCloseParen) {
				List<SingleVariableDeclaration> params = node.parameters();
				ASTNode beforeBrace = params.isEmpty() ? node.getName() : params.get(params.size() - 1);
				handleTokenAfter(beforeBrace, TokenNameRPAREN, true, false);
			}
		}

		if ((node.isConstructor() ? this.options.insert_space_before_opening_brace_in_constructor_declaration
				: this.options.insert_space_before_opening_brace_in_method_declaration) && node.getBody() != null)
			this.tm.firstTokenIn(node.getBody(), TokenNameLBRACE).spaceBefore();

		if (node.getReceiverType() != null)
			this.tm.lastTokenIn(node.getReceiverType(), -1).spaceAfter();

		boolean beforeComma = node.isConstructor()
				? this.options.insert_space_before_comma_in_constructor_declaration_parameters
				: this.options.insert_space_before_comma_in_method_declaration_parameters;
		boolean afterComma = node.isConstructor()
				? this.options.insert_space_after_comma_in_constructor_declaration_parameters
				: this.options.insert_space_after_comma_in_method_declaration_parameters;
		List<SingleVariableDeclaration> params = node.parameters();
		if (node.getReceiverType() != null) {
			params = new ArrayList<>(params);
			params.add(0, null); // space for explicit receiver, null OK - first value not read in handleCommas 
		}
		handleCommas(params, beforeComma, afterComma);

		List<Type> thrownExceptionTypes = node.thrownExceptionTypes();
		if (!thrownExceptionTypes.isEmpty()) {
			this.tm.firstTokenBefore(thrownExceptionTypes.get(0), TokenNamethrows).spaceBefore();

			beforeComma = node.isConstructor()
					? this.options.insert_space_before_comma_in_constructor_declaration_throws
					: this.options.insert_space_before_comma_in_method_declaration_throws;
			afterComma = node.isConstructor()
					? this.options.insert_space_after_comma_in_constructor_declaration_throws
					: this.options.insert_space_after_comma_in_method_declaration_throws;
			handleCommas(thrownExceptionTypes, beforeComma, afterComma);
		}

		List<TypeParameter> typeParameters = node.typeParameters();
		if (!typeParameters.isEmpty()) {
			handleTypeParameters(typeParameters);
			handleTokenBefore(typeParameters.get(0), TokenNameLESS, true, false);
			handleTokenAfter(typeParameters.get(typeParameters.size() - 1), TokenNameGREATER, false, true);
		}

		handleSemicolon(node);
		return true;
	}

	private void handleTypeParameters(List<TypeParameter> typeParameters) {
		if (!typeParameters.isEmpty()) {
			handleTokenBefore(typeParameters.get(0), TokenNameLESS,
					this.options.insert_space_before_opening_angle_bracket_in_type_parameters,
					this.options.insert_space_after_opening_angle_bracket_in_type_parameters);
			handleTokenAfter(typeParameters.get(typeParameters.size() - 1), TokenNameGREATER,
					this.options.insert_space_before_closing_angle_bracket_in_type_parameters,
					this.options.insert_space_after_closing_angle_bracket_in_type_parameters);
			handleCommas(typeParameters, this.options.insert_space_before_comma_in_type_parameters,
					this.options.insert_space_after_comma_in_type_parameters);
		}
	}

	@Override
	public boolean visit(FieldDeclaration node) {
		handleToken((ASTNode) node.fragments().get(0), TokenNameIdentifier, true, false);
		handleCommas(node.fragments(), this.options.insert_space_before_comma_in_multiple_field_declarations,
				this.options.insert_space_after_comma_in_multiple_field_declarations);
		handleSemicolon(node);
		return true;
	}

	@Override
	public boolean visit(VariableDeclarationStatement node) {
		handleToken((ASTNode) node.fragments().get(0), TokenNameIdentifier, true, false);
		handleCommas(node.fragments(), this.options.insert_space_before_comma_in_multiple_local_declarations,
				this.options.insert_space_after_comma_in_multiple_local_declarations);
		return true;
	}

	@Override
	public boolean visit(VariableDeclarationFragment node) {
		if (node.getInitializer() != null) {
			handleToken(node.getName(), TokenNameEQUAL, this.options.insert_space_before_assignment_operator,
					this.options.insert_space_after_assignment_operator);
		}
		return true;
	}

	@Override
	public void endVisit(SingleVariableDeclaration node) {
		// this must be endVisit in case a space added by a visit on a child node needs to be cleared
		if (node.isVarargs()) {
			handleTokenBefore(node.getName(), TokenNameELLIPSIS, this.options.insert_space_before_ellipsis,
					this.options.insert_space_after_ellipsis);
			List<Annotation> varargsAnnotations = node.varargsAnnotations();
			if (!varargsAnnotations.isEmpty()) {
				this.tm.firstTokenIn(varargsAnnotations.get(0), TokenNameAT).spaceBefore();
				this.tm.lastTokenIn(varargsAnnotations.get(varargsAnnotations.size() - 1), -1).clearSpaceAfter();
			}
		} else {
			handleToken(node.getName(), TokenNameIdentifier, true, false);
		}
	}

	@Override
	public boolean visit(SwitchStatement node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_switch,
				this.options.insert_space_after_opening_paren_in_switch);
		handleTokenAfter(node.getExpression(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_switch, false);
		handleTokenAfter(node.getExpression(), TokenNameLBRACE,
				this.options.insert_space_before_opening_brace_in_switch, false);
		handleSemicolon(node.statements());
		return true;
	}

	@Override
	public boolean visit(SwitchExpression node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_switch,
				this.options.insert_space_after_opening_paren_in_switch);
		handleTokenAfter(node.getExpression(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_switch, false);
		handleTokenAfter(node.getExpression(), TokenNameLBRACE,
				this.options.insert_space_before_opening_brace_in_switch, false);
		handleSemicolon(node.statements());
		return true;
	}

	@Override
	public boolean visit(SwitchCase node) {
		if (node.getAST().apiLevel() == AST.JLS13 && node.isSwitchLabeledRule()) {
			handleToken(this.tm.lastTokenIn(node, TokenNameARROW),
					node.isDefault() ? this.options.insert_space_before_arrow_in_switch_default
							: this.options.insert_space_before_arrow_in_switch_case,
					node.isDefault() ? this.options.insert_space_after_arrow_in_switch_default
							: this.options.insert_space_after_arrow_in_switch_case);
		} else {
			handleToken(this.tm.lastTokenIn(node, TokenNameCOLON),
					node.isDefault() ? this.options.insert_space_before_colon_in_default
							: this.options.insert_space_before_colon_in_case,
					false);
		}
		if (!node.isDefault()) {
			handleToken(node, TokenNamecase, false, true);
			if (node.getAST().apiLevel() == AST.JLS13) {
				handleCommas(node.expressions(), this.options.insert_space_before_comma_in_switch_case_expressions,
					this.options.insert_space_after_comma_in_switch_case_expressions);
			}
		}
		return true;
	}

	@Override
	public boolean visit(YieldStatement node) {
		if (node.getExpression() != null && !node.isImplicit()) {
			this.tm.firstTokenIn(node, -1).spaceAfter();
		}
		return true;
	}

	@Override
	public boolean visit(DoStatement node) {
		handleTokenBefore(node.getExpression(), TokenNameLPAREN,
				this.options.insert_space_before_opening_paren_in_while,
				this.options.insert_space_after_opening_paren_in_while);
		handleTokenBefore(node.getExpression(), TokenNamewhile,
				!(node.getBody() instanceof Block) || this.options.insert_space_after_closing_brace_in_block, false);
		handleTokenAfter(node.getExpression(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_while, false);
		return true;
	}

	@Override
	public boolean visit(WhileStatement node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_while,
				this.options.insert_space_after_opening_paren_in_while);
		handleTokenBefore(node.getBody(), TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_while,
				false);
		handleLoopBody(node.getBody());
		return true;
	}

	@Override
	public boolean visit(SynchronizedStatement node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_synchronized,
				this.options.insert_space_after_opening_paren_in_synchronized);
		handleTokenBefore(node.getBody(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_synchronized, false);
		return true;
	}

	@Override
	public boolean visit(TryStatement node) {
		List<Expression> resources = node.resources();
		if (!resources.isEmpty()) {
			handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_try,
					this.options.insert_space_after_opening_paren_in_try);
			handleTokenBefore(node.getBody(), TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_try,
					false);
			for (int i = 1; i < resources.size(); i++) {
				handleTokenBefore(resources.get(i), TokenNameSEMICOLON,
						this.options.insert_space_before_semicolon_in_try_resources,
						this.options.insert_space_after_semicolon_in_try_resources);
			}
			// there can be a semicolon after the last resource
			int index = this.tm.firstIndexAfter(resources.get(resources.size() - 1), -1);
			while (index < this.tm.size()) {
				Token token = this.tm.get(index++);
				if (token.tokenType == TokenNameSEMICOLON) {
					handleToken(token, this.options.insert_space_before_semicolon_in_try_resources, false);
				} else if (token.tokenType == TokenNameRPAREN) {
					break;
				}
			}
		}
		return true;
	}

	@Override
	public boolean visit(CatchClause node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_catch,
				this.options.insert_space_after_opening_paren_in_catch);
		handleTokenBefore(node.getBody(), TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_catch,
				false);
		return true;
	}

	@Override
	public boolean visit(AssertStatement node) {
		this.tm.firstTokenIn(node, TokenNameassert).spaceAfter();
		if (node.getMessage() != null) {
			handleTokenBefore(node.getMessage(), TokenNameCOLON, this.options.insert_space_before_colon_in_assert,
					this.options.insert_space_after_colon_in_assert);
		}
		return true;
	}

	@Override
	public boolean visit(ReturnStatement node) {
		if (node.getExpression() != null) {
			int returnTokenIndex = this.tm.firstIndexIn(node, TokenNamereturn);
			if (!(node.getExpression() instanceof ParenthesizedExpression)
					|| this.options.insert_space_before_parenthesized_expression_in_return) {
				this.tm.get(returnTokenIndex).spaceAfter();
			}
		}
		return true;
	}

	@Override
	public boolean visit(ThrowStatement node) {
		int returnTokenIndex = this.tm.firstIndexIn(node, TokenNamethrow);
		if (this.tm.get(returnTokenIndex + 1).tokenType != TokenNameLPAREN
				|| this.options.insert_space_before_parenthesized_expression_in_throw) {
			this.tm.get(returnTokenIndex).spaceAfter();
		}
		return true;
	}

	@Override
	public boolean visit(LabeledStatement node) {
		handleToken(node, TokenNameCOLON, this.options.insert_space_before_colon_in_labeled_statement,
				this.options.insert_space_after_colon_in_labeled_statement);
		return true;
	}

	@Override
	public boolean visit(AnnotationTypeDeclaration node) {
		handleToken(node, TokenNameAT, this.options.insert_space_before_at_in_annotation_type_declaration,
				this.options.insert_space_after_at_in_annotation_type_declaration);
		handleToken(node.getName(), TokenNameLBRACE,
				this.options.insert_space_before_opening_brace_in_annotation_type_declaration, false);
		return true;
	}

	@Override
	public boolean visit(AnnotationTypeMemberDeclaration node) {
		handleToken(node.getName(), TokenNameIdentifier, true, false);
		handleToken(node.getName(), TokenNameLPAREN,
				this.options.insert_space_before_opening_paren_in_annotation_type_member_declaration, false);
		handleEmptyParens(node.getName(),
				this.options.insert_space_between_empty_parens_in_annotation_type_member_declaration);
		if (node.getDefault() != null)
			handleTokenBefore(node.getDefault(), TokenNamedefault, true, true);
		return true;
	}

	@Override
	public boolean visit(NormalAnnotation node) {
		handleAnnotation(node, true);
		handleCommas(node.values(), this.options.insert_space_before_comma_in_annotation,
				this.options.insert_space_after_comma_in_annotation);
		return true;
	}

	@Override
	public boolean visit(MemberValuePair node) {
		handleToken(node, TokenNameEQUAL, this.options.insert_space_before_assignment_operator,
				this.options.insert_space_after_assignment_operator);
		return true;
	}

	@Override
	public boolean visit(SingleMemberAnnotation node) {
		handleAnnotation(node, true);
		return true;
	}

	@Override
	public boolean visit(MarkerAnnotation node) {
		handleAnnotation(node, false);
		return true;
	}

	private void handleAnnotation(Annotation node, boolean handleParenthesis) {
		handleToken(node, TokenNameAT, false, this.options.insert_space_after_at_in_annotation);
		if (handleParenthesis) {
			handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_annotation,
					this.options.insert_space_after_opening_paren_in_annotation);
			if (this.options.insert_space_before_closing_paren_in_annotation)
				this.tm.lastTokenIn(node, TokenNameRPAREN).spaceBefore();
		}

		ASTNode parent = node.getParent();
		boolean skipSpaceAfter = parent instanceof Annotation || parent instanceof MemberValuePair
				|| (parent instanceof AnnotationTypeMemberDeclaration
						&& ((AnnotationTypeMemberDeclaration) parent).getDefault() == node)
				|| parent instanceof ArrayInitializer;
		if (!skipSpaceAfter)
			this.tm.lastTokenIn(node, -1).spaceAfter();
	}

	@Override
	public boolean visit(LambdaExpression node) {
		handleToken(node, TokenNameARROW, this.options.insert_space_before_lambda_arrow,
				this.options.insert_space_after_lambda_arrow);
		List<VariableDeclaration> parameters = node.parameters();
		if (node.hasParentheses()) {
			if (handleEmptyParens(node, this.options.insert_space_between_empty_parens_in_method_declaration)) {
				handleToken(node, TokenNameLPAREN,
						this.options.insert_space_before_opening_paren_in_method_declaration, false);
			} else {
				handleToken(node, TokenNameLPAREN,
						this.options.insert_space_before_opening_paren_in_method_declaration,
						this.options.insert_space_after_opening_paren_in_method_declaration);

				handleTokenBefore(node.getBody(), TokenNameRPAREN,
						this.options.insert_space_before_closing_paren_in_method_declaration, false);
			}
			handleCommas(parameters, this.options.insert_space_before_comma_in_method_declaration_parameters,
					this.options.insert_space_after_comma_in_method_declaration_parameters);
		}
		return true;
	}

	@Override
	public boolean visit(Block node) {
		handleSemicolon(node.statements());

		ASTNode parent = node.getParent();
		if (parent.getLength() == 0)
			return true; // this is a fake block created by parsing in statements mode
		if (parent instanceof MethodDeclaration)
			return true; // spaces handled in #visit(MethodDeclaration)

		handleToken(node, TokenNameLBRACE, this.options.insert_space_before_opening_brace_in_block, false);
		if (this.options.insert_space_after_closing_brace_in_block
				&& (parent instanceof Statement || parent instanceof CatchClause)) {
			int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
			this.tm.get(closeBraceIndex).spaceAfter();
		}
		return true;
	}

	@Override
	public boolean visit(IfStatement node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_if,
				this.options.insert_space_after_opening_paren_in_if);

		Statement thenStatement = node.getThenStatement();
		handleTokenBefore(thenStatement, TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_if, false);

		handleLoopBody(thenStatement);
		handleSemicolon(thenStatement);
		return true;
	}

	@Override
	public boolean visit(ForStatement node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_for,
				this.options.insert_space_after_opening_paren_in_for);
		handleTokenBefore(node.getBody(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_for, false);
		handleCommas(node.initializers(), this.options.insert_space_before_comma_in_for_inits,
				this.options.insert_space_after_comma_in_for_inits);
		handleCommas(node.updaters(), this.options.insert_space_before_comma_in_for_increments,
				this.options.insert_space_after_comma_in_for_increments);

		boolean part1Empty = node.initializers().isEmpty();
		boolean part2Empty = node.getExpression() == null;
		boolean part3Empty = node.updaters().isEmpty();
		handleToken(node, TokenNameSEMICOLON, this.options.insert_space_before_semicolon_in_for && !part1Empty,
				this.options.insert_space_after_semicolon_in_for && !part2Empty);
		handleTokenBefore(node.getBody(), TokenNameSEMICOLON,
				this.options.insert_space_before_semicolon_in_for && !part2Empty,
				this.options.insert_space_after_semicolon_in_for && !part3Empty);

		handleLoopBody(node.getBody());
		return true;
	}

	@Override
	public boolean visit(VariableDeclarationExpression node) {
		ASTNode parent = node.getParent();
		if (parent instanceof ForStatement) {
			handleCommas(node.fragments(), this.options.insert_space_before_comma_in_for_inits,
					this.options.insert_space_after_comma_in_for_inits);
		} else if (parent instanceof ExpressionStatement) {
			handleCommas(node.fragments(), this.options.insert_space_before_comma_in_multiple_local_declarations,
					this.options.insert_space_after_comma_in_multiple_local_declarations);
		}
		this.tm.firstTokenAfter(node.getType(), -1).spaceBefore();
		return true;
	}

	@Override
	public boolean visit(EnhancedForStatement node) {
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_for,
				this.options.insert_space_after_opening_paren_in_for);
		handleTokenBefore(node.getBody(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_for, false);
		handleTokenAfter(node.getParameter(), TokenNameCOLON, this.options.insert_space_before_colon_in_for,
				this.options.insert_space_after_colon_in_for);
		handleLoopBody(node.getBody());
		return true;
	}

	@Override
	public boolean visit(MethodInvocation node) {
		handleTypeArguments(node.typeArguments());
		handleInvocation(node, node.getName());
		handleCommas(node.arguments(), this.options.insert_space_before_comma_in_method_invocation_arguments,
				this.options.insert_space_after_comma_in_method_invocation_arguments);
		return true;
	}

	@Override
	public boolean visit(SuperMethodInvocation node) {
		handleTypeArguments(node.typeArguments());
		handleInvocation(node, node.getName());
		handleCommas(node.arguments(), this.options.insert_space_before_comma_in_method_invocation_arguments,
				this.options.insert_space_after_comma_in_method_invocation_arguments);
		return true;
	}

	@Override
	public boolean visit(ClassInstanceCreation node) {
		List<Type> typeArguments = node.typeArguments();
		handleTypeArguments(typeArguments);
		handleInvocation(node, node.getType(), node.getAnonymousClassDeclaration());
		if (!typeArguments.isEmpty()) {
			handleTokenBefore(typeArguments.get(0), TokenNamenew, false, true); // fix for: new<Integer>A<String>()
		}
		handleCommas(node.arguments(), this.options.insert_space_before_comma_in_allocation_expression,
				this.options.insert_space_after_comma_in_allocation_expression);
		return true;
	}

	@Override
	public boolean visit(ConstructorInvocation node) {
		handleTypeArguments(node.typeArguments());
		handleInvocation(node, node);
		handleCommas(node.arguments(),
				this.options.insert_space_before_comma_in_explicit_constructor_call_arguments,
				this.options.insert_space_after_comma_in_explicit_constructor_call_arguments);
		return true;
	}

	@Override
	public boolean visit(SuperConstructorInvocation node) {
		handleTypeArguments(node.typeArguments());
		handleInvocation(node, node);
		handleCommas(node.arguments(),
				this.options.insert_space_before_comma_in_explicit_constructor_call_arguments,
				this.options.insert_space_after_comma_in_explicit_constructor_call_arguments);
		return true;
	}

	private void handleInvocation(ASTNode invocationNode, ASTNode nodeBeforeOpeningParen) {
		handleInvocation(invocationNode, nodeBeforeOpeningParen, null);
	}

	private void handleInvocation(ASTNode invocationNode, ASTNode nodeBeforeOpeningParen,
			ASTNode nodeAfterClosingParen) {
		if (handleEmptyParens(nodeBeforeOpeningParen,
				this.options.insert_space_between_empty_parens_in_method_invocation)) {
			handleToken(nodeBeforeOpeningParen, TokenNameLPAREN,
					this.options.insert_space_before_opening_paren_in_method_invocation, false);
		} else {
			handleToken(nodeBeforeOpeningParen, TokenNameLPAREN,
					this.options.insert_space_before_opening_paren_in_method_invocation,
					this.options.insert_space_after_opening_paren_in_method_invocation);
			if (this.options.insert_space_before_closing_paren_in_method_invocation) {
				Token closingParen = nodeAfterClosingParen == null
						? this.tm.lastTokenIn(invocationNode, TokenNameRPAREN)
						: this.tm.firstTokenBefore(nodeAfterClosingParen, TokenNameRPAREN);
				closingParen.spaceBefore();
			}
		}
	}

	@Override
	public boolean visit(Assignment node) {
		handleOperator(node.getOperator().toString(), node.getRightHandSide(),
				this.options.insert_space_before_assignment_operator,
				this.options.insert_space_after_assignment_operator);
		return true;
	}

	@Override
	public boolean visit(InfixExpression node) {
		Operator operator = node.getOperator();
		boolean spaceBefore = SPACE_BEFORE_OPERATOR.get(operator).test(this.options);
		boolean spaceAfter = SPACE_AFTER_OPERATOR.get(operator).test(this.options);
		if (this.tm.isStringConcatenation(node)) {
			spaceBefore = this.options.insert_space_before_string_concatenation;
			spaceAfter = this.options.insert_space_after_string_concatenation;
		}
		handleOperator(operator.toString(), node.getRightOperand(), spaceBefore, spaceAfter);
		List<Expression> extendedOperands = node.extendedOperands();
		for (Expression operand : extendedOperands) {
			handleOperator(operator.toString(), operand, spaceBefore, spaceAfter);
		}
		return true;
	}

	@Override
	public boolean visit(PrefixExpression node) {
		PrefixExpression.Operator operator = node.getOperator();
		if (operator.equals(PrefixExpression.Operator.INCREMENT)
				|| operator.equals(PrefixExpression.Operator.DECREMENT)) {
			handleOperator(operator.toString(), node.getOperand(),
					this.options.insert_space_before_prefix_operator,
					this.options.insert_space_after_prefix_operator);
		} else {
			handleOperator(operator.toString(), node.getOperand(), this.options.insert_space_before_unary_operator,
					this.options.insert_space_after_unary_operator);
		}
		return true;
	}

	@Override
	public boolean visit(PostfixExpression node) {
		if (this.options.insert_space_before_postfix_operator || this.options.insert_space_after_postfix_operator) {
			String operator = node.getOperator().toString();
			int i = this.tm.firstIndexAfter(node.getOperand(), -1);
			while (!operator.equals(this.tm.toString(i))) {
				i++;
			}
			handleToken(this.tm.get(i), this.options.insert_space_before_postfix_operator,
					this.options.insert_space_after_postfix_operator);
		}
		return true;
	}

	private void handleOperator(String operator, ASTNode nodeAfter, boolean spaceBefore, boolean spaceAfter) {
		if (spaceBefore || spaceAfter) {
			int i = this.tm.firstIndexBefore(nodeAfter, -1);
			while (!operator.equals(this.tm.toString(i))) {
				i--;
			}
			handleToken(this.tm.get(i), spaceBefore, spaceAfter);
		}
	}

	@Override
	public boolean visit(ParenthesizedExpression node) {
		handleToken(node, TokenNameLPAREN,
				this.options.insert_space_before_opening_paren_in_parenthesized_expression,
				this.options.insert_space_after_opening_paren_in_parenthesized_expression);
		handleTokenAfter(node.getExpression(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_parenthesized_expression, false);
		return true;
	}

	@Override
	public boolean visit(CastExpression node) {
		handleToken(node, TokenNameLPAREN, false, this.options.insert_space_after_opening_paren_in_cast);
		handleTokenBefore(node.getExpression(), TokenNameRPAREN,
				this.options.insert_space_before_closing_paren_in_cast,
				this.options.insert_space_after_closing_paren_in_cast);
		return true;
	}

	@Override
	public boolean visit(IntersectionType node) {
		List<Type> types = node.types();
		for (int i = 1; i < types.size(); i++)
			handleTokenBefore(types.get(i), TokenNameAND, this.options.insert_space_before_bitwise_operator,
					this.options.insert_space_after_bitwise_operator);
		return true;
	}

	@Override
	public boolean visit(ConditionalExpression node) {
		handleTokenBefore(node.getThenExpression(), TokenNameQUESTION,
				this.options.insert_space_before_question_in_conditional,
				this.options.insert_space_after_question_in_conditional);
		handleTokenBefore(node.getElseExpression(), TokenNameCOLON,
				this.options.insert_space_before_colon_in_conditional,
				this.options.insert_space_after_colon_in_conditional);
		return true;
	}

	@Override
	public boolean visit(ArrayType node) {
		ASTNode parent = node.getParent();
		boolean spaceBeofreOpening, spaceBetween;
		if (parent instanceof ArrayCreation) {
			spaceBeofreOpening = this.options.insert_space_before_opening_bracket_in_array_allocation_expression;
			spaceBetween = this.options.insert_space_between_empty_brackets_in_array_allocation_expression;
		} else {
			spaceBeofreOpening = this.options.insert_space_before_opening_bracket_in_array_type_reference;
			spaceBetween = this.options.insert_space_between_brackets_in_array_type_reference;
		}
		List<Dimension> dimensions = node.dimensions();
		for (Dimension dimension : dimensions) {
			handleToken(dimension, TokenNameLBRACKET, spaceBeofreOpening, false);
			handleEmptyBrackets(dimension, spaceBetween);
		}
		return true;
	}

	@Override
	public boolean visit(ArrayAccess node) {
		handleTokenBefore(node.getIndex(), TokenNameLBRACKET,
				this.options.insert_space_before_opening_bracket_in_array_reference,
				this.options.insert_space_after_opening_bracket_in_array_reference);
		handleTokenAfter(node.getIndex(), TokenNameRBRACKET,
				this.options.insert_space_before_closing_bracket_in_array_reference, false);
		return true;
	}

	@Override
	public boolean visit(ArrayCreation node) {
		List<Expression> dimensions = node.dimensions();
		for (Expression dimension : dimensions) {
			handleTokenBefore(dimension, TokenNameLBRACKET, false,
					this.options.insert_space_after_opening_bracket_in_array_allocation_expression);
			handleTokenAfter(dimension, TokenNameRBRACKET,
					this.options.insert_space_before_closing_bracket_in_array_allocation_expression, false);
		}
		return true;
	}

	@Override
	public boolean visit(ArrayInitializer node) {
		int openingBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
		int closingBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
		Token lastToken = this.tm.get(closingBraceIndex - 1);
		if (lastToken.tokenType == TokenNameLBRACE) {
			handleToken(this.tm.get(openingBraceIndex),
					this.options.insert_space_before_opening_brace_in_array_initializer
							&& !(node.getParent() instanceof ArrayInitializer)
							&& !(node.getParent() instanceof SingleMemberAnnotation),
					this.options.insert_space_between_empty_braces_in_array_initializer);
		} else {
			boolean endsWithComma = lastToken.tokenType == TokenNameCOMMA;
			handleToken(this.tm.get(openingBraceIndex),
					this.options.insert_space_before_opening_brace_in_array_initializer
							&& !(node.getParent() instanceof ArrayInitializer)
							&& !(node.getParent() instanceof SingleMemberAnnotation),
					this.options.insert_space_after_opening_brace_in_array_initializer
							&& !(endsWithComma && node.expressions().isEmpty()));
			handleCommas(node.expressions(), this.options.insert_space_before_comma_in_array_initializer,
					this.options.insert_space_after_comma_in_array_initializer);
			if (endsWithComma) {
				handleToken(lastToken, this.options.insert_space_before_comma_in_array_initializer,
						false); //this.options.insert_space_after_comma_in_array_initializer);
			}
			handleToken(this.tm.get(closingBraceIndex),
					this.options.insert_space_before_closing_brace_in_array_initializer
							&& !(endsWithComma && node.expressions().isEmpty()), false);
		}
		return true;
	}

	@Override
	public boolean visit(ParameterizedType node) {
		List<Type> typeArguments = node.typeArguments();
		boolean hasArguments = !typeArguments.isEmpty();
		handleTokenAfter(node.getType(), TokenNameLESS,
				this.options.insert_space_before_opening_angle_bracket_in_parameterized_type_reference,
				hasArguments && this.options.insert_space_after_opening_angle_bracket_in_parameterized_type_reference);
		if (hasArguments) {
			handleTokenAfter(typeArguments.get(typeArguments.size() - 1), TokenNameGREATER,
					this.options.insert_space_before_closing_angle_bracket_in_parameterized_type_reference, false);
			handleCommas(node.typeArguments(),
					this.options.insert_space_before_comma_in_parameterized_type_reference,
					this.options.insert_space_after_comma_in_parameterized_type_reference);
		}
		return true;
	}

	@Override
	public boolean visit(TypeParameter node) {
		List<Type> typeBounds = node.typeBounds();
		for (int i = 1; i < typeBounds.size(); i++) {
			handleTokenBefore(typeBounds.get(i), TokenNameAND,
					this.options.insert_space_before_and_in_type_parameter,
					this.options.insert_space_after_and_in_type_parameter);
		}
		return true;
	}

	@Override
	public boolean visit(WildcardType node) {
		handleToken(node, TokenNameQUESTION, this.options.insert_space_before_question_in_wilcard,
				this.options.insert_space_after_question_in_wilcard || node.getBound() != null);
		return true;
	}

	@Override
	public boolean visit(UnionType node) {
		List<Type> types = node.types();
		for (int i = 1; i < types.size(); i++)
			handleTokenBefore(types.get(i), TokenNameOR, this.options.insert_space_before_bitwise_operator,
					this.options.insert_space_after_bitwise_operator);
		return true;
	}

	@Override
	public boolean visit(Dimension node) {
		List<Annotation> annotations = node.annotations();
		if (!annotations.isEmpty())
			handleToken(annotations.get(0), TokenNameAT, true, false);
		return true;
	}

	@Override
	public boolean visit(TypeMethodReference node) {
		handleTypeArguments(node.typeArguments());
		return true;
	}

	@Override
	public boolean visit(ExpressionMethodReference node) {
		handleTypeArguments(node.typeArguments());
		return true;
	}

	@Override
	public boolean visit(SuperMethodReference node) {
		handleTypeArguments(node.typeArguments());
		return true;
	}

	@Override
	public boolean visit(CreationReference node) {
		handleTypeArguments(node.typeArguments());
		return true;
	}

//{ObjectTeams: more visits:
	@Override
	public boolean visit(RoleTypeDeclaration node) {
		return visit((TypeDeclaration)node);
	}
	@Override
	public boolean visit(BaseCallMessageSend node) {
		// see MethodInvocation (sauf type arguments).
		handleInvocation(node, node.getName());
		handleCommas(node.getArguments(), this.options.insert_space_before_comma_in_method_invocation_arguments,
				this.options.insert_space_after_comma_in_method_invocation_arguments);
		return true;
	}
	@Override
	public boolean visit(CalloutMappingDeclaration node) {
		handleTokenAfter(node.getRoleMappingElement(), node.isCalloutOverride() ? TokenNameCALLOUT_OVERRIDE : TokenNameBINDOUT, true, true);
		if (node.hasParameterMapping())
			handleTokenAfter(node.getBaseMappingElement(), TokenNamewith, true, true);
		return true;
	}
	@Override
	public boolean visit(CallinMappingDeclaration node) {
		handleTokenAfter(node.getRoleMappingElement(), TokenNameBINDIN, true, true);
		List<ASTNode> baseMappingElements = node.getBaseMappingElements();
		handleCommas(baseMappingElements, false, true);
		ASTNode lastBase = baseMappingElements.get(baseMappingElements.size()-1);
		GuardPredicateDeclaration predicate = node.getGuardPredicate();
		if (predicate != null)
			handleTokenAfter(lastBase, predicate.isBase() ? TokenNamebase : TokenNamewhen, true, true);
		if (node.hasParameterMapping())
			handleTokenAfter(lastBase, TokenNamewith, true, true);
		return true;
	}
	@Override
	public boolean visit(MethodSpec node) {
		handleCommas(node.parameters(), this.options.insert_space_before_comma_in_method_declaration_parameters,
				this.options.insert_space_after_comma_in_method_declaration_parameters);
		return true;
	}
	@Override
	public boolean visit(ParameterMapping node) {
		if (node.isBindIN())
			handleTokenAfter(node.getIdentifier(), TokenNameBINDIN, true, true);
		else
			handleTokenBefore(node.getIdentifier(), TokenNameBINDOUT, true, true);
		return true;
	}
	@Override
	public boolean visit(GuardPredicateDeclaration node) {
		handleToken(node, TokenNamewhen, true, true);
		return true;
	}
	@Override
	public boolean visit(WithinStatement node) { // like while
		handleToken(node, TokenNameLPAREN, this.options.insert_space_before_opening_paren_in_while,
				this.options.insert_space_after_opening_paren_in_while);
		handleTokenBefore(node.getBody(), TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_while,
				false);
		return true;
	}
// SH}

	private void handleTypeArguments(List<Type> typeArguments) {
		if (typeArguments.isEmpty())
			return;
		handleTokenBefore(typeArguments.get(0), TokenNameLESS,
				this.options.insert_space_before_opening_angle_bracket_in_type_arguments,
				this.options.insert_space_after_opening_angle_bracket_in_type_arguments);
		handleTokenAfter(typeArguments.get(typeArguments.size() - 1), TokenNameGREATER,
				this.options.insert_space_before_closing_angle_bracket_in_type_arguments,
				this.options.insert_space_after_closing_angle_bracket_in_type_arguments);
		handleCommas(typeArguments, this.options.insert_space_before_comma_in_type_arguments,
				this.options.insert_space_after_comma_in_type_arguments);
	}

	@Override
	public boolean visit(InstanceofExpression node) {
		handleTokenAfter(node.getLeftOperand(), TokenNameinstanceof, true, true);
		return true;
	}

	@Override
	public boolean visit(ModuleDeclaration node) {
		handleToken(node.getName(), TokenNameLBRACE,
				this.options.insert_space_before_opening_brace_in_type_declaration, false);
		return true;
	}

	@Override
	public boolean visit(ExportsDirective node) {
		handleModuleStatementCommas(node.modules());
		return true;
	}
	
	@Override
	public boolean visit(OpensDirective node) {
		handleModuleStatementCommas(node.modules());
		return true;
	}

	@Override
	public boolean visit(ProvidesDirective node) {
		handleModuleStatementCommas(node.implementations());
		return true;
	}

	private void handleModuleStatementCommas(List<Name> names) {
		// using settings for fields for now, add new settings if necessary
		handleCommas(names, this.options.insert_space_before_comma_in_multiple_field_declarations,
				this.options.insert_space_after_comma_in_multiple_field_declarations);
	}

	private void handleCommas(List<? extends ASTNode> nodes, boolean spaceBefore, boolean spaceAfter) {
		if (spaceBefore || spaceAfter) {
			for (int i = 1; i < nodes.size(); i++) {
				handleTokenBefore(nodes.get(i), TokenNameCOMMA, spaceBefore, spaceAfter);
			}
		}
	}

	private void handleToken(ASTNode node, int tokenType, boolean spaceBefore, boolean spaceAfter) {
		if (spaceBefore || spaceAfter) {
			Token token = this.tm.get(this.tm.findIndex(node.getStartPosition(), tokenType, true));
			// ^not the same as "firstTokenIn(node, tokenType)" - do not assert the token is inside the node
			handleToken(token, spaceBefore, spaceAfter);
		}
	}

	private void handleTokenBefore(ASTNode node, int tokenType, boolean spaceBefore, boolean spaceAfter) {
		if (spaceBefore || spaceAfter) {
			Token token = this.tm.firstTokenBefore(node, tokenType);
			handleToken(token, spaceBefore, spaceAfter);
		}
	}

	private void handleTokenAfter(ASTNode node, int tokenType, boolean spaceBefore, boolean spaceAfter) {
		if (tokenType == TokenNameGREATER) {
			// there could be ">>" or ">>>" instead, get rid of them
			int index = this.tm.lastIndexIn(node, -1);
			for (int i = index; i < index + 2; i++) {
				Token token = this.tm.get(i);
				if (token.tokenType == TokenNameRIGHT_SHIFT || token.tokenType == TokenNameUNSIGNED_RIGHT_SHIFT) {
					this.tm.remove(i);
					for (int j = 0; j < (token.tokenType == TokenNameRIGHT_SHIFT ? 2 : 3); j++) {
						this.tm.insert(i + j, new Token(token.originalStart + j, token.originalStart + j,
								TokenNameGREATER));
					}
				}
			}
		}
		if (spaceBefore || spaceAfter) {
			Token token = this.tm.firstTokenAfter(node, tokenType);
			handleToken(token, spaceBefore, spaceAfter);
		}
	}

	private void handleToken(Token token, boolean spaceBefore, boolean spaceAfter) {
		if (spaceBefore)
			token.spaceBefore();
		if (spaceAfter)
			token.spaceAfter();
	}

	private boolean handleEmptyParens(ASTNode nodeBeforeParens, boolean insertSpace) {
		int openingIndex = this.tm.findIndex(nodeBeforeParens.getStartPosition(), TokenNameLPAREN, true);
		if (this.tm.get(openingIndex + 1).tokenType == TokenNameRPAREN) {
			if (insertSpace)
				this.tm.get(openingIndex).spaceAfter();
			return true;
		}
		return false;
	}

	private boolean handleEmptyBrackets(ASTNode nodeContainingBrackets, boolean insertSpace) {
		int openingIndex = this.tm.firstIndexIn(nodeContainingBrackets, TokenNameLBRACKET);
		if (this.tm.get(openingIndex + 1).tokenType == TokenNameRBRACKET) {
			if (insertSpace)
				this.tm.get(openingIndex).spaceAfter();
			return true;
		}
		return false;
	}

	private void handleSemicolon(ASTNode node) {
		if (this.options.insert_space_before_semicolon) {
			Token lastToken = this.tm.lastTokenIn(node, -1);
			if (lastToken.tokenType == TokenNameSEMICOLON)
				lastToken.spaceBefore();
		}
	}

	private void handleSemicolon(List<ASTNode> nodes) {
		if (this.options.insert_space_before_semicolon) {
			for (ASTNode node : nodes)
				handleSemicolon(node);
		}
	}

	private void handleLoopBody(Statement loopBody) {
		/* space before body statement may be needed if it will stay on the same line */
		int firstTokenIndex = this.tm.firstIndexIn(loopBody, -1);
		if (!(loopBody instanceof Block) && !(loopBody instanceof EmptyStatement)
				&& !this.tm.get(firstTokenIndex - 1).isComment()) {
			this.tm.get(firstTokenIndex).spaceBefore();
		}
	}

	public void finishUp() {
		this.tm.traverse(0, new TokenTraverser() {
			boolean isPreviousJIDP = false;

			@Override
			protected boolean token(Token token, int index) {
				// put space between consecutive keywords, numbers or identifiers
				char c = SpacePreparator.this.tm.charAt(token.originalStart);
				boolean isJIDP = ScannerHelper.isJavaIdentifierPart(c);
				if ((isJIDP || c == '@') && this.isPreviousJIDP)
					getPrevious().spaceAfter();
				this.isPreviousJIDP = isJIDP;

				switch (token.tokenType) {
					case TokenNamePLUS:
						if (getNext().tokenType == TokenNamePLUS || getNext().tokenType == TokenNamePLUS_PLUS)
							token.spaceAfter();
						break;
					case TokenNameMINUS:
						if (getNext().tokenType == TokenNameMINUS || getNext().tokenType == TokenNameMINUS_MINUS)
							token.spaceAfter();
						break;
				}
				return true;
			}
		});
	}
}
