/*******************************************************************************
 * Copyright (c) 2000, 2004 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.internal.core.jdom;

import java.util.ArrayList;
import java.util.Map;

import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.jdom.*;
import org.eclipse.jdt.internal.compiler.DocumentElementParser;
import org.eclipse.jdt.internal.compiler.IDocumentElementRequestor;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
/**
 * The DOMBuilder constructs each type of JDOM document fragment,
 * for the DOMFactory. The DOMBuilder has been separated from the
 * DOMFactory to hide the implmentation of node creation and the
 * public Requestor API methods.
 * 
 * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
 * powerful, fine-grained DOM/AST API found in the 
 * org.eclipse.jdt.core.dom package.
 */
public class DOMBuilder extends AbstractDOMBuilder implements IDocumentElementRequestor {
	
	/**
	 * True when parsing a single member - ignore any problems
	 * encountered after the member.
	 */
	protected boolean fBuildingSingleMember= false;
	
	/**
	 * True when the single member being built has been
	 * exited.
	 */
	protected boolean fFinishedSingleMember = false;		

	/**
	 * Collection of multiple fields in one declaration
	 */
	protected ArrayList fFields;

	Map options = JavaCore.getOptions();

/**
 * Creates a new DOMBuilder
 */
public DOMBuilder() {
	// Creates a new DOMBuilder
}
/**
 * @see IDocumentElementRequestor#acceptImport(int, int, int[], char[], int, boolean, int)
 */
public void acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, 
	int nameStart, boolean onDemand, int modifiers) {
	int[] sourceRange = {declarationStart, declarationEnd};
	int[] nameRange = {nameStart, declarationEnd - 1};
	
	/* See 1FVII1P */
	String importName = new String(fDocument, nameRange[0], nameRange[1] + 1 - nameRange[0]);

	fNode= new DOMImport(fDocument, sourceRange, importName, nameRange, onDemand, modifiers);
	addChild(fNode);
	if (fBuildingSingleMember) {
		fFinishedSingleMember= true;
	}
}
/**
 * @see IDocumentElementRequestor#acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, int modifiersStart, int bodyStart, int bodyEnd)
 */
public void acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, 
	int modifiersStart, int bodyStart, int bodyEnd) {
	int[] sourceRange = {declarationStart, declarationEnd};
	int[] commentRange = {-1, -1};
	if (javaDocPositions != null) {
		int length = javaDocPositions.length;
		commentRange[0] = javaDocPositions[length - 2];
		commentRange[1] = javaDocPositions[length - 1];
	}

	int[] modifiersRange = {-1, -1};
	if (modifiersStart >= declarationStart) {
		modifiersRange[0] = modifiersStart;
		modifiersRange[1] = bodyStart - 1;
	}
	fNode = new DOMInitializer(fDocument, sourceRange, commentRange, modifiers, 
		modifiersRange, bodyStart);
	addChild(fNode);
	if (fBuildingSingleMember) {
		fFinishedSingleMember= true;
	}
}
/**
 * @see IDocumentElementRequestor#acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition)
 */
public void acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, 
	int nameStartPosition) {
	int[] sourceRange = {declarationStart, declarationEnd};
	int[] nameRange = {nameStartPosition, declarationEnd - 1};
	fNode= new DOMPackage(fDocument, sourceRange, CharOperation.charToString(name), nameRange);
	addChild(fNode);
	if (fBuildingSingleMember) {
		fFinishedSingleMember= true;
	}
}
/**
 * Sets the abort flag to true. The parser has encountered an error
 * in the current document. If we are only building a single member, and
 * we are done with the member - don't worry about the error.
 *
 * @see IDocumentElementRequestor
 */
public void acceptProblem(IProblem problem){
	if (fBuildingSingleMember && fFinishedSingleMember) {
		return;
	}
	fAbort= true;
}
/**
 * Adds the given node to the current enclosing scope, building the JDOM
 * tree. Nodes are only added to an enclosing scope when a compilation unit or type
 * is being built (since those are the only nodes that have children).
 *
 * <p>NOTE: nodes are added to the JDOM via the method #basicAddChild such that
 * the nodes in the newly created JDOM are not fragmented. 
 */
protected void addChild(IDOMNode child) {
	super.addChild(child);
	if (fStack.isEmpty() && fFields != null) {
		fFields.add(child);
	}
}
/**
 * @see IDOMFactory#createCompilationUnit()
 */
public IDOMCompilationUnit createCompilationUnit() {
	return new DOMCompilationUnit();
}
/**
 * @see IDOMFactory#createCompilationUnit(String, String)
 */
public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
	initializeBuild(compilationUnit.getContents(), true, true, false);
	getParser(options).parseCompilationUnit(compilationUnit);
	return super.createCompilationUnit(compilationUnit);
}
/**
 * @see IDOMFactory#createField(String)
 */
public IDOMField createField(char[] sourceCode) {
	initializeBuild(sourceCode, false, false, true);
	getParser(options).parseField(sourceCode);
	if (fAbort || fNode == null) {
		return null;
	}

	// we only accept field declarations with one field
	if (fFieldCount > 1) {
		return null;
	}
	
	fNode.normalize(this);
	return (IDOMField)fNode;
}
/**
 * 
 */
public IDOMField[] createFields(char[] sourceCode) {
	initializeBuild(sourceCode, false, false, false);
	fFields= new ArrayList();
	getParser(options).parseField(sourceCode);
	if (fAbort) {
		return null;
	}
	IDOMField[] fields= new IDOMField[fFields.size()];
	fFields.toArray(fields);
	for (int i= 0; i < fields.length; i++) {
		DOMNode node= (DOMNode)fields[i];
		if (i < (fields.length - 1)) {
			DOMNode next= (DOMNode)fields[i + 1];
			node.fNextNode= next;
			next.fPreviousNode= node;
		}
		((DOMNode)fields[i]).normalize(this);
	}
	return fields;
}
/**
 * @see IDOMFactory#createImport()
 */
public IDOMImport createImport() {
	return new DOMImport();
}
/**
 * @see IDOMFactory#createImport(String)
 */
public IDOMImport createImport(char[] sourceCode) {
	initializeBuild(sourceCode, false, false, true);
	getParser(options).parseImport(sourceCode);
	if (fAbort || fNode == null) {
		return null;
	}
	fNode.normalize(this);
	return (IDOMImport)fNode;
}
/**
 * Creates an INITIALIZER document fragment from the given source.
 *
 * @see IDOMFactory#createInitializer(String)
 */
public IDOMInitializer createInitializer(char[] sourceCode) {
	initializeBuild(sourceCode, false, false, true);
	getParser(options).parseInitializer(sourceCode);
	if (fAbort || fNode == null || !(fNode instanceof IDOMInitializer)) {
		return null;
	}
	fNode.normalize(this);
	return (IDOMInitializer)fNode;
}
/**
 * @see IDOMFactory#createMethod(String)
 */
public IDOMMethod createMethod(char[] sourceCode) {
	initializeBuild(sourceCode, false, false, true);
	getParser(options).parseMethod(sourceCode);
	if (fAbort || fNode == null) {
		return null;
	}
	fNode.normalize(this);
	return (IDOMMethod)fNode;
}
/**
 * @see IDOMFactory#createPackage()
 */
public IDOMPackage createPackage() {
	return new DOMPackage();
}
/**
 * @see IDOMFactory#createPackage(String)
 */
public IDOMPackage createPackage(char[] sourceCode) {
	initializeBuild(sourceCode, false, false, true);
	getParser(options).parsePackage(sourceCode);
	if (fAbort || fNode == null) {
		return null;
	}
	fNode.normalize(this);
	return (IDOMPackage)fNode;
}
/**
 * @see IDOMFactory#createType(String)
 */
public IDOMType createType(char[] sourceCode) {
	initializeBuild(sourceCode, false, true, false);
	getParser(options).parseType(sourceCode);
	if (fAbort) {
		return null;
	}
	if (fNode != null) fNode.normalize(this);
	return (IDOMType)fNode;
}
/**
 * Creates a new DOMMethod and inizializes.
 *
 * @param declarationStart - a source position corresponding to the first character 
 *		of this constructor declaration
 * @param modifiers - the modifiers for this constructor converted to a flag
 * @param modifiersStart - a source position corresponding to the first character of the
 *		textual modifiers
 * @param returnType - the name of the return type
 * @param returnTypeStart - a source position corresponding to the first character
 *		of the return type
 * @param returnTypeEnd - a source position corresponding to the last character
 *		of the return type
 * @param returnTypeDimensionCount - the array dimension count as supplied on the
 *		return type (for instance, 'public int[] foo() {}')
 * @param name - the name of this constructor
 * @param nameStart - a source position corresponding to the first character of the name
 * @param nameEnd - a source position corresponding to the last character of the name
 * @param parameterTypes - a list of parameter type names
 * @param parameterTypeStarts - a list of source positions corresponding to the
 *		first character of each parameter type name
 * @param parameterTypeEnds - a list of source positions corresponding to the
 *		last character of each parameter type name
 * @param parameterNames - a list of the names of the parameters
 * @param parametersEnd - a source position corresponding to the last character of the
 *		parameter list
 * @extendedReturnTypeDimensionCount - the array dimension count as supplied on the
 *		end of the parameter list (for instance, 'public int foo()[] {}')
 * @extendedReturnTypeDimensionEnd - a source position corresponding to the last character
 *		of the extended return type dimension
 * @param exceptionTypes - a list of the exception types
 * @param exceptionTypeStarts - a list of source positions corresponding to the first
 *		character of the respective exception types
 * @param exceptionTypeEnds - a list of source positions corresponding to the last
 *		character of the respective exception types
 * @param bodyStart - a source position corresponding to the start of this 
 *		constructor's body
 */
protected void enterAbstractMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
	char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, 
	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, 
	int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, 
	int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, 
	int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, 
	int[] exceptionTypeEnds, int bodyStart, boolean isConstructor) {
	int[] sourceRange = {declarationStart, -1}; // will be fixed up on exit
	int[] nameRange = {nameStart, nameEnd};
	int[] commentRange = {-1, -1};
	if (javaDocPositions != null) {
		int length = javaDocPositions.length;
		commentRange[0] = javaDocPositions[length - 2]; // get last javadoc comment (see bug 68772)
		commentRange[1] = javaDocPositions[length - 1];
	}
	int[] modifiersRange = {-1, -1};
	if (modifiersStart > -1) {
		modifiersRange[0] = modifiersStart;
		if (isConstructor) {
			modifiersRange[1] = nameStart - 1;
		} else {
			modifiersRange[1] = returnTypeStart - 1;
		}
	}
	int[] returnTypeRange = null;
	
	if (extendedReturnTypeDimensionCount > 0)
		returnTypeRange = new int[] {returnTypeStart, returnTypeEnd, 
			parametersEnd + 1, extendedReturnTypeDimensionEnd};
	else
		returnTypeRange = new int[] {returnTypeStart, returnTypeEnd};
	int[] parameterRange = {nameEnd + 1, parametersEnd};
	int[] exceptionRange = {-1, -1};
	if (exceptionTypes != null && exceptionTypes.length > 0) {
		int exceptionCount = exceptionTypes.length;
		exceptionRange[0] = exceptionTypeStarts[0];
		exceptionRange[1] = exceptionTypeEnds[exceptionCount - 1];
	}
	int[] bodyRange = null;
	if (exceptionRange[1] > -1) {
		bodyRange = new int[] {exceptionRange[1] + 1, -1}; // will be fixed up on exit
	} else {
		bodyRange = new int[] {parametersEnd + 1, -1};
	}
	fNode = new DOMMethod(fDocument, sourceRange, CharOperation.charToString(name), nameRange, commentRange, modifiers, 
		modifiersRange, isConstructor, CharOperation.charToString(returnType), returnTypeRange,
		CharOperation.charArrayToStringArray(parameterTypes),
		CharOperation.charArrayToStringArray(parameterNames), 
		parameterRange, CharOperation.charArrayToStringArray(exceptionTypes), exceptionRange, bodyRange);
	addChild(fNode);
	fStack.push(fNode);
}
/**
 * @see IDocumentElementRequestor#enterClass(
	int declarationStart,
	int[] javaDocPositions,
	int modifiers,
	int modifiersStart,
	int classStart, 
	char[] name,
	int nameStart,
	int nameEnd,
	char[] superclass,
	int superclassStart,
	int superclassEnd,
	char[][] superinterfaces,
	int[] superinterfaceStarts,
	int[] superinterfaceEnds,
	int bodyStart)
 */
public void enterClass(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, 
	char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart, 
	int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, 
	int[] superinterfaceEnds, int bodyStart) {

	enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
		name, nameStart, nameEnd, superclass, superclassStart, 
		superclassEnd, superinterfaces, superinterfaceStarts, 
		superinterfaceEnds, bodyStart, true);
}
/**
 * @see IDocumentElementRequestor#enterConstructor(
	int declarationStart,
	int[] javaDocPositions,	
	int modifiers,
	int modifiersStart, 
	char[] name,
	int nameStart,
	int nameEnd,
	char[][] parameterTypes,
	int [] parameterTypeStarts,
	int [] parameterTypeEnds,			
	char[][] parameterNames,
	int [] parameterNameStarts,
	int [] parameterNameEnds,
	int parametersEnd,	
	char[][] exceptionTypes,
	int [] exceptionTypeStarts,
	int [] exceptionTypeEnds,
	int bodyStart)
 */
public void enterConstructor(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, 
	int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames, 
	int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd, 
	char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds, 
	int bodyStart) {
		
	/* see 1FVIIQZ */
	String nameString = new String(fDocument, nameStart, nameEnd - nameStart);
	int openParenPosition = nameString.indexOf('(');
	if (openParenPosition > -1)
		nameEnd = nameStart + openParenPosition - 1;
		
	enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart, 
		null, -1, -1, 0, 
		name, nameStart, nameEnd, parameterTypes, parameterTypeStarts, 
		parameterTypeEnds, parameterNames, parameterNameStarts, 
		parameterNameEnds, parametersEnd, 0, 
		-1, exceptionTypes, exceptionTypeStarts, 
		exceptionTypeEnds, bodyStart,true);
}
/**
 * @see IDocumentElementRequestor#enterField(
	int declarationStart,
	int[] javaDocPositions,	
	int modifiers,
	int modifiersStart,
	char[] type,
	int typeStart,
	int typeEnd,
 	int typeDimensionCount,
	char[] name,
	int nameStart,
	int nameEnd,
	int extendedTypeDimensionCount,
	int extendedTypeDimensionEnd)
 */
public void enterField(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
	char[] type, int typeStart, int typeEnd, int typeDimensionCount, char[] name, 
	int nameStart, int nameEnd, int extendedTypeDimensionCount, 
	int extendedTypeDimensionEnd) {
	int[] sourceRange = {declarationStart, 
		(extendedTypeDimensionEnd > nameEnd) ? extendedTypeDimensionEnd : nameEnd};
	int[] nameRange = {nameStart, nameEnd};
	int[] commentRange = {-1, -1};
		if (javaDocPositions != null) {
			int length = javaDocPositions.length;
			commentRange[0] = javaDocPositions[length - 2]; // get last javadoc comment (see bug 68772)
			commentRange[1] = javaDocPositions[length - 1];
		}
	int[] modifiersRange = {-1, -1};
	if (modifiersStart > -1) {
		modifiersRange[0] = modifiersStart;
		modifiersRange[1] = typeStart - 1;
	}
	int[] typeRange = {typeStart, typeEnd};
	boolean hasInitializer = false; // fixed on exitField
	int[] initializerRange = {-1, -1}; // fixed on exitField
	boolean isVariableDeclarator = false;
	if (fNode instanceof DOMField) {
		DOMField field = (DOMField)fNode;
		if (field.fTypeRange[0] == typeStart)
			isVariableDeclarator = true;
	}	
	fNode = new DOMField(fDocument, sourceRange, CharOperation.charToString(name), nameRange, commentRange, 
		modifiers, modifiersRange, typeRange, CharOperation.charToString(type), hasInitializer, 
		initializerRange, isVariableDeclarator);
	addChild(fNode);
	fStack.push(fNode);
}
/**
 * @see IDocumentElementRequestor#enterInterface(
	int declarationStart,
	int[] javaDocPositions,	
	int modifiers,
	int modifiersStart,
	int interfaceStart,
	char[] name,
	int nameStart,
	int nameEnd,
	char[][] superinterfaces,
	int[] superinterfaceStarts,
	int[] superinterfaceEnds,
	int bodyStart)
 */
public void enterInterface(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart,
	char[] name, int nameStart, int nameEnd, char[][] superinterfaces, 
	int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) {

	enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
		name, nameStart, nameEnd, null, -1, -1, superinterfaces, 
		superinterfaceStarts, superinterfaceEnds, bodyStart, false);
}
/**
 * @see IDocumentElementRequestor#enterMethod(
	int declarationStart,
	int[] javaDocPositions,	
	int modifiers,
	int modifiersStart, 
	char[] returnType,
	int returnTypeStart,
	int returnTypeEnd,
 	int returnTypeDimensionCount,
	char[] name,
	int nameStart,
	int nameEnd,
	char[][] parameterTypes,
	int [] parameterTypeStarts,
	int [] parameterTypeEnds,			
	char[][] parameterNames,
	int [] parameterNameStarts,
	int [] parameterNameEnds,
	int parametersEnd,
	int extendedReturnTypeDimensionCount,
	int extendedReturnTypeDimensionEnd,	
	char[][] exceptionTypes,
	int [] exceptionTypeStarts,
	int [] exceptionTypeEnds,
	int bodyStart)
 */
public void enterMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
	char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, 
	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, 
	int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, 
	int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, 
	int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, 
	int[] exceptionTypeEnds, int bodyStart) {
	enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart, 
		returnType, returnTypeStart, returnTypeEnd, returnTypeDimensionCount, 
		name, nameStart, nameEnd, parameterTypes, parameterTypeStarts, 
		parameterTypeEnds, parameterNames, parameterNameStarts, 
		parameterNameEnds, parametersEnd, extendedReturnTypeDimensionCount, 
		extendedReturnTypeDimensionEnd, exceptionTypes, exceptionTypeStarts, 
		exceptionTypeEnds, bodyStart,false);
}

protected void enterType(int declarationStart, int[] javaDocPositions, 
	int modifiers, int modifiersStart, int keywordStart, char[] name, 
	int nameStart, int nameEnd, char[] superclass, int superclassStart, 
	int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, 
	int[] superinterfaceEnds, int bodyStart, boolean isClass) {
	if (fBuildingType) {
		int[] sourceRange = {declarationStart, -1}; // will be fixed in the exit
		int[] commentRange = {-1, -1};
		if (javaDocPositions != null) {
			int length = javaDocPositions.length;
			commentRange[0] = javaDocPositions[length - 2];  // get last javadoc comment (see bug 68772)
			commentRange[1] = javaDocPositions[length - 1];
		}
		int[] modifiersRange = {-1, -1};
		if (modifiersStart > -1) {
			modifiersRange[0] = modifiersStart;
			modifiersRange[1] = (modifiersStart > -1) ? keywordStart - 1 : -1;
		}
		int[] typeKeywordRange = {keywordStart, nameStart - 1};
		int[] nameRange = new int[] {nameStart, nameEnd};
		int[] extendsKeywordRange = {-1, -1};
		int[] superclassRange = {-1, -1};
		int[] implementsKeywordRange = {-1, -1};
		int[] interfacesRange = {-1, -1};
		if (isClass) {
			if (superclass != null) {
				extendsKeywordRange[0] = nameEnd + 1;
				extendsKeywordRange[1] = superclassStart - 1;
				superclassRange[0] = superclassStart;
				superclassRange[1] = superclassEnd;
			}
			if (superinterfaces != null && superinterfaces.length > 0) {
				superclassRange[1] = superclassEnd;
				if (superclassEnd > -1) {
					implementsKeywordRange[0] = superclassEnd + 1;
				} else {
					implementsKeywordRange[0] = nameEnd + 1;
				}
				implementsKeywordRange[1] = superinterfaceStarts[0] - 1;
				interfacesRange[0] = superinterfaceStarts[0];
				interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
			}
		} else {
			if (superinterfaces != null && superinterfaces.length > 0) {
				extendsKeywordRange[0] = nameEnd + 1;
				extendsKeywordRange[1] = superinterfaceStarts[0] - 1;
				interfacesRange[0] = superinterfaceStarts[0];
				interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
			}
		}
		int[] openBodyRange = {bodyStart, -1}; // fixed by setTypeRanges(DOMNode)
		int[] closeBodyRange = {-1, -1}; // will be fixed in exit		
		fNode = new DOMType(fDocument, sourceRange, new String(name), nameRange, commentRange, 
			modifiers, modifiersRange, typeKeywordRange, superclassRange, extendsKeywordRange, 
			CharOperation.charArrayToStringArray(superinterfaces), interfacesRange,
			implementsKeywordRange, openBodyRange, 
			closeBodyRange, isClass);
		addChild(fNode);
		fStack.push(fNode);
	}
}
/**
 * Finishes the configuration of the constructors and methods.
 *
 * @param bodyEnd - a source position corresponding to the closing bracket of the method
 * @param declarationEnd - a source position corresponding to the end of the method
 *		declaration.  This can include whitespace and comments following the closing bracket.
 */
protected void exitAbstractMethod(int bodyEnd, int declarationEnd) {
	DOMMethod method = (DOMMethod) fStack.pop();
	method.setSourceRangeEnd(declarationEnd);
	method.setBodyRangeEnd(bodyEnd + 1);
	fNode = method;
	if (fBuildingSingleMember) {
		fFinishedSingleMember= true;
	}
}
/**
 * Finishes the configuration of the class DOM object which
 * was created by a previous enterClass call.
 *
 * @see IDocumentElementRequestor#exitClass(int, int)
 */
public void exitClass(int bodyEnd, int declarationEnd) {
	exitType(bodyEnd, declarationEnd);
}
/**
 * Finishes the configuration of the method DOM object which
 * was created by a previous enterConstructor call.
 *
 * @see IDocumentElementRequestor#exitConstructor(int, int)
 */
public void exitConstructor(int bodyEnd, int declarationEnd) {
	exitAbstractMethod(bodyEnd, declarationEnd);
}
/**
 * Finishes the configuration of the field DOM object which
 * was created by a previous enterField call.
 *
 * @see IDocumentElementRequestor#exitField(int, int)
 */
public void exitField(int bodyEnd, int declarationEnd) {
	DOMField field = (DOMField)fStack.pop();
	if (field.getEndPosition() < declarationEnd) {
		field.setSourceRangeEnd(declarationEnd);
		int nameEnd = field.fNameRange[1];
		if (nameEnd < bodyEnd) {
			/* see 1FVIIV8 - obtain initializer range */
			String initializer = new String(fDocument, nameEnd + 1, bodyEnd - nameEnd);
			int index = initializer.indexOf('=');
			if (index > -1) {
				field.setHasInitializer(true);
				field.setInitializerRange(nameEnd + index + 2, bodyEnd);
			}
		}
	}
	fFieldCount++;
	fNode = field;
	if (fBuildingSingleMember) {
		fFinishedSingleMember= true;
	}
}
/**
 * Finishes the configuration of the interface DOM object which
 * was created by a previous enterInterface call.
 *
 * @see IDocumentElementRequestor#exitInterface(int, int)
 */
public void exitInterface(int bodyEnd, int declarationEnd) {
	exitType(bodyEnd, declarationEnd);
}
/**
 * Finishes the configuration of the method DOM object which
 * was created by a previous enterMethod call.
 *
 * @see IDocumentElementRequestor#exitMethod(int, int)
 */
public void exitMethod(int bodyEnd, int declarationEnd) {
	exitAbstractMethod(bodyEnd, declarationEnd);
}
/**
 * Creates a new parser.
 */
protected DocumentElementParser getParser(Map settings) {
	return new DocumentElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings));
}
/**
 * Initializes the builder to create a document fragment.
 *
 * @param sourceCode - the document containing the source code to be analyzed
 * @param buildingCompilationUnit - true if a the document is being analyzed to
 *		create a compilation unit, otherwise false
 * @param buildingType - true if the document is being analyzed to create a
 *		type or compilation unit
 * @param singleMember - true if building a single member
 */
protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType, boolean singleMember) {
	super.initializeBuild(sourceCode, buildingCompilationUnit, buildingType);
	fBuildingSingleMember= singleMember;
	fFinishedSingleMember= false;

}
}
