gt: 				|| parent instanceof ArrayInitializer;
context: /*******************************************************************************
   * Copyright (c) 2014, 2018 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/
   *
   * 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
   *******************************************************************************/
  package org.eclipse.jdt.internal.formatter;
  
  import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.*;
  
  import java.util.ArrayList;
  import java.util.List;
  
  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.Block;
  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.IfStatement;
  import org.eclipse.jdt.core.dom.ImportDeclaration;
  import org.eclipse.jdt.core.dom.InfixExpression;
  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.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.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.ProvidesDirective;
  import org.eclipse.jdt.core.dom.PrefixExpression.Operator;
  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.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.internal.compiler.parser.ScannerHelper;
  
  public class SpacePreparator extends ASTVisitor {
  	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(SwitchCase node) {
  		if (node.isDefault()) {
  			handleToken(node, TokenNameCOLON, this.options.insert_space_before_colon_in_default, false);
  		} else {
  			handleToken(node, TokenNamecase, false, true);
  			handleToken(node.getExpression(), TokenNameCOLON, this.options.insert_space_before_colon_in_case, false);
  		}
  		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)
  