/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.core.dom;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Abstract superclass of all Abstract Syntax Tree (AST) node types.
 * <p>
 * An AST node represents a Java source code construct, such
 * as a name, type, expression, statement, or declaration.
 * </p>
 * <p>
 * Each AST node belongs to a unique AST instance, called the owning AST.
 * The children of an AST node always have the same owner as their parent node.
 * If a node from one AST is to be added to a different AST, the subtree must
 * be cloned first to ensure that the added nodes have the correct owning AST.
 * </p>
 * <p>
 * When an AST node is part of an AST, it has a unique parent node.
 * Clients can navigate upwards, from child to parent, as well as downwards,
 * from parent to child. Newly created nodes are unparented. When an 
 * unparented node is set as a child of a node (using a 
 * <code>set<it>CHILD</it></code> method), its parent link is set automatically
 * and the parent link of the former child is set to <code>null</code>.
 * For nodes with properties that include a list of children (for example,
 * <code>Block</code> whose <code>statements</code> property is a list
 * of statements), adding or removing an element to/for the list property
 * automatically updates the parent links. These lists support the 
 * <code>List.set</code> method; however, the constraint that the same
 * node cannot appear more than once means that this method cannot be used
 * to swap elements without first removing the node.
 * </p>
 * <p>
 * ASTs must not contain cycles. All operations that could create a cycle
 * detect this possibility and fail.
 * </p>
 * <p>
 * ASTs do not contain "holes" (missing subtrees). If a node is required to
 * have a certain property, a syntactically plausible initial value is
 * always supplied. 
 * </p>
 * <p>
 * The hierarchy of AST node types has some convenient groupings marked
 * by abstract superclasses:
 * <ul>
 * <li>expressions - <code>Expression</code></li>
 * <li>names - <code>Name</code> (a sub-kind of expression)</li>
 * <li>statements - <code>Statement</code></li>
 * <li>types - <code>Type</code></li>
 * <li>type body declarations - <code>BodyDeclaration</code></li>
 * </ul>
 * </p>
 * <p>
 * Abstract syntax trees may be hand constructed by clients, using the
 * <code>new<it>TYPE</it></code> factory methods (see <code>AST</code>) to
 * create new nodes, and the various <code>set<it>CHILD</it></code> methods
 * to connect them together.
 * </p>
 * <p>
 * The class {@link ASTParser} parses a string
 * containing a Java source code and returns an abstract syntax tree
 * for it. The resulting nodes carry source ranges relating the node back to
 * the original source characters. The source range covers the construct
 * as a whole.
 * </p>
 * <p>
 * Each AST node carries bit flags, which may convey additional information about
 * the node. For instance, the parser uses a flag to indicate a syntax error.
 * Newly created nodes have no flags set.
 * </p>
 * <p>
 * Each AST node is capable of carrying an open-ended collection of
 * client-defined properties. Newly created nodes have none. 
 * <code>getProperty</code> and <code>setProperty</code> are used to access
 * these properties.
 * </p>
 * <p>
 * AST nodes are thread-safe for readers provided there are no active writers.
 * If one thread is modifying an AST, including creating new nodes or cloning
 * existing ones, it is <b>not</b> safe for another thread to read, visit,
 * write, create, or clone <em>any</em> of the nodes on the same AST.
 * When synchronization is required, consider using the common AST
 * object that owns the node; that is, use  
 * <code>synchronize (node.getAST()) {...}</code>.
 * </p>
 * <p>
 * ASTs also support the visitor pattern; see the class <code>ASTVisitor</code>
 * for details.
 * </p>
 * <p>
 * Compilation units created by <code>ASTParser</code> from a
 * source document can be serialized after arbitrary modifications
 * with minimal loss of original formatting. See 
 * {@link CompilationUnit#recordModifications()} for details.
 * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
 * an alternative way to describe and serialize changes to a
 * read-only AST.
 * </p>
 * 
 * @see ASTParser
 * @see ASTVisitor
 * @since 2.0
 */
public abstract class ASTNode {
	/*
	 * INSTRUCTIONS FOR ADDING NEW CONCRETE AST NODE TYPES
	 * 
	 * There are several things that need to be changed when a
	 * new concrete AST node type (call it "FooBar"):
	 * 
	 * 1. Create the FooBar AST node type class.
	 * The most effective way to do this is to copy a similar
	 * existing concrete node class to get a template that
     * includes all the framework methods that must be implemented.
	 * 
	 * 2. Add node type constant ASTNode.FOO_BAR.
	 * Node constants are numbered consecutively. Add the
	 * constant after the existing ones.
	 * 
	 * 3. Add entry to ASTNode.nodeClassForType(int).
	 * 
	 * 4. Add AST.newFooBar() factory method.
	 * 
	 * 5. Add ASTVisitor.visit(FooBar) and endVisit(FooBar) methods.
	 * 
	 * 6. Add ASTMatcher.match(FooBar,Object) method.
	 * 
	 * 7. Ensure that SimpleName.isDeclaration() covers FooBar
	 * nodes if required.
	 * 
	 * 8. Add NaiveASTFlattener.visit(FooBar) method to illustrate
	 * how these nodes should be serialized.
	 * 
	 * 9. Update the AST test suites.
	 * 
	 * The next steps are to update AST.parse* to start generating
	 * the new type of nodes, and ASTRewrite to serialize them back out.
	 */
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>AnonymousClassDeclaration</code>.
	 * @see AnonymousClassDeclaration
	 */
	public static final int ANONYMOUS_CLASS_DECLARATION = 1;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ArrayAccess</code>.
	 * @see ArrayAccess
	 */
	public static final int ARRAY_ACCESS = 2;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ArrayCreation</code>.
	 * @see ArrayCreation
	 */
	public static final int ARRAY_CREATION = 3;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ArrayInitializer</code>.
	 * @see ArrayInitializer
	 */
	public static final int ARRAY_INITIALIZER = 4;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ArrayType</code>.
	 * @see ArrayType
	 */
	public static final int ARRAY_TYPE = 5;

	/**
	 * Node type constant indicating a node of type 
	 * <code>AssertStatement</code>.
	 * @see AssertStatement
	 */
	public static final int ASSERT_STATEMENT = 6;

	/**
	 * Node type constant indicating a node of type 
	 * <code>Assignment</code>.
	 * @see Assignment
	 */
	public static final int ASSIGNMENT = 7;

	/**
	 * Node type constant indicating a node of type 
	 * <code>Block</code>.
	 * @see Block
	 */
	public static final int BLOCK = 8;

	/**
	 * Node type constant indicating a node of type 
	 * <code>BooleanLiteral</code>.
	 * @see BooleanLiteral
	 */
	public static final int BOOLEAN_LITERAL = 9;

	/**
	 * Node type constant indicating a node of type 
	 * <code>BreakStatement</code>.
	 * @see BreakStatement
	 */
	public static final int BREAK_STATEMENT = 10;

	/**
	 * Node type constant indicating a node of type 
	 * <code>CastExpression</code>.
	 * @see CastExpression
	 */
	public static final int CAST_EXPRESSION = 11;

	/**
	 * Node type constant indicating a node of type 
	 * <code>CatchClause</code>.
	 * @see CatchClause
	 */
	public static final int CATCH_CLAUSE = 12;

	/**
	 * Node type constant indicating a node of type 
	 * <code>CharacterLiteral</code>.
	 * @see CharacterLiteral
	 */
	public static final int CHARACTER_LITERAL = 13;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ClassInstanceCreation</code>.
	 * @see ClassInstanceCreation
	 */
	public static final int CLASS_INSTANCE_CREATION = 14;

	/**
	 * Node type constant indicating a node of type 
	 * <code>CompilationUnit</code>.
	 * @see CompilationUnit
	 */
	public static final int COMPILATION_UNIT = 15;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ConditionalExpression</code>.
	 * @see ConditionalExpression
	 */
	public static final int CONDITIONAL_EXPRESSION = 16;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ConstructorInvocation</code>.
	 * @see ConstructorInvocation
	 */
	public static final int CONSTRUCTOR_INVOCATION = 17;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ContinueStatement</code>.
	 * @see ContinueStatement
	 */
	public static final int CONTINUE_STATEMENT = 18;

	/**
	 * Node type constant indicating a node of type 
	 * <code>DoStatement</code>.
	 * @see DoStatement
	 */
	public static final int DO_STATEMENT = 19;

	/**
	 * Node type constant indicating a node of type 
	 * <code>EmptyStatement</code>.
	 * @see EmptyStatement
	 */
	public static final int EMPTY_STATEMENT = 20;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ExpressionStatement</code>.
	 * @see ExpressionStatement
	 */
	public static final int EXPRESSION_STATEMENT = 21;

	/**
	 * Node type constant indicating a node of type 
	 * <code>FieldAccess</code>.
	 * @see FieldAccess
	 */
	public static final int FIELD_ACCESS = 22;

	/**
	 * Node type constant indicating a node of type 
	 * <code>FieldDeclaration</code>.
	 * @see FieldDeclaration
	 */
	public static final int FIELD_DECLARATION = 23;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ForStatement</code>.
	 * @see ForStatement
	 */
	public static final int FOR_STATEMENT = 24;

	/**
	 * Node type constant indicating a node of type 
	 * <code>IfStatement</code>.
	 * @see IfStatement
	 */
	public static final int IF_STATEMENT = 25;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ImportDeclaration</code>.
	 * @see ImportDeclaration
	 */
	public static final int IMPORT_DECLARATION = 26;

	/**
	 * Node type constant indicating a node of type 
	 * <code>InfixExpression</code>.
	 * @see InfixExpression
	 */
	public static final int INFIX_EXPRESSION = 27;

	/**
	 * Node type constant indicating a node of type 
	 * <code>Initializer</code>.
	 * @see Initializer
	 */
	public static final int INITIALIZER = 28;

	/**
	 * Node type constant indicating a node of type 
	 * <code>Javadoc</code>.
	 * @see Javadoc
	 */
	public static final int JAVADOC = 29;

	/**
	 * Node type constant indicating a node of type 
	 * <code>LabeledStatement</code>.
	 * @see LabeledStatement
	 */
	public static final int LABELED_STATEMENT = 30;

	/**
	 * Node type constant indicating a node of type 
	 * <code>MethodDeclaration</code>.
	 * @see MethodDeclaration
	 */
	public static final int METHOD_DECLARATION = 31;

	/**
	 * Node type constant indicating a node of type 
	 * <code>MethodInvocation</code>.
	 * @see MethodInvocation
	 */
	public static final int METHOD_INVOCATION = 32;

	/**
	 * Node type constant indicating a node of type 
	 * <code>NullLiteral</code>.
	 * @see NullLiteral
	 */
	public static final int NULL_LITERAL = 33;

	/**
	 * Node type constant indicating a node of type 
	 * <code>NumberLiteral</code>.
	 * @see NumberLiteral
	 */
	public static final int NUMBER_LITERAL = 34;

	/**
	 * Node type constant indicating a node of type 
	 * <code>PackageDeclaration</code>.
	 * @see PackageDeclaration
	 */
	public static final int PACKAGE_DECLARATION = 35;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ParenthesizedExpression</code>.
	 * @see ParenthesizedExpression
	 */
	public static final int PARENTHESIZED_EXPRESSION = 36;

	/**
	 * Node type constant indicating a node of type 
	 * <code>PostfixExpression</code>.
	 * @see PostfixExpression
	 */
	public static final int POSTFIX_EXPRESSION = 37;

	/**
	 * Node type constant indicating a node of type 
	 * <code>PrefixExpression</code>.
	 * @see PrefixExpression
	 */
	public static final int PREFIX_EXPRESSION = 38;

	/**
	 * Node type constant indicating a node of type 
	 * <code>PrimitiveType</code>.
	 * @see PrimitiveType
	 */
	public static final int PRIMITIVE_TYPE = 39;

	/**
	 * Node type constant indicating a node of type 
	 * <code>QualifiedName</code>.
	 * @see QualifiedName
	 */
	public static final int QUALIFIED_NAME = 40;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ReturnStatement</code>.
	 * @see ReturnStatement
	 */
	public static final int RETURN_STATEMENT = 41;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SimpleName</code>.
	 * @see SimpleName
	 */
	public static final int SIMPLE_NAME = 42;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SimpleType</code>.
	 * @see SimpleType
	 */
	public static final int SIMPLE_TYPE = 43;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SingleVariableDeclaration</code>.
	 * @see SingleVariableDeclaration
	 */
	public static final int SINGLE_VARIABLE_DECLARATION = 44;

	/**
	 * Node type constant indicating a node of type 
	 * <code>StringLiteral</code>.
	 * @see StringLiteral
	 */
	public static final int STRING_LITERAL = 45;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SuperConstructorInvocation</code>.
	 * @see SuperConstructorInvocation
	 */
	public static final int SUPER_CONSTRUCTOR_INVOCATION = 46;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SuperFieldAccess</code>.
	 * @see SuperFieldAccess
	 */
	public static final int SUPER_FIELD_ACCESS = 47;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SuperMethodInvocation</code>.
	 * @see SuperMethodInvocation
	 */
	public static final int SUPER_METHOD_INVOCATION = 48;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SwitchCase</code>.
	 * @see SwitchCase
	 */
	public static final int SWITCH_CASE = 49;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SwitchStatement</code>.
	 * @see SwitchStatement
	 */
	public static final int SWITCH_STATEMENT = 50;

	/**
	 * Node type constant indicating a node of type 
	 * <code>SynchronizedStatement</code>.
	 * @see SynchronizedStatement
	 */
	public static final int SYNCHRONIZED_STATEMENT = 51;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ThisExpression</code>.
	 * @see ThisExpression
	 */
	public static final int THIS_EXPRESSION = 52;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ThrowStatement</code>.
	 * @see ThrowStatement
	 */
	public static final int THROW_STATEMENT = 53;

	/**
	 * Node type constant indicating a node of type 
	 * <code>TryStatement</code>.
	 * @see TryStatement
	 */
	public static final int TRY_STATEMENT = 54;

	/**
	 * Node type constant indicating a node of type 
	 * <code>TypeDeclaration</code>.
	 * @see TypeDeclaration
	 */
	public static final int TYPE_DECLARATION = 55;

	/**
	 * Node type constant indicating a node of type 
	 * <code>TypeDeclarationStatement</code>.
	 * @see TypeDeclarationStatement
	 */
	public static final int TYPE_DECLARATION_STATEMENT = 56;

	/**
	 * Node type constant indicating a node of type 
	 * <code>TypeLiteral</code>.
	 * @see TypeLiteral
	 */
	public static final int TYPE_LITERAL = 57;

	/**
	 * Node type constant indicating a node of type 
	 * <code>VariableDeclarationExpression</code>.
	 * @see VariableDeclarationExpression
	 */
	public static final int VARIABLE_DECLARATION_EXPRESSION = 58;

	/**
	 * Node type constant indicating a node of type 
	 * <code>VariableDeclarationFragment</code>.
	 * @see VariableDeclarationFragment
	 */
	public static final int VARIABLE_DECLARATION_FRAGMENT = 59;

	/**
	 * Node type constant indicating a node of type 
	 * <code>VariableDeclarationStatement</code>.
	 * @see VariableDeclarationStatement
	 */
	public static final int VARIABLE_DECLARATION_STATEMENT = 60;

	/**
	 * Node type constant indicating a node of type 
	 * <code>WhileStatement</code>.
	 * @see WhileStatement
	 */
	public static final int WHILE_STATEMENT = 61;

	/**
	 * Node type constant indicating a node of type 
	 * <code>InstanceofExpression</code>.
	 * @see InstanceofExpression
	 */
	public static final int INSTANCEOF_EXPRESSION = 62;

	/**
	 * Node type constant indicating a node of type 
	 * <code>LineComment</code>.
	 * @see LineComment
	 * @since 3.0
	 */
	public static final int LINE_COMMENT = 63;

	/**
	 * Node type constant indicating a node of type 
	 * <code>BlockComment</code>.
	 * @see BlockComment
	 * @since 3.0
	 */
	public static final int BLOCK_COMMENT = 64;

	/**
	 * Node type constant indicating a node of type 
	 * <code>TagElement</code>.
	 * @see TagElement
	 * @since 3.0
	 */
	public static final int TAG_ELEMENT = 65;

	/**
	 * Node type constant indicating a node of type 
	 * <code>TextElement</code>.
	 * @see TextElement
	 * @since 3.0
	 */
	public static final int TEXT_ELEMENT = 66;

	/**
	 * Node type constant indicating a node of type 
	 * <code>MemberRef</code>.
	 * @see MemberRef
	 * @since 3.0
	 */
	public static final int MEMBER_REF = 67;

	/**
	 * Node type constant indicating a node of type 
	 * <code>MethodRef</code>.
	 * @see MethodRef
	 * @since 3.0
	 */
	public static final int METHOD_REF = 68;

	/**
	 * Node type constant indicating a node of type 
	 * <code>MethodRefParameter</code>.
	 * @see MethodRefParameter
	 * @since 3.0
	 */
	public static final int METHOD_REF_PARAMETER = 69;

	/**
	 * Node type constant indicating a node of type 
	 * <code>EnhancedForStatement</code>.
	 * @see EnhancedForStatement
	 * @since 3.1
	 */
	public static final int ENHANCED_FOR_STATEMENT = 70;

	/**
	 * Node type constant indicating a node of type 
	 * <code>EnumDeclaration</code>.
	 * @see EnumDeclaration
	 * @since 3.1
	 */
	public static final int ENUM_DECLARATION = 71;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>EnumConstantDeclaration</code>.
	 * @see EnumConstantDeclaration
	 * @since 3.1
	 */
	public static final int ENUM_CONSTANT_DECLARATION = 72;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>TypeParameter</code>.
	 * @see TypeParameter
	 * @since 3.1
	 */
	public static final int TYPE_PARAMETER = 73;

	/**
	 * Node type constant indicating a node of type 
	 * <code>ParameterizedType</code>.
	 * @see ParameterizedType
	 * @since 3.1
	 */
	public static final int PARAMETERIZED_TYPE = 74;

	/**
	 * Node type constant indicating a node of type 
	 * <code>QualifiedType</code>.
	 * @see QualifiedType
	 * @since 3.1
	 */
	public static final int QUALIFIED_TYPE = 75;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>WildcardType</code>.
	 * @see WildcardType
	 * @since 3.1
	 */
	public static final int WILDCARD_TYPE = 76;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>NormalAnnotation</code>.
	 * @see NormalAnnotation
	 * @since 3.1
	 */
	public static final int NORMAL_ANNOTATION = 77;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>MarkerAnnotation</code>.
	 * @see MarkerAnnotation
	 * @since 3.1
	 */
	public static final int MARKER_ANNOTATION = 78;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>SingleMemberAnnotation</code>.
	 * @see SingleMemberAnnotation
	 * @since 3.1
	 */
	public static final int SINGLE_MEMBER_ANNOTATION = 79;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>MemberValuePair</code>.
	 * @see MemberValuePair
	 * @since 3.1
	 */
	public static final int MEMBER_VALUE_PAIR = 80;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>AnnotationTypeDeclaration</code>.
	 * @see AnnotationTypeDeclaration
	 * @since 3.1
	 */
	public static final int ANNOTATION_TYPE_DECLARATION = 81;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>AnnotationTypeMemberDeclaration</code>.
	 * @see AnnotationTypeMemberDeclaration
	 * @since 3.1
	 */
	public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
	
	/**
	 * Node type constant indicating a node of type 
	 * <code>Modifier</code>.
	 * @see Modifier
	 * @since 3.1
	 */
	public static final int MODIFIER = 83;
	
	/**
	 * Returns the node class for the corresponding node type.
	 * 
	 * @param nodeType AST node type
	 * @return the corresponding <code>ASTNode</code> subclass
	 * @exception IllegalArgumentException if <code>nodeType</code> is 
	 * not a legal AST node type
	 * @see #getNodeType()
	 * @since 3.0
	 */
	public static Class nodeClassForType(int nodeType) {
		switch (nodeType) {
			case ANNOTATION_TYPE_DECLARATION :
				return AnnotationTypeDeclaration.class;
			case ANNOTATION_TYPE_MEMBER_DECLARATION :
				return AnnotationTypeMemberDeclaration.class;
			case ANONYMOUS_CLASS_DECLARATION :
				return AnonymousClassDeclaration.class;
			case ARRAY_ACCESS :
				return ArrayAccess.class;
			case ARRAY_CREATION :
				return ArrayCreation.class;
			case ARRAY_INITIALIZER :
				return ArrayInitializer.class;
			case ARRAY_TYPE :
				return ArrayType.class;
			case ASSERT_STATEMENT :
				return AssertStatement.class;
			case ASSIGNMENT :
				return Assignment.class;
			case BLOCK :
				return Block.class;
			case BLOCK_COMMENT :
				return BlockComment.class;
			case BOOLEAN_LITERAL :
				return BooleanLiteral.class;
			case BREAK_STATEMENT :
				return BreakStatement.class;
			case CAST_EXPRESSION :
				return CastExpression.class;
			case CATCH_CLAUSE :
				return CatchClause.class;
			case CHARACTER_LITERAL :
				return CharacterLiteral.class;
			case CLASS_INSTANCE_CREATION :
				return ClassInstanceCreation.class;
			case COMPILATION_UNIT :
				return CompilationUnit.class;
			case CONDITIONAL_EXPRESSION :
				return ConditionalExpression.class;
			case CONSTRUCTOR_INVOCATION :
				return ConstructorInvocation.class;
			case CONTINUE_STATEMENT :
				return ContinueStatement.class;
			case DO_STATEMENT :
				return DoStatement.class;
			case EMPTY_STATEMENT :
				return EmptyStatement.class;
			case ENHANCED_FOR_STATEMENT :
				return EnhancedForStatement.class;
			case ENUM_CONSTANT_DECLARATION :
				return EnumConstantDeclaration.class;
			case ENUM_DECLARATION :
				return EnumDeclaration.class;
			case EXPRESSION_STATEMENT :
				return ExpressionStatement.class;
			case FIELD_ACCESS :
				return FieldAccess.class;
			case FIELD_DECLARATION :
				return FieldDeclaration.class;
			case FOR_STATEMENT :
				return ForStatement.class;
			case IF_STATEMENT :
				return IfStatement.class;
			case IMPORT_DECLARATION :
				return ImportDeclaration.class;
			case INFIX_EXPRESSION :
				return InfixExpression.class;
			case INITIALIZER :
				return Initializer.class;
			case INSTANCEOF_EXPRESSION :
				return InstanceofExpression.class;
			case JAVADOC :
				return Javadoc.class;
			case LABELED_STATEMENT :
				return LabeledStatement.class;
			case LINE_COMMENT :
				return LineComment.class;
			case MARKER_ANNOTATION :
				return MarkerAnnotation.class;
			case MEMBER_REF :
				return MemberRef.class;
			case MEMBER_VALUE_PAIR :
				return MemberValuePair.class;
			case METHOD_DECLARATION :
				return MethodDeclaration.class;
			case METHOD_INVOCATION :
				return MethodInvocation.class;
			case METHOD_REF :
				return MethodRef.class;
			case METHOD_REF_PARAMETER :
				return MethodRefParameter.class;
			case MODIFIER :
				return Modifier.class;
			case NORMAL_ANNOTATION :
				return NormalAnnotation.class;
			case NULL_LITERAL :
				return NullLiteral.class;
			case NUMBER_LITERAL :
				return NumberLiteral.class;
			case PACKAGE_DECLARATION :
				return PackageDeclaration.class;
			case PARAMETERIZED_TYPE :
				return ParameterizedType.class;
			case PARENTHESIZED_EXPRESSION :
				return ParenthesizedExpression.class;
			case POSTFIX_EXPRESSION :
				return PostfixExpression.class;
			case PREFIX_EXPRESSION :
				return PrefixExpression.class;
			case PRIMITIVE_TYPE :
				return PrimitiveType.class;
			case QUALIFIED_NAME :
				return QualifiedName.class;
			case QUALIFIED_TYPE :
				return QualifiedType.class;
			case RETURN_STATEMENT :
				return ReturnStatement.class;
			case SIMPLE_NAME :
				return SimpleName.class;
			case SIMPLE_TYPE :
				return SimpleType.class;
			case SINGLE_MEMBER_ANNOTATION :
				return SingleMemberAnnotation.class;
			case SINGLE_VARIABLE_DECLARATION :
				return SingleVariableDeclaration.class;
			case STRING_LITERAL :
				return StringLiteral.class;
			case SUPER_CONSTRUCTOR_INVOCATION :
				return SuperConstructorInvocation.class;
			case SUPER_FIELD_ACCESS :
				return SuperFieldAccess.class;
			case SUPER_METHOD_INVOCATION :
				return SuperMethodInvocation.class;
			case SWITCH_CASE:
				return SwitchCase.class;
			case SWITCH_STATEMENT :
				return SwitchStatement.class;
			case SYNCHRONIZED_STATEMENT :
				return SynchronizedStatement.class;
			case TAG_ELEMENT :
				return TagElement.class;
			case TEXT_ELEMENT :
				return TextElement.class;
			case THIS_EXPRESSION :
				return ThisExpression.class;
			case THROW_STATEMENT :
				return ThrowStatement.class;
			case TRY_STATEMENT :
				return TryStatement.class;
			case TYPE_DECLARATION :
				return TypeDeclaration.class;
			case TYPE_DECLARATION_STATEMENT :
				return TypeDeclarationStatement.class;
			case TYPE_LITERAL :
				return TypeLiteral.class;
			case TYPE_PARAMETER :
				return TypeParameter.class;
			case VARIABLE_DECLARATION_EXPRESSION :
				return VariableDeclarationExpression.class;
			case VARIABLE_DECLARATION_FRAGMENT :
				return VariableDeclarationFragment.class;
			case VARIABLE_DECLARATION_STATEMENT :
				return VariableDeclarationStatement.class;
			case WHILE_STATEMENT :
				return WhileStatement.class;
			case WILDCARD_TYPE :
				return WildcardType.class;
		}
		throw new IllegalArgumentException();
	}
	
	/**
	 * Owning AST.
     * <p>
     * N.B. This ia a private field, but declared as package-visible
     * for more efficient access from inner classes.
     * </p>
	 */
	final AST ast;
	
	/**
	 * Parent AST node, or <code>null</code> if this node is a root.
	 * Initially <code>null</code>.
	 */
	private ASTNode parent = null;
	
	/**
	 * An unmodifiable empty map (used to implement <code>properties()</code>).
	 */
	private static final Map UNMODIFIABLE_EMPTY_MAP
		= Collections.unmodifiableMap(new HashMap(1));
	
	/**
	 * Primary field used in representing node properties efficiently.
	 * If <code>null</code>, this node has no properties.
	 * If a <code>String</code>, this is the name of this node's sole property,
	 * and <code>property2</code> contains its value.
	 * If a <code>HashMap</code>, this is the table of property name-value
	 * mappings; <code>property2</code>, if non-null is its unmodifiable
	 * equivalent.
	 * Initially <code>null</code>.
	 * 
	 * @see #property2
	 */
	private Object property1 = null;
	
	/**
	 * Auxillary field used in representing node properties efficiently.
	 * 
	 * @see #property1
	 */
	private Object property2 = null;
	
	/**
	 * A character index into the original source string, 
	 * or <code>-1</code> if no source position information is available
	 * for this node; <code>-1</code> by default.
	 */
	private int startPosition = -1;

	/**
	 * A character length, or <code>0</code> if no source position
	 * information is recorded for this node; <code>0</code> by default.
	 */
	private int length = 0;
	
	/**
	 * Flag constant (bit mask, value 1) indicating that there is something
	 * not quite right with this AST node.
	 * <p>
	 * The standard parser (<code>ASTParser</code>) sets this
	 * flag on a node to indicate a syntax error detected in the vicinity.
	 * </p>
	 */
	public static final int MALFORMED = 1;

	/**
	 * Flag constant (bit mask, value 2) indicating that this is a node
	 * that was created by the parser (as opposed to one created by another
	 * party).
	 * <p>
	 * The standard parser (<code>ASTParser</code>) sets this
	 * flag on the nodes it creates.
	 * </p>
	 * @since 3.0
	 */
	public static final int ORIGINAL = 2;

	/**
	 * Flag constant (bit mask, value 4) indicating that this node
	 * is unmodifiable. When a node is marked unmodifiable, the
	 * following operations result in a runtime exception:
	 * <ul>
	 * <li>Change a simple property of this node.</li>
	 * <li>Add or remove a child node from this node.</li>
	 * <li>Parent (or reparent) this node.</li>
	 * </ul>
	 * <p>
	 * The standard parser (<code>ASTParser</code>) does not set
	 * this flag on the nodes it creates. However, clients may set
	 * this flag on a node to prevent further modification of the
	 * its structural properties.
	 * </p>
	 * @since 3.0
	 */
	public static final int PROTECT = 4;

	/**
	 * int containing the node type in the top 16 bits and
	 * flags in the bottom 16 bits; none set by default.
     * <p>
     * N.B. This is a private field, but declared as package-visible
     * for more efficient access from inner classes.
     * </p>
	 * 
	 * @see #MALFORMED
	 */
	int typeAndFlags = 0;
		
	/**
	 * Property of parent in which this node is a child, or <code>null</code>
	 * if this node is a root. Initially <code>null</code>.
	 * 
	 * @see #getLocationInParent
	 * @since 3.0
	 */
	private StructuralPropertyDescriptor location = null;
	
	/** Internal convenience constant indicating that there is definite risk of cycles.
	 * @since 3.0
	 */ 
	static final boolean CYCLE_RISK = true;
	
	/** Internal convenience constant indicating that there is no risk of cycles.
	 * @since 3.0
	 */ 
	static final boolean NO_CYCLE_RISK = false;
	
	/** Internal convenience constant indicating that a structural property is mandatory.
	 * @since 3.0
	 */ 
	static final boolean MANDATORY = true;
	
	/** Internal convenience constant indicating that a structural property is optional.
	 * @since 3.0
	 */ 
	static final boolean OPTIONAL = false;
	
	/**
	 * A specialized implementation of a list of ASTNodes. The
	 * implementation is based on an ArrayList.
	 */ 
	class NodeList extends AbstractList {
		
		/**
		 * The underlying list in which the nodes of this list are
		 * stored (element type: <code>ASTNode</code>).
		 * <p>
		 * Be stingy on storage - assume that list will be empty.
		 * </p>
		 * <p>
		 * This field declared default visibility (rather than private)
		 * so that accesses from <code>NodeList.Cursor</code> do not require
		 * a synthetic accessor method.
		 * </p>
		 */
		ArrayList store = new ArrayList(0);
		
		/**
		 * The property descriptor for this list.
		 */
		ChildListPropertyDescriptor propertyDescriptor;
		
		/**
		 * A cursor for iterating over the elements of the list.
		 * Does not lose its position if the list is changed during
		 * the iteration.
		 */
		class Cursor implements Iterator {
			/**
			 * The position of the cursor between elements. If the value
			 * is N, then the cursor sits between the element at positions
			 * N-1 and N. Initially just before the first element of the
			 * list.
			 */
			private int position = 0;
			
			/* (non-Javadoc)
			 * Method declared on <code>Iterator</code>.
			 */
			public boolean hasNext() {
				return this.position < NodeList.this.store.size();
			}
			
			/* (non-Javadoc)
			 * Method declared on <code>Iterator</code>.
			 */
			public Object next() {
				Object result = NodeList.this.store.get(this.position);
				this.position++;
				return result;
		    }
			
			/* (non-Javadoc)
			 * Method declared on <code>Iterator</code>.
			 */
			public void remove() {
				throw new UnsupportedOperationException();
			}
			
			/**
			 * Adjusts this cursor to accomodate an add/remove at the given
			 * index.
			 * 
			 * @param index the position at which the element was added
			 *    or removed
			 * @param delta +1 for add, and -1 for remove
			 */
			void update(int index, int delta) {
				if (this.position > index) {
					// the cursor has passed the added or removed element
					this.position += delta;
				}
			}
		}

		/**
		 * A list of currently active cursors (element type:
		 * <code>Cursor</code>), or <code>null</code> if there are no
		 * active cursors.
		 * <p>
		 * It is important for storage considerations to maintain the
		 * null-means-empty invariant; otherwise, every NodeList instance
		 * will waste a lot of space. A cursor is needed only for the duration
		 * of a visit to the child nodes. Under normal circumstances, only a 
		 * single cursor is needed; multiple cursors are only required if there
		 * are multiple visits going on at the same time.
		 * </p>
		 */
		private List cursors = null;

		/**
		 * Creates a new empty list of nodes owned by this node.
		 * This node will be the common parent of all nodes added to 
		 * this list.
		 * 
		 * @param property the property descriptor
		 * @since 3.0
		 */
		NodeList(ChildListPropertyDescriptor property) {
			super();
			this.propertyDescriptor = property;
		}
	
		/* (non-javadoc)
		 * @see java.util.AbstractCollection#size()
		 */
		public int size() {
			return this.store.size();
		}
	
		/* (non-javadoc)
		 * @see AbstractList#get(int)
		 */
		public Object get(int index) {
			return this.store.get(index);
		}
	
		/* (non-javadoc)
		 * @see List#set(int, java.lang.Object)
		 */
		public Object set(int index, Object element) {
		    if (element == null) {
		        throw new IllegalArgumentException();
		    }
			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
				// this node is protected => cannot gain or lose children
				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
			}
			// delink old child from parent, and link new child to parent
			ASTNode newChild = (ASTNode) element;
			ASTNode oldChild = (ASTNode) this.store.get(index);
			if (oldChild == newChild) {
				return oldChild;
			}
			if ((oldChild.typeAndFlags & PROTECT) != 0) {
				// old child is protected => cannot be unparented
				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
			}
			ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
			ASTNode.this.ast.preReplaceChildEvent(ASTNode.this, oldChild, newChild, this.propertyDescriptor);
			
			Object result = this.store.set(index, newChild);
			// n.b. setParent will call ast.modifying()
			oldChild.setParent(null, null);
			newChild.setParent(ASTNode.this, this.propertyDescriptor);
			ASTNode.this.ast.postReplaceChildEvent(ASTNode.this, oldChild, newChild, this.propertyDescriptor);
			return result;
		}
		
		/* (non-javadoc)
		 * @see List#add(int, java.lang.Object)
		 */
		public void add(int index, Object element) {
		    if (element == null) {
		        throw new IllegalArgumentException();
		    }
			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
				// this node is protected => cannot gain or lose children
				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
			}
			// link new child to parent
			ASTNode newChild = (ASTNode) element;
			ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
			ASTNode.this.ast.preAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
			
			
			this.store.add(index, element);
			updateCursors(index, +1);
			// n.b. setParent will call ast.modifying()
			newChild.setParent(ASTNode.this, this.propertyDescriptor);
			ASTNode.this.ast.postAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
		}
		
		/* (non-javadoc)
		 * @see List#remove(int)
		 */
		public Object remove(int index) {
			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
				// this node is protected => cannot gain or lose children
				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
			}
			// delink old child from parent
			ASTNode oldChild = (ASTNode) this.store.get(index);
			if ((oldChild.typeAndFlags & PROTECT) != 0) {
				// old child is protected => cannot be unparented
				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
			}
			
			ASTNode.this.ast.preRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
			// n.b. setParent will call ast.modifying()
			oldChild.setParent(null, null);
			Object result = this.store.remove(index);
			updateCursors(index, -1);
			ASTNode.this.ast.postRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
			return result;

		}
		
		/**
		 * Allocate a cursor to use for a visit. The client must call
		 * <code>releaseCursor</code> when done.
		 * <p>
		 * This method is internally synchronized on this NodeList.
		 * It is thread-safe to create a cursor.
		 * </p>
		 * 
		 * @return a new cursor positioned before the first element 
		 *    of the list
		 */
		Cursor newCursor() {
			synchronized (this) {
				// serialize cursor management on this NodeList
				if (this.cursors == null) {
					// convert null to empty list
					this.cursors = new ArrayList(1);
				}
				Cursor result = new Cursor();
				this.cursors.add(result);
				return result;
			}
		}
		
		/**
		 * Releases the given cursor at the end of a visit.
		 * <p>
		 * This method is internally synchronized on this NodeList.
		 * It is thread-safe to release a cursor.
		 * </p>
		 * 
		 * @param cursor the cursor
		 */
		void releaseCursor(Cursor cursor) {
			synchronized (this) {
				// serialize cursor management on this NodeList
				this.cursors.remove(cursor);
				if (this.cursors.isEmpty()) {
					// important: convert empty list back to null
					// otherwise the node will hang on to needless junk
					this.cursors = null;
				}
			}
		}

		/**
		 * Adjusts all cursors to accomodate an add/remove at the given
		 * index.
		 * <p>
		 * This method is only used when the list is being modified.
		 * The AST is not thread-safe if any of the clients are modifying it.
		 * </p>
		 * 
		 * @param index the position at which the element was added
		 *    or removed
		 * @param delta +1 for add, and -1 for remove
		 */
		private void updateCursors(int index, int delta) {
			if (this.cursors == null) {
				// there are no cursors to worry about
				return;
			}
			for (Iterator it = this.cursors.iterator(); it.hasNext(); ) {
				Cursor c = (Cursor) it.next();
				c.update(index, delta);
			}
		}
		
		/**
		 * Returns an estimate of the memory footprint of this node list 
		 * instance in bytes.
	     * <ul>
	     * <li>1 object header for the NodeList instance</li>
	     * <li>5 4-byte fields of the NodeList instance</li>
	     * <li>0 for cursors since null unless walk in progress</li>
	     * <li>1 object header for the ArrayList instance</li>
	     * <li>2 4-byte fields of the ArrayList instance</li>
	     * <li>1 object header for an Object[] instance</li>
	     * <li>4 bytes in array for each element</li>
	     * </ul>
	 	 * 
		 * @return the size of this node list in bytes
		 */
		int memSize() {
			int result = HEADERS + 5 * 4;
			result += HEADERS + 2 * 4;
			result += HEADERS + 4 * size();
			return result;
		}

		/**
		 * Returns an estimate of the memory footprint in bytes of this node
		 * list and all its subtrees.
		 * 
		 * @return the size of this list of subtrees in bytes
		 */
		int listSize() {
			int result = memSize();
			for (Iterator it = iterator(); it.hasNext(); ) {
				ASTNode child = (ASTNode) it.next();
				result += child.treeSize();
			}
			return result;
		}
	}

	/**
	 * Creates a new AST node owned by the given AST. Once established,
	 * the relationship between an AST node and its owning AST does not change
	 * over the lifetime of the node. The new node has no parent node,
	 * and no properties.
	 * <p>
	 * N.B. This constructor is package-private; all subclasses my be 
	 * declared in the same package; clients are unable to declare 
	 * additional subclasses.
	 * </p>
	 * 
	 * @param ast the AST that is to own this node
	 */
	ASTNode(AST ast) {
		if (ast == null) {
			throw new IllegalArgumentException();
		}
		
		this.ast = ast;
		setNodeType(getNodeType0());
		setFlags(ast.getDefaultNodeFlag());
		// setFlags calls modifying();
	}
	
	/**
	 * Returns this node's AST.
	 * <p>
	 * Note that the relationship between an AST node and its owing AST does
	 * not change over the lifetime of a node.
	 * </p>
	 * 
	 * @return the AST that owns this node
	 */ 
	public final AST getAST() {
		return this.ast;
	}
	
	/**
	 * Returns this node's parent node, or <code>null</code> if this is the
	 * root node.
	 * <p>
	 * Note that the relationship between an AST node and its parent node
	 * may change over the lifetime of a node.
	 * </p>
	 * 
	 * @return the parent of this node, or <code>null</code> if none
	 */ 
	public final ASTNode getParent() {
		return this.parent;
	}
		
	/**
	 * Returns the location of this node within its parent,
	 * or <code>null</code> if this is a root node.
	 * <p>
	 * <pre>
	 * ASTNode node = ...;
	 * ASTNode parent = node.getParent();
	 * StructuralPropertyDescriptor location = node.getLocationInParent();
	 * assert (parent != null) == (location != null);
	 * if ((location != null) && location.isChildProperty())
	 *    assert parent.getStructuralProperty(location) == node;
	 * if ((location != null) && location.isChildListProperty())
	 *    assert ((List) parent.getStructuralProperty(location)).contains(node);
	 * </pre>
	 * </p>
	 * <p>
	 * Note that the relationship between an AST node and its parent node
	 * may change over the lifetime of a node.
	 * </p>
	 * 
	 * @return the location of this node in its parent, 
	 * or <code>null</code> if this node has no parent
	 * @since 3.0
	 */ 
	public final StructuralPropertyDescriptor getLocationInParent() {
		return this.location;
	}
		
	/**
	 * Returns the root node at or above this node; returns this node if 
	 * it is a root.
	 * 
	 * @return the root node at or above this node
	 */ 
	public final ASTNode getRoot() {
		ASTNode candidate = this;
		while (true) {
			ASTNode p = candidate.getParent();
			if (p == null) {
				// candidate has no parent - that's the guy
				return candidate;
			}
			candidate = p;
		}
	}
	
	/**
	 * Returns the value of the given structural property for this node. The value
	 * returned depends on the kind of property:
	 * <ul>
	 * <li>{@link SimplePropertyDescriptor} - the value of the given simple property,
	 * or <code>null</code> if none; primitive values are "boxed"</li>
	 * <li>{@link ChildPropertyDescriptor} - the child node (type <code>ASTNode</code>),
	 * or <code>null</code> if none</li>
	 * <li>{@link ChildListPropertyDescriptor} - the list (element type: {@link ASTNode})</li>
	 * </ul>
	 * 
	 * @param property the property
	 * @return the value, or <code>null</code> if none
	 * @exception RuntimeException if this node does not have the given property
	 * @since 3.0
	 */
	public final Object getStructuralProperty(StructuralPropertyDescriptor property) {
		if (property instanceof SimplePropertyDescriptor) {
			SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
			if (p.getValueType() == int.class) {
				int result = internalGetSetIntProperty(p, true, 0);
				return new Integer(result);
			} else if (p.getValueType() == boolean.class) {
				boolean result = internalGetSetBooleanProperty(p, true, false);
				return Boolean.valueOf(result);
			} else {
				return internalGetSetObjectProperty(p, true, null);
			}
		}
		if (property instanceof ChildPropertyDescriptor) {
			return internalGetSetChildProperty((ChildPropertyDescriptor) property, true, null);
		}
		if (property instanceof ChildListPropertyDescriptor) {
			return internalGetChildListProperty((ChildListPropertyDescriptor) property);
		}
		throw new IllegalArgumentException();
	}
	
	/**
	 * Sets the value of the given structural property for this node. The value
	 * passed depends on the kind of property:
	 * <ul>
	 * <li>{@link SimplePropertyDescriptor} - the new value of the given simple property,
	 * or <code>null</code> if none; primitive values are "boxed"</li>
	 * <li>{@link ChildPropertyDescriptor} - the new child node (type <code>ASTNode</code>),
	 * or <code>null</code> if none</li>
	 * <li>{@link ChildListPropertyDescriptor} - not allowed</li>
	 * </ul>
	 * 
	 * @param property the property
	 * @param value the property value
	 * @exception RuntimeException if this node does not have the
	 * given property, or if the given property cannot be set
	 * @since 3.0
	 */
	public final void setStructuralProperty(StructuralPropertyDescriptor property, Object value) {
		if (property instanceof SimplePropertyDescriptor) {
			SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
			if (p.getValueType() == int.class) {
				int arg = ((Integer) value).intValue();
				internalGetSetIntProperty(p, false, arg);
				return;
			} else if (p.getValueType() == boolean.class) {
				boolean arg = ((Boolean) value).booleanValue();
				internalGetSetBooleanProperty(p, false, arg);
				return;
			} else {
				if (value == null && p.isMandatory()) {
					throw new IllegalArgumentException();
				}
				internalGetSetObjectProperty(p, false, value);
				return;
			}
		}
		if (property instanceof ChildPropertyDescriptor) {
			ChildPropertyDescriptor p = (ChildPropertyDescriptor) property;
			ASTNode child = (ASTNode) value;
			if (child == null && p.isMandatory()) {
				throw new IllegalArgumentException();
			}
			internalGetSetChildProperty(p, false, child);
			return;
		}
		if (property instanceof ChildListPropertyDescriptor) {
			throw new IllegalArgumentException("Cannot set the list of child list property");  //$NON-NLS-1$
		}
	}

	/**
	 * Sets the value of the given int-valued property for this node.
	 * The default implementation of this method throws an exception explaining
	 * that this node does not have such a property. This method should be
	 * extended in subclasses that have at leasy one simple property whose value
	 * type is int.
	 * 
	 * @param property the property
	 * @param get <code>true</code> for a get operation, and 
	 * <code>false</code> for a set operation
	 * @param value the new property value; ignored for get operations
	 * @return the value; always returns
	 * <code>0</code> for set operations
	 * @exception RuntimeException if this node does not have the 
	 * given property, or if the given value cannot be set as specified
	 * @since 3.0
	 */
	int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
	}
	
	/**
	 * Sets the value of the given boolean-valued property for this node.
	 * The default implementation of this method throws an exception explaining
	 * that this node does not have such a property. This method should be
	 * extended in subclasses that have at leasy one simple property whose value
	 * type is boolean.
	 * 
	 * @param property the property
	 * @param get <code>true</code> for a get operation, and 
	 * <code>false</code> for a set operation
	 * @param value the new property value; ignored for get operations
	 * @return the value; always returns
	 * <code>false</code> for set operations
	 * @exception RuntimeException if this node does not have the 
	 * given property, or if the given value cannot be set as specified
	 * @since 3.0
	 */
	boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
	}
	
	/**
	 * Sets the value of the given property for this node.
	 * The default implementation of this method throws an exception explaining
	 * that this node does not have such a property. This method should be
	 * extended in subclasses that have at leasy one simple property whose value
	 * type is a reference type.
	 * 
	 * @param property the property
	 * @param get <code>true</code> for a get operation, and 
	 * <code>false</code> for a set operation
	 * @param value the new property value, or <code>null</code> if none;
	 * ignored for get operations
	 * @return the value, or <code>null</code> if none; always returns
	 * <code>null</code> for set operations
	 * @exception RuntimeException if this node does not have the 
	 * given property, or if the given value cannot be set as specified
	 * @since 3.0
	 */
	Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
	}

	/**
	 * Sets the child value of the given property for this node.
	 * The default implementation of this method throws an exception explaining
	 * that this node does not have such a property. This method should be
	 * extended in subclasses that have at leasy one child property.
	 * 
	 * @param property the property
	 * @param get <code>true</code> for a get operation, and 
	 * <code>false</code> for a set operation
	 * @param child the new child value, or <code>null</code> if none;
	 * always <code>null</code> for get operations
	 * @return the child, or <code>null</code> if none; always returns
	 * <code>null</code> for set operations
	 * @exception RuntimeException if this node does not have the
	 * given property, or if the given child cannot be set as specified
	 * @since 3.0
	 */
	ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
	}
	
	/**
	 * Returns the list value of the given property for this node.
	 * The default implementation of this method throws an exception explaining
	 * that this noed does not have such a property. This method should be
	 * extended in subclasses that have at leasy one child list property.
	 * 
	 * @param property the property
	 * @return the list (element type: {@link ASTNode})
	 * @exception RuntimeException if the given node does not have the
	 * given property
	 * @since 3.0
	 */
	List internalGetChildListProperty(ChildListPropertyDescriptor property) {
		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
	}
	
	/**
	 * Returns a list of structural property descriptors for nodes of the
	 * same type as this node. Clients must not modify the result.
	 * <p>
	 * Note that property descriptors are a meta-level mechanism
	 * for manipulating ASTNodes in a generic way. They are
	 * unrelated to <code>get/setProperty</code>.
	 * </p>
	 * 
	 * @return a list of property descriptors (element type: 
	 * {@link StructuralPropertyDescriptor})
	 * @since 3.0
	 */
	public final List structuralPropertiesForType() {
		return internalStructuralPropertiesForType(this.ast.apiLevel);
	}
	
	/**
	 * Returns a list of property descriptors for this node type.
	 * Clients must not modify the result. This abstract method
	 * must be implemented in each concrete AST node type.
	 * <p>
	 * N.B. This method is package-private, so that the implementations
	 * of this method in each of the concrete AST node types do not
	 * clutter up the API doc.
	 * </p>
	 * 
	 * @param apiLevel the API level; one of the <code>AST.JLS&ast;</code> constants
	 * @return a list of property descriptors (element type: 
	 * {@link StructuralPropertyDescriptor})
	 * @since 3.0
	 */
	abstract List internalStructuralPropertiesForType(int apiLevel);
	
	/**
	 * Internal helper method that starts the building a list of
	 * property descriptors for the given node type.
	 * 
	 * @param nodeClass the class for a concrete node type
	 * @param propertyList empty list
	 */
	static void createPropertyList(Class nodeClass, List propertyList) {
		// stuff nodeClass at head of list for future ref
		propertyList.add(nodeClass);
	}
	
	/**
	 * Internal helper method that adding a property descriptor.
	 * 
	 * @param property the structural property descriptor
	 * @param propertyList list beginning with the AST node class
	 * followed by accumulated structural property descriptors
	 */
	static void addProperty(StructuralPropertyDescriptor property, List propertyList) {
		Class nodeClass = (Class) propertyList.get(0);
		if (property.getNodeClass() != nodeClass) {
			// easily made cut-and-paste mistake
			throw new RuntimeException("Structural property descriptor has wrong node class!");  //$NON-NLS-1$
		}
		propertyList.add(property);
	}
		
	/**
	 * Internal helper method that completes the building of
	 * a node type's structural property descriptor list.
	 * 
	 * @param propertyList list beginning with the AST node class
	 * followed by accumulated structural property descriptors
	 * @return unmodifiable list of structural property descriptors
	 * (element type: <code>StructuralPropertyDescriptor</code>)
	 */
	static List reapPropertyList(List propertyList) {
		propertyList.remove(0); // remove nodeClass
		// compact
		ArrayList a = new ArrayList(propertyList.size());
		a.addAll(propertyList); 
		return Collections.unmodifiableList(a);
	}
	
	/**
     * Checks that this AST operation is not used when
     * building JLS2 level ASTs.

     * @exception UnsupportedOperationException
	 * @since 3.0
     */
	final void unsupportedIn2() {
	  if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
	  	throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
	  }
	}

	/**
     * Checks that this AST operation is only used when
     * building JLS2 level ASTs.

     * @exception UnsupportedOperationException
	 * @since 3.0
     */
	final void supportedOnlyIn2() {
	  if (this.ast.apiLevel != AST.JLS2_INTERNAL) {
	  	throw new UnsupportedOperationException("Operation only supported in JLS2 AST"); //$NON-NLS-1$
	  }
	}

	/**
	 * Sets or clears this node's parent node and location.
	 * <p>
	 * Note that this method is package-private. The pointer from a node
	 * to its parent is set implicitly as a side effect of inserting or
	 * removing the node as a child of another node. This method calls
	 * <code>ast.modifying()</code>.
	 * </p>
	 * 
	 * @param parent the new parent of this node, or <code>null</code> if none
	 * @param property the location of this node in its parent, 
	 * or <code>null</code> if <code>parent</code> is <code>null</code>
	 * @see #getLocationInParent
	 * @see #getParent
	 * @since 3.0
	 */ 
	final void setParent(ASTNode parent, StructuralPropertyDescriptor property) {
		this.ast.modifying();
		this.parent = parent;
		this.location = property;
	}
	
	/**
	 * Removes this node from its parent. Has no effect if this node
	 * is unparented. If this node appears as an element of a child list
	 * property of its parent, then this node is removed from the
	 * list using <code>List.remove</code>.
	 * If this node appears as the value of a child property of its
	 * parent, then this node is detached from its parent 
	 * by passing <code>null</code> to the appropriate setter method;
	 * this operation fails if this node is in a mandatory property.
	 * 
	 * @since 3.0
	 */ 
	public final void delete() {
		StructuralPropertyDescriptor p = getLocationInParent();
		if (p == null) {
			// node is unparented
			return;
		}
		if (p.isChildProperty()) {
			getParent().setStructuralProperty(this.location, null);
			return;
		}
		if (p.isChildListProperty()) {
			List l = (List) getParent().getStructuralProperty(this.location);
			l.remove(this);
		}
	}

	/**
	 * Checks whether the given new child node is a node 
	 * in a different AST from its parent-to-be, whether it is
	 * already has a parent, whether adding it to its
	 * parent-to-be would create a cycle, and whether the child is of
	 * the right type. The parent-to-be is the enclosing instance.
	 * 
	 * @param node the parent-to-be node
	 * @param newChild the new child of the parent
	 * @param cycleCheck <code>true</code> if cycles are possible and need 
	 *   to be checked, <code>false</code> if cycles are impossible and do 
	 *   not need to be checked
	 * @param nodeType a type constraint on child nodes, or <code>null</code>
	 *   if no special check is required
	 * @exception IllegalArgumentException if:
	 * <ul>
	 * <li>the child is null</li>
	 * <li>the node belongs to a different AST</li>
	 * <li>the child has the incorrect node type</li>
	 * <li>the node already has a parent</li>
	 * <li>a cycle in would be created</li>
	 * </ul>
	 */ 
	static void checkNewChild(ASTNode node, ASTNode newChild,
			boolean cycleCheck, Class nodeType) {
		if (newChild.ast != node.ast) {
			// new child is from a different AST
			throw new IllegalArgumentException();
		}		
		if (newChild.getParent() != null) {
			// new child currently has a different parent
			throw new IllegalArgumentException();
		}
		if (cycleCheck && newChild == node.getRoot()) {
			// inserting new child would create a cycle
			throw new IllegalArgumentException();
		}
		Class childClass = newChild.getClass();
		if (nodeType != null && !nodeType.isAssignableFrom(childClass)) {
			// new child is not of the right type
			throw new ClassCastException();
		}
		if ((newChild.typeAndFlags & PROTECT) != 0) {
			// new child node is protected => cannot be parented
			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
		}
	}

	/**
     * Prelude portion of the "3 step program" for replacing the
	 * old child of this node with another node.
     * Here is the code pattern found in all AST node subclasses:
     * <pre>
     * ASTNode oldChild = this.foo;
     * preReplaceChild(oldChild, newFoo, FOO_PROPERTY);
     * this.foo = newFoo;
     * postReplaceChild(oldChild, newFoo, FOO_PROPERTY);
     * </pre>
     * The first part (preReplaceChild) does all the precondition checks,
     * reports pre-delete events, and changes parent links.
	 * The old child is delinked from its parent (making it a root node),
	 * and the new child node is linked to its parent. The new child node
	 * must be a root node in the same AST as its new parent, and must not
	 * be an ancestor of this node. All three nodes must be
     * modifiable (not PROTECTED). The replace operation must fail
     * atomically; so it is crucial that all precondition checks
     * be done before any linking and delinking happens.
     * The final part (postReplaceChild )reports post-add events.
	 * <p>
	 * This method calls <code>ast.modifying()</code> for the nodes affected.
	 * </p>
	 * 
	 * @param oldChild the old child of this node, or <code>null</code> if
	 *   there was no old child to replace
	 * @param newChild the new child of this node, or <code>null</code> if
	 *   there is no replacement child
	 * @param property the property descriptor of this node describing
     * the relationship between node and child
	 * @exception RuntimeException if:
	 * <ul>
	 * <li>the node belongs to a different AST</li>
	 * <li>the node already has a parent</li>
	 * <li>a cycle in would be created</li>
	 * <li>any of the nodes involved are unmodifiable</li>
	 * </ul>
	 * @since 3.0
	 */ 
	final void preReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property) {
		if ((this.typeAndFlags & PROTECT) != 0) {
			// this node is protected => cannot gain or lose children
			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
		}
		if (newChild != null) {
			checkNewChild(this, newChild, property.cycleRisk, null);
		}
		// delink old child from parent
		if (oldChild != null) {
			if ((oldChild.typeAndFlags & PROTECT) != 0) {
				// old child node is protected => cannot be unparented
				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
			}
			if (newChild != null) {
				this.ast.preReplaceChildEvent(this, oldChild, newChild, property);
			} else {
				this.ast.preRemoveChildEvent(this, oldChild, property);
			}
			oldChild.setParent(null, null);
		} else {
			if(newChild != null) {
				this.ast.preAddChildEvent(this, newChild, property);
			}
		}
		// link new child to parent
		if (newChild != null) {
			newChild.setParent(this, property);
			// cannot notify postAddChildEvent until parent is linked to child too
		}
	}

	/**
     * Postlude portion of the "3 step program" for replacing the
	 * old child of this node with another node.
     * See {@link #preReplaceChild(ASTNode, ASTNode, ChildPropertyDescriptor)}
     * for details.
	 * @since 3.0
	 */ 
	final void postReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property) {
		// link new child to parent
		if (newChild != null) {
			if (oldChild != null) {
				this.ast.postReplaceChildEvent(this, oldChild, newChild, property);
			} else {
				this.ast.postAddChildEvent(this, newChild, property);
			}
		} else {
			this.ast.postRemoveChildEvent(this, oldChild, property);
		}
	}
	
	/**
     * Prelude portion of the "3 step program" for changing the
	 * value of a simple property of this node.
     * Here is the code pattern found in all AST node subclasses:
     * <pre>
     * preValueChange(FOO_PROPERTY);
     * this.foo = newFoo;
     * postValueChange(FOO_PROPERTY);
     * </pre>
     * The first part (preValueChange) does the precondition check
     * to make sure the node is modifiable (not PROTECTED).
     * The change operation must fail atomically; so it is crucial
     * that the precondition checks are done before the field is
     * hammered. The final part (postValueChange)reports post-change
     * events.
	 * <p>
	 * This method calls <code>ast.modifying()</code> for the node affected.
	 * </p>
	 * 
	 * @param property the property descriptor of this node 
	 * @exception RuntimeException if:
	 * <ul>
	 * <li>this node is unmodifiable</li>
	 * </ul>
	 * @since 3.0
	 */ 
	final void preValueChange(SimplePropertyDescriptor property) {
		if ((this.typeAndFlags & PROTECT) != 0) {
			// this node is protected => cannot change valure of properties
			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
		}
		this.ast.preValueChangeEvent(this, property);
		this.ast.modifying();
	}

	/**
     * Postlude portion of the "3 step program" for replacing the
	 * old child of this node with another node.
     * See {@link #preValueChange(SimplePropertyDescriptor)} for details.
	 * @since 3.0
	 */ 
	final void postValueChange(SimplePropertyDescriptor property) {
		this.ast.postValueChangeEvent(this, property);
	}
	
	/**
     * Ensures that this node is modifiable (that is, not marked PROTECTED).
     * If successful, calls ast.modifying().
     * @exception RuntimeException is not modifiable
     */
	final void checkModifiable() {
		if ((this.typeAndFlags & PROTECT) != 0) {
			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
		}
		this.ast.modifying();
	}
	
	/**
     * Begin lazy initialization of this node.
     * Here is the code pattern found in all AST
     * node subclasses:
     * <pre>
     * if (this.foo == null) {
	 *    // lazy init must be thread-safe for readers
     *    synchronized (this) {
     *       if (this.foo == null) {
     *          preLazyInit();
     *          this.foo = ...; // code to create new node
     *          postLazyInit(this.foo, FOO_PROPERTY);
     *       }
     *    }
     * }
     * </pre>
     * @since 3.0
     */
	final void preLazyInit() {
		// IMPORTANT: this method is called by readers
		// ASTNode.this is locked at this point
		this.ast.disableEvents();
		// will turn events back on in postLasyInit
	}
	
	/**
     * End lazy initialization of this node.
     * 
	 * @param newChild the new child of this node, or <code>null</code> if
	 *   there is no replacement child
	 * @param property the property descriptor of this node describing
     * the relationship between node and child
     * @since 3.0
     */
	final void postLazyInit(ASTNode newChild, ChildPropertyDescriptor property) {
		// IMPORTANT: this method is called by readers
		// ASTNode.this is locked at this point
		// newChild is brand new (so no chance of concurrent access)
		newChild.setParent(this, property);
		// turn events back on (they were turned off in corresponding preLazyInit)
		this.ast.reenableEvents();
	}

	/**
	 * Returns the named property of this node, or <code>null</code> if none.
	 * 
	 * @param propertyName the property name
	 * @return the property value, or <code>null</code> if none
	 * @see #setProperty(String,Object)
	 */
	public final Object getProperty(String propertyName) {
		if (propertyName == null) {
			throw new IllegalArgumentException();
		}
		if (this.property1 == null) {
			// node has no properties at all
			return null;
		}
		if (this.property1 instanceof String) {
			// node has only a single property
			if (propertyName.equals(this.property1)) {
				return this.property2;
			} else {
				return null;
			}
		}
		// otherwise node has table of properties
		Map m = (Map) this.property1;
		return m.get(propertyName);
	}
	
	/**
	 * Sets the named property of this node to the given value,
	 * or to <code>null</code> to clear it.
	 * <p>
	 * Clients should employ property names that are sufficiently unique
	 * to avoid inadvertent conflicts with other clients that might also be
	 * setting properties on the same node.
	 * </p>
	 * <p>
	 * Note that modifying a property is not considered a modification to the 
	 * AST itself. This is to allow clients to decorate existing nodes with 
	 * their own properties without jeopardizing certain things (like the 
	 * validity of bindings), which rely on the underlying tree remaining static.
	 * </p>
	 * 
	 * @param propertyName the property name
	 * @param data the new property value, or <code>null</code> if none
	 * @see #getProperty(String)
	 */
	public final void setProperty(String propertyName, Object data) {
		if (propertyName == null) {
			throw new IllegalArgumentException();
		}
		// N.B. DO NOT CALL ast.modifying();

		if (this.property1 == null) {
			// node has no properties at all
			if (data == null) {
				// we already know this
				return;
			}
			// node gets its fist property
			this.property1 = propertyName;
			this.property2 = data;
			return;
		}

		if (this.property1 instanceof String) {
			// node has only a single property
			if (propertyName.equals(this.property1)) {
				// we're in luck
				this.property2 = data;
				if (data == null) {
					// just deleted last property
					this.property1 = null;
					this.property2 = null;
				}
				return;
			}
			if (data == null) {
				// we already know this
				return;
			}
			// node already has one property - getting its second
			// convert to more flexible representation
			HashMap m = new HashMap(2);
			m.put(this.property1, this.property2);
			m.put(propertyName, data);
			this.property1 = m;
			this.property2 = null;
			return;
		}
			
		// node has two or more properties
		HashMap m = (HashMap) this.property1;
		if (data == null) {
			m.remove(propertyName);
			// check for just one property left
			if (m.size() == 1) {
				// convert to more efficient representation
				Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]);
				this.property1 = entries[0].getKey();
				this.property2 = entries[0].getValue();
			}
			return;
		} else {
			m.put(propertyName, data);
			// still has two or more properties
			return;
		}
	}

	/**
	 * Returns an unmodifiable table of the properties of this node with 
	 * non-<code>null</code> values.
	 * 
	 * @return the table of property values keyed by property name
	 *   (key type: <code>String</code>; value type: <code>Object</code>)
	 */
	public final Map properties() {
		if (this.property1 == null) {
			// node has no properties at all
			return UNMODIFIABLE_EMPTY_MAP;
		} 
		if (this.property1 instanceof String) {
			// node has a single property
			return Collections.singletonMap(this.property1, this.property2);
		}
		
		// node has two or more properties
		if (this.property2 == null) {
			this.property2 = Collections.unmodifiableMap((Map) this.property1);
		}
		// property2 is unmodifiable wrapper for map in property1
		return (Map) this.property2;
	}
	
	/**
	 * Returns the flags associated with this node.
	 * <p>
	 * No flags are associated with newly created nodes.
	 * </p>
	 * <p>
	 * The flags are the bitwise-or of individual flags.
	 * The following flags are currently defined:
	 * <ul>
	 * <li>{@link #MALFORMED} - indicates node is syntactically 
	 *   malformed</li>
	 * <li>{@link #ORIGINAL} - indicates original node
	 * created by ASTParser</li>
	 * <li>{@link #PROTECT} - indicates node is protected
	 * from further modification</li>
	 * </ul>
	 * Other bit positions are reserved for future use.
	 * </p>
	 * 
	 * @return the bitwise-or of individual flags
	 * @see #setFlags(int)
	 */
	public final int getFlags() {
		return this.typeAndFlags & 0xFFFF;
	}
	
	/**
	 * Sets the flags associated with this node to the given value.
	 * <p>
	 * The flags are the bitwise-or of individual flags.
	 * The following flags are currently defined:
	 * <ul>
	 * <li>{@link #MALFORMED} - indicates node is syntactically 
	 *   malformed</li>
	 * <li>{@link #ORIGINAL} - indicates original node
	 * created by ASTParser</li>
	 * <li>{@link #PROTECT} - indicates node is protected
	 * from further modification</li>
	 * </ul>
	 * Other bit positions are reserved for future use.
	 * </p>
	 * <p>
	 * Note that the flags are <em>not</em> considered a structural
	 * property of the node, and can be changed even if the
	 * node is marked as protected.
	 * </p>
	 * 
	 * @param flags the bitwise-or of individual flags
	 * @see #getFlags()
	 */
	public final void setFlags(int flags) {
		this.ast.modifying();
		int old = this.typeAndFlags & 0xFFFF0000;
		this.typeAndFlags = old | (flags & 0xFFFF);
	}

	/**
	 * Returns an integer value identifying the type of this concrete AST node.
	 * The values are small positive integers, suitable for use in switch statements.
	 * <p>
	 * For each concrete node type there is a unique node type constant (name
	 * and value). The unique node type constant for a concrete node type such as 
	 * <code>CastExpression</code> is <code>ASTNode.CAST_EXPRESSION</code>.
	 * </p>
	 * 
	 * @return one of the node type constants
	 */
	public final int getNodeType() {
		return this.typeAndFlags >>> 16;
	}
	
	/**
	 * Sets the integer value identifying the type of this concrete AST node.
	 * The values are small positive integers, suitable for use in switch statements.
	 * 
	 * @param nodeType one of the node type constants
	 */
	private void setNodeType(int nodeType) {
		int old = this.typeAndFlags & 0xFFFF0000;
		this.typeAndFlags = old | (nodeType << 16);
	}
	
	/**
	 * Returns an integer value identifying the type of this concrete AST node.
	 * <p>
	 * This internal method is implemented in each of the
	 * concrete node subclasses.
	 * </p>
	 * 
	 * @return one of the node type constants
	 */
	abstract int getNodeType0();
	
	/**
	 * The <code>ASTNode</code> implementation of this <code>Object</code>
	 * method uses object identity (==). Use <code>subtreeMatch</code> to
	 * compare two subtrees for equality.
	 * 
	 * @param obj {@inheritDoc}
	 * @return {@inheritDoc}
	 * @see #subtreeMatch(ASTMatcher matcher, Object other)
	 */
	public final boolean equals(Object obj) {
		return this == obj; // equivalent to Object.equals
	}

	/**
	 * Returns whether the subtree rooted at the given node matches the
	 * given other object as decided by the given matcher.
	 * 
	 * @param matcher the matcher
	 * @param other the other object, or <code>null</code>
	 * @return <code>true</code> if the subtree matches, or 
	 * <code>false</code> if they do not match
	 */
	public final boolean subtreeMatch(ASTMatcher matcher, Object other) {
		return subtreeMatch0(matcher, other);
	}
	
	/**
	 * Returns whether the subtree rooted at the given node matches the
	 * given other object as decided by the given matcher.
	 * <p>
	 * This internal method is implemented in each of the
	 * concrete node subclasses.
	 * </p>
	 * 
	 * @param matcher the matcher
	 * @param other the other object, or <code>null</code>
	 * @return <code>true</code> if the subtree matches, or 
	 * <code>false</code> if they do not match
	 */
	abstract boolean subtreeMatch0(ASTMatcher matcher, Object other);
	
	/**
	 * Returns a deep copy of the subtree of AST nodes rooted at the
	 * given node. The resulting nodes are owned by the given AST,
	 * which may be different from the ASTs of the given node. 
	 * Even if the given node has a parent, the result node will be unparented.
	 * <p>
	 * Source range information on the original nodes is automatically copied to the new
	 * nodes. Client properties (<code>properties</code>) are not carried over.
	 * </p>
	 * <p>
	 * The node's <code>AST</code> and the target <code>AST</code> must support
     * the same API level.
	 * </p>
	 * 
	 * @param target the AST that is to own the nodes in the result
	 * @param node the node to copy, or <code>null</code> if none
	 * @return the copied node, or <code>null</code> if <code>node</code>
	 *    is <code>null</code>
	 */
	public static ASTNode copySubtree(AST target, ASTNode node) {
		if (node == null) {
			return null;
		}
		if (target == null) {
			throw new IllegalArgumentException();
		}
		if (target.apiLevel() != node.getAST().apiLevel()) {
			throw new UnsupportedOperationException();
		}
		ASTNode newNode = node.clone(target);
		return newNode;
	}

	/**
	 * Returns a deep copy of the subtrees of AST nodes rooted at the
	 * given list of nodes. The resulting nodes are owned by the given AST,
	 * which may be different from the ASTs of the nodes in the list. 
	 * Even if the nodes in the list have parents, the nodes in the result
	 * will be unparented.
	 * <p>
	 * Source range information on the original nodes is automatically copied to the new
	 * nodes. Client properties (<code>properties</code>) are not carried over.
	 * </p>
	 * 
	 * @param target the AST that is to own the nodes in the result
	 * @param nodes the list of nodes to copy
	 *    (element type: <code>ASTNode</code>)
	 * @return the list of copied subtrees
	 *    (element type: <code>ASTNode</code>)
	 */
	public static List copySubtrees(AST target, List nodes) {
		List result = new ArrayList(nodes.size());
		for (Iterator it = nodes.iterator(); it.hasNext(); ) {
			ASTNode oldNode = (ASTNode) it.next();
			ASTNode newNode = oldNode.clone(target);
			result.add(newNode);
		}
		return result;
	}

	/**
	 * Returns a deep copy of the subtree of AST nodes rooted at this node.
	 * The resulting nodes are owned by the given AST, which may be different
	 * from the AST of this node. Even if this node has a parent, the 
	 * result node will be unparented.
	 * <p>
	 * This method reports pre- and post-clone events, and dispatches
	 * to <code>clone0(AST)</code> which is reimplemented in node subclasses.
	 * </p>
	 * 
	 * @param target the AST that is to own the nodes in the result
	 * @return the root node of the copies subtree
	 */
	final ASTNode clone(AST target) {
		this.ast.preCloneNodeEvent(this);
		ASTNode c = this.clone0(target);
		this.ast.postCloneNodeEvent(this, c);
		return c;
	}

	/**
	 * Returns a deep copy of the subtree of AST nodes rooted at this node.
	 * The resulting nodes are owned by the given AST, which may be different
	 * from the AST of this node. Even if this node has a parent, the 
	 * result node will be unparented.
	 * <p>
	 * This method must be implemented in subclasses.
	 * </p>
	 * <p>
	 * This method does not report pre- and post-clone events.
	 * All callers should instead call <code>clone(AST)</code>
	 * to ensure that pre- and post-clone events are reported.
	 * </p>
	 * <p>
	 * N.B. This method is package-private, so that the implementations
	 * of this method in each of the concrete AST node types do not
	 * clutter up the API doc. 
	 * </p>
	 * 
	 * @param target the AST that is to own the nodes in the result
	 * @return the root node of the copies subtree
	 */
	abstract ASTNode clone0(AST target);
	
	/**
	 * Accepts the given visitor on a visit of the current node.
	 * 
	 * @param visitor the visitor object
	 * @exception IllegalArgumentException if the visitor is null
	 */
	public final void accept(ASTVisitor visitor) {
		if (visitor == null) {
			throw new IllegalArgumentException();
		}
		// begin with the generic pre-visit
		visitor.preVisit(this);
		// dynamic dispatch to internal method for type-specific visit/endVisit
		accept0(visitor);
		// end with the generic post-visit
		visitor.postVisit(this);
	}

	/**
	 * Accepts the given visitor on a type-specific visit of the current node.
	 * This method must be implemented in all concrete AST node types.
	 * <p>
	 * General template for implementation on each concrete ASTNode class:
	 * <pre>
	 * <code>
	 * boolean visitChildren = visitor.visit(this);
	 * if (visitChildren) {
	 *    // visit children in normal left to right reading order
	 *    acceptChild(visitor, getProperty1());
	 *    acceptChildren(visitor, rawListProperty);
	 *    acceptChild(visitor, getProperty2());
	 * }
	 * visitor.endVisit(this);
	 * </code>
	 * </pre>
	 * Note that the caller (<code>accept</code>) take cares of invoking
	 * <code>visitor.preVisit(this)</code> and <code>visitor.postVisit(this)</code>.
	 * </p>
	 * 
	 * @param visitor the visitor object
	 */
	abstract void accept0(ASTVisitor visitor);

	/**
	 * Accepts the given visitor on a visit of the current node.
	 * <p>
	 * This method should be used by the concrete implementations of
	 * <code>accept0</code> to traverse optional properties. Equivalent
	 * to <code>child.accept(visitor)</code> if <code>child</code>
	 * is not <code>null</code>.
	 * </p>
	 * 
	 * @param visitor the visitor object
	 * @param child the child AST node to dispatch too, or <code>null</code>
	 *    if none
	 */
	final void acceptChild(ASTVisitor visitor, ASTNode child) {
		if (child == null) {
			return;
		}
		child.accept(visitor);
	}

	/**
	 * Accepts the given visitor on a visit of the given live list of
	 * child nodes. 
	 * <p>
	 * This method must be used by the concrete implementations of
	 * <code>accept</code> to traverse list-values properties; it
	 * encapsulates the proper handling of on-the-fly changes to the list.
	 * </p>
	 * 
	 * @param visitor the visitor object
	 * @param children the child AST node to dispatch too, or <code>null</code>
	 *    if none
	 */
	final void acceptChildren(ASTVisitor visitor, ASTNode.NodeList children) {
		// use a cursor to keep track of where we are up to
		// (the list may be changing under foot)
		NodeList.Cursor cursor = children.newCursor();
		try {
			while (cursor.hasNext()) {
				ASTNode child = (ASTNode) cursor.next();
				child.accept(visitor);
			}
		} finally {
			children.releaseCursor(cursor);
		}
	}

	/**
	 * Returns the character index into the original source file indicating
	 * where the source fragment corresponding to this node begins.
	 * <p>
	 * The parser supplies useful well-defined source ranges to the nodes it creates.
	 * See {@link ASTParser#setKind(int)} for details
	 * on precisely where source ranges begin and end.
	 * </p>
	 * 
	 * @return the 0-based character index, or <code>-1</code>
	 *    if no source position information is recorded for this node
	 * @see #getLength()
	 * @see ASTParser
	 */
	public final int getStartPosition() {
		return this.startPosition;
	}

	/**
	 * Returns the length in characters of the original source file indicating
	 * where the source fragment corresponding to this node ends.
	 * <p>
	 * The parser supplies useful well-defined source ranges to the nodes it creates.
	 * See {@link ASTParser#setKind(int)} methods for details
	 * on precisely where source ranges begin and end.
	 * </p>
	 * 
	 * @return a (possibly 0) length, or <code>0</code>
	 *    if no source position information is recorded for this node
	 * @see #getStartPosition()
	 * @see ASTParser
	 */
	public final int getLength() {
		return this.length;
	}

	/**
	 * Sets the source range of the original source file where the source
	 * fragment corresponding to this node was found.
	 * <p>
	 * See {@link ASTParser#setKind(int)} for details
	 * on precisely where source ranges are supposed to begin and end.
	 * </p>
	 * 
	 * @param startPosition a 0-based character index, 
	 *    or <code>-1</code> if no source position information is 
	 *    available for this node
	 * @param length a (possibly 0) length, 
	 *    or <code>0</code> if no source position information is recorded 
	 *    for this node
	 * @see #getStartPosition()
	 * @see #getLength()
	 * @see ASTParser
	 */
	public final void setSourceRange(int startPosition, int length) {
		if (startPosition >= 0 && length < 0) {
			throw new IllegalArgumentException();
		}
		if (startPosition < 0 && length != 0) {
			throw new IllegalArgumentException();
		}
		// source positions are not considered a structural property
		// but we protect them nevertheless
		checkModifiable();
		this.startPosition = startPosition;
		this.length = length;
	}
	
	/**
	 * Returns a string representation of this node suitable for debugging
	 * purposes only.
	 * 
	 * @return a debug string 
	 */
	public final String toString() {
		StringBuffer buffer = new StringBuffer();
		int p = buffer.length();
		try {
			appendDebugString(buffer);
		} catch (RuntimeException e) {
			// since debugger sometimes call toString methods, problems can easily happen when
			// toString is called on an instance that is being initialized
			buffer.setLength(p);
			buffer.append("!"); //$NON-NLS-1$
			buffer.append(standardToString());
		}
		return buffer.toString();
	}
	
	/**
	 * Returns the string representation of this node produced by the standard
	 * <code>Object.toString</code> method.
	 * 
	 * @return a debug string 
	 */
	final String standardToString() {
		return super.toString();
	}
	
	/**
	 * Appends a debug representation of this node to the given string buffer.
	 * <p>
	 * The <code>ASTNode</code> implementation of this method prints out the entire 
	 * subtree. Subclasses may override to provide a more succinct representation.
	 * </p>
	 * 
	 * @param buffer the string buffer to append to
	 */
	void appendDebugString(StringBuffer buffer) {
		// print the subtree by default
		appendPrintString(buffer);
	}
		
	/**
	 * Appends a standard Java source code representation of this subtree to the given
	 * string buffer.
	 * 
	 * @param buffer the string buffer to append to
	 */
	final void appendPrintString(StringBuffer buffer) {
		NaiveASTFlattener printer = new NaiveASTFlattener();
		this.accept(printer);
		buffer.append(printer.getResult());
	}
	
	/**
	 * Estimate of size of an object header in bytes.
	 */
	static final int HEADERS = 12;
	
	/**
	 * Approximate base size of an AST node instance in bytes, 
	 * including object header and instance fields.
	 * That is, HEADERS + (# instance vars in ASTNode)*4.
	 */
	static final int BASE_NODE_SIZE = HEADERS + 7 * 4;
	
	/**
	 * Returns an estimate of the memory footprint, in bytes,
	 * of the given string.
	 * 
	 * @param string the string to measure, or <code>null</code>
	 * @return the size of this string object in bytes, or
	 *   0 if the string is <code>null</code>
     * @since 3.0
	 */
	static int stringSize(String string) {
		int size = 0;
		if (string != null) {
			// Strings usually have 4 instance fields, one of which is a char[]
			size += HEADERS + 4 * 4;
			// char[] has 2 bytes per character
			size += HEADERS + 2 * string.length();
		}
		return size;
	}
	
	/**
	 * Returns an estimate of the memory footprint in bytes of the entire 
	 * subtree rooted at this node.
	 * 
	 * @return the size of this subtree in bytes
	 */
	public final int subtreeBytes() {
		return treeSize();
	}
		
	/**
	 * Returns an estimate of the memory footprint in bytes of the entire 
	 * subtree rooted at this node.
	 * <p>
	 * N.B. This method is package-private, so that the implementations
	 * of this method in each of the concrete AST node types do not
	 * clutter up the API doc.
	 * </p>
	 * 
	 * @return the size of this subtree in bytes
	 */
	abstract int treeSize();

	/**
	 * Returns an estimate of the memory footprint of this node in bytes.
	 * The estimate does not include the space occupied by child nodes.
	 * 
	 * @return the size of this node in bytes
	 */
	abstract int memSize();
}
