/*******************************************************************************
 * 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 Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-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(CharOperation.subarray(fDocument, nameRange[0], nameRange[1] + 1));

	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;

}
}
