Made all bundles require a Java 1.4 EE, and backported some classescode to Java 1.4
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / SourceElementParser.java
index b7dda3f..c120843 100644 (file)
@@ -39,1297 +39,1404 @@ import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 import net.sourceforge.phpdt.internal.core.util.CommentRecorderParser;
 
 /**
- * A source element parser extracts structural and reference information
- * from a piece of source.
- *
- * also see @ISourceElementRequestor
- *
- * The structural investigation includes:
- * - the package statement
- * - import statements
- * - top-level types: package member, member types (member types of member types...)
- * - fields
- * - methods
- *
+ * A source element parser extracts structural and reference information from a
+ * piece of source.
+ * 
+ * also see
+ * 
+ * @ISourceElementRequestor
+ * 
+ * The structural investigation includes: - the package statement - import
+ * statements - top-level types: package member, member types (member types of
+ * member types...) - fields - methods
+ * 
  * If reference information is requested, then all source constructs are
  * investigated and type, field & method references are provided as well.
- *
+ * 
  * Any (parsing) problem encountered is also provided.
  */
 
-public class SourceElementParser extends CommentRecorderParser {//extends
-                                                                // UnitParser {
+public class SourceElementParser extends CommentRecorderParser {// extends
+       // UnitParser {
+
+       ISourceElementRequestor requestor;
+
+       int fieldCount;
+
+       int localIntPtr;
+
+       int lastFieldEndPosition;
+
+       ISourceType sourceType;
+
+       boolean reportReferenceInfo;
+
+       char[][] typeNames;
+
+       char[][] superTypeNames;
+
+       int nestedTypeIndex;
+
+       static final char[] JAVA_LANG_OBJECT = "java.lang.Object".toCharArray(); //$NON-NLS-1$
+
+       NameReference[] unknownRefs;
+
+       int unknownRefsCounter;
+
+       LocalDeclarationVisitor localDeclarationVisitor = null;
+
+       // CompilerOptions options;
+
+       /**
+        * An ast visitor that visits local type declarations.
+        */
+       public class LocalDeclarationVisitor extends ASTVisitor {
+               public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+                       notifySourceElementRequestor(typeDeclaration, sourceType == null);
+                       return false; // don't visit members as this was done during
+                                                       // notifySourceElementRequestor(...)
+               }
+
+               public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
+                       notifySourceElementRequestor(typeDeclaration, sourceType == null);
+                       return false; // don't visit members as this was done during
+                                                       // notifySourceElementRequestor(...)
+               }
+
+       }
+
+       public SourceElementParser(final ISourceElementRequestor requestor,
+                       IProblemFactory problemFactory, CompilerOptions options) {
+               // we want to notify all syntax error with the acceptProblem API
+               // To do so, we define the record method of the ProblemReporter
+               super(new ProblemReporter(DefaultErrorHandlingPolicies
+                               .exitAfterAllProblems(), options, problemFactory) {
+                       public void record(IProblem problem, CompilationResult unitResult,
+                                       ReferenceContext referenceContext) {
+                               unitResult.record(problem, referenceContext);
+                               if (requestor != null) {
+                                       requestor.acceptProblem(problem);
+                               }
+                       }
+               });
+               // true);
+               // options.sourceLevel >= CompilerOptions.JDK1_4);
+               this.requestor = requestor;
+               typeNames = new char[4][];
+               superTypeNames = new char[4][];
+               nestedTypeIndex = 0;
+               this.options = options;
+       }
+
+       /**
+        * @deprecated use SourceElementParser(ISourceElementRequestor,
+        *             IProblemFactory, CompilerOptions)
+        */
+       public SourceElementParser(final ISourceElementRequestor requestor,
+                       IProblemFactory problemFactory) {
+               this(requestor, problemFactory, new CompilerOptions());
+       }
+
+       public SourceElementParser(final ISourceElementRequestor requestor,
+                       IProblemFactory problemFactory, CompilerOptions options,
+                       boolean reportLocalDeclarations) {
+               this(requestor, problemFactory, options);
+               if (reportLocalDeclarations) {
+                       this.localDeclarationVisitor = new LocalDeclarationVisitor();
+               }
+       }
+
+       // public void checkAnnotation() {
+       // int firstCommentIndex = scanner.commentPtr;
+       //
+       // super.checkAnnotation();
+       //
+       // // modify the modifier source start to point at the first comment
+       // if (firstCommentIndex >= 0) {
+       // modifiersSourceStart = scanner.commentStarts[0];
+       // }
+       // }
+       // protected void classInstanceCreation(boolean alwaysQualified) {
+       //
+       // boolean previousFlag = reportReferenceInfo;
+       // reportReferenceInfo = false; // not to see the type reference reported in
+       // super call to getTypeReference(...)
+       // super.classInstanceCreation(alwaysQualified);
+       // reportReferenceInfo = previousFlag;
+       // if (reportReferenceInfo){
+       // AllocationExpression alloc =
+       // (AllocationExpression)expressionStack[expressionPtr];
+       // TypeReference typeRef = alloc.type;
+       // requestor.acceptConstructorReference(
+       // typeRef instanceof SingleTypeReference
+       // ? ((SingleTypeReference) typeRef).token
+       // : CharOperation.concatWith(alloc.type.getTypeName(), '.'),
+       // alloc.arguments == null ? 0 : alloc.arguments.length,
+       // alloc.sourceStart);
+       // }
+       // }
+       // protected void consumeConstructorHeaderName() {
+       // // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
+       //
+       // /* recovering - might be an empty message send */
+       // if (currentElement != null){
+       // if (lastIgnoredToken == TokenNamenew){ // was an allocation expression
+       // lastCheckPoint = scanner.startPosition; // force to restart at this exact
+       // position
+       // restartRecovery = true;
+       // return;
+       // }
+       // }
+       // SourceConstructorDeclaration cd = new
+       // SourceConstructorDeclaration(this.compilationUnit.compilationResult);
+       //
+       // //name -- this is not really revelant but we do .....
+       // cd.selector = identifierStack[identifierPtr];
+       // long selectorSourcePositions = identifierPositionStack[identifierPtr--];
+       // identifierLengthPtr--;
+       //
+       // //modifiers
+       // cd.declarationSourceStart = intStack[intPtr--];
+       // cd.modifiers = intStack[intPtr--];
+       //
+       // //highlight starts at the selector starts
+       // cd.sourceStart = (int) (selectorSourcePositions >>> 32);
+       // cd.selectorSourceEnd = (int) selectorSourcePositions;
+       // pushOnAstStack(cd);
+       //
+       // cd.sourceEnd = lParenPos;
+       // cd.bodyStart = lParenPos+1;
+       // listLength = 0; // initialize listLength before reading parameters/throws
+       //
+       // // recovery
+       // if (currentElement != null){
+       // lastCheckPoint = cd.bodyStart;
+       // if ((currentElement instanceof RecoveredType && lastIgnoredToken !=
+       // TokenNameDOT)
+       // || cd.modifiers != 0){
+       // currentElement = currentElement.add(cd, 0);
+       // lastIgnoredToken = -1;
+       // }
+       // }
+       // }
+       // /**
+       // *
+       // * INTERNAL USE-ONLY
+       // */
+       // protected void consumeExitVariableWithInitialization() {
+       // // ExitVariableWithInitialization ::= $empty
+       // // the scanner is located after the comma or the semi-colon.
+       // // we want to include the comma or the semi-colon
+       // super.consumeExitVariableWithInitialization();
+       // if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) &&
+       // (currentToken != TokenNameSEMICOLON)))
+       // return;
+       // ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition =
+       // scanner.currentPosition - 1;
+       // }
+       // protected void consumeExitVariableWithoutInitialization() {
+       // // ExitVariableWithoutInitialization ::= $empty
+       // // do nothing by default
+       // super.consumeExitVariableWithoutInitialization();
+       // if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) &&
+       // (currentToken != TokenNameSEMICOLON)))
+       // return;
+       // ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition =
+       // scanner.currentPosition - 1;
+       // }
+       // /**
+       // *
+       // * INTERNAL USE-ONLY
+       // */
+       // protected void consumeFieldAccess(boolean isSuperAccess) {
+       // // FieldAccess ::= Primary '.' 'Identifier'
+       // // FieldAccess ::= 'super' '.' 'Identifier'
+       // super.consumeFieldAccess(isSuperAccess);
+       // FieldReference fr = (FieldReference) expressionStack[expressionPtr];
+       // if (reportReferenceInfo) {
+       // requestor.acceptFieldReference(fr.token, fr.sourceStart);
+       // }
+       // }
+       // protected void consumeMethodHeaderName() {
+       // // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+       // SourceMethodDeclaration md = new
+       // SourceMethodDeclaration(this.compilationUnit.compilationResult);
+       //
+       // //name
+       // md.selector = identifierStack[identifierPtr];
+       // long selectorSourcePositions = identifierPositionStack[identifierPtr--];
+       // identifierLengthPtr--;
+       // //type
+       // md.returnType = getTypeReference(intStack[intPtr--]);
+       // //modifiers
+       // md.declarationSourceStart = intStack[intPtr--];
+       // md.modifiers = intStack[intPtr--];
+       //
+       // //highlight starts at selector start
+       // md.sourceStart = (int) (selectorSourcePositions >>> 32);
+       // md.selectorSourceEnd = (int) selectorSourcePositions;
+       // pushOnAstStack(md);
+       // md.sourceEnd = lParenPos;
+       // md.bodyStart = lParenPos+1;
+       // listLength = 0; // initialize listLength before reading parameters/throws
+       //      
+       // // recovery
+       // if (currentElement != null){
+       // if (currentElement instanceof RecoveredType
+       // //|| md.modifiers != 0
+       // || (scanner.getLineNumber(md.returnType.sourceStart)
+       // == scanner.getLineNumber(md.sourceStart))){
+       // lastCheckPoint = md.bodyStart;
+       // currentElement = currentElement.add(md, 0);
+       // lastIgnoredToken = -1;
+       // } else {
+       // lastCheckPoint = md.sourceStart;
+       // restartRecovery = true;
+       // }
+       // }
+       // }
+       // /**
+       // *
+       // * INTERNAL USE-ONLY
+       // */
+       // protected void consumeMethodInvocationName() {
+       // // MethodInvocation ::= Name '(' ArgumentListopt ')'
+       //
+       // // when the name is only an identifier...we have a message send to "this"
+       // (implicit)
+       // super.consumeMethodInvocationName();
+       // MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
+       // Expression[] args = messageSend.arguments;
+       // if (reportReferenceInfo) {
+       // requestor.acceptMethodReference(
+       // messageSend.selector,
+       // args == null ? 0 : args.length,
+       // (int)(messageSend.nameSourcePosition >>> 32));
+       // }
+       // }
+       // /**
+       // *
+       // * INTERNAL USE-ONLY
+       // */
+       // protected void consumeMethodInvocationPrimary() {
+       // super.consumeMethodInvocationPrimary();
+       // MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
+       // Expression[] args = messageSend.arguments;
+       // if (reportReferenceInfo) {
+       // requestor.acceptMethodReference(
+       // messageSend.selector,
+       // args == null ? 0 : args.length,
+       // (int)(messageSend.nameSourcePosition >>> 32));
+       // }
+       // }
+       // /**
+       // *
+       // * INTERNAL USE-ONLY
+       // */
+       // protected void consumeMethodInvocationSuper() {
+       // // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
+       // super.consumeMethodInvocationSuper();
+       // MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
+       // Expression[] args = messageSend.arguments;
+       // if (reportReferenceInfo) {
+       // requestor.acceptMethodReference(
+       // messageSend.selector,
+       // args == null ? 0 : args.length,
+       // (int)(messageSend.nameSourcePosition >>> 32));
+       // }
+       // }
+       // protected void consumeSingleTypeImportDeclarationName() {
+       // // SingleTypeImportDeclarationName ::= 'import' Name
+       // /* push an ImportRef build from the last name
+       // stored in the identifier stack. */
+       //
+       // super.consumeSingleTypeImportDeclarationName();
+       // ImportReference impt = (ImportReference)astStack[astPtr];
+       // if (reportReferenceInfo) {
+       // requestor.acceptTypeReference(impt.tokens, impt.sourceStart,
+       // impt.sourceEnd);
+       // }
+       // }
+       // protected void consumeTypeImportOnDemandDeclarationName() {
+       // // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
+       // /* push an ImportRef build from the last name
+       // stored in the identifier stack. */
+       //
+       // super.consumeTypeImportOnDemandDeclarationName();
+       // ImportReference impt = (ImportReference)astStack[astPtr];
+       // if (reportReferenceInfo) {
+       // requestor.acceptUnknownReference(impt.tokens, impt.sourceStart,
+       // impt.sourceEnd);
+       // }
+       // }
+       // protected FieldDeclaration createFieldDeclaration(Expression
+       // initialization, char[] name, int sourceStart, int sourceEnd) {
+       // return new SourceFieldDeclaration(null, name, sourceStart, sourceEnd);
+       // }
+       // protected CompilationUnitDeclaration endParse(int act) {
+       // if (sourceType != null) {
+       // if (sourceType.isInterface()) {
+       // consumeInterfaceDeclaration();
+       // } else {
+       // consumeClassDeclaration();
+       // }
+       // }
+       // if (compilationUnit != null) {
+       // CompilationUnitDeclaration result = super.endParse(act);
+       // return result;
+       // } else {
+       // return null;
+       // }
+       // }
+       /*
+        * Flush annotations defined prior to a given positions.
+        * 
+        * Note: annotations are stacked in syntactical order
+        * 
+        * Either answer given <position>, or the end position of a comment line
+        * immediately following the <position> (same line)
+        * 
+        * e.g. void foo(){ } // end of method foo
+        */
+       // 
+       // public int flushAnnotationsDefinedPriorTo(int position) {
+       //
+       // return lastFieldEndPosition =
+       // super.flushAnnotationsDefinedPriorTo(position);
+       // }
+       // public TypeReference getTypeReference(int dim) {
+       // /* build a Reference on a variable that may be qualified or not
+       // * This variable is a type reference and dim will be its dimensions
+       // */
+       // int length;
+       // if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
+       // // single variable reference
+       // if (dim == 0) {
+       // SingleTypeReference ref =
+       // new SingleTypeReference(
+       // identifierStack[identifierPtr],
+       // identifierPositionStack[identifierPtr--]);
+       // if (reportReferenceInfo) {
+       // requestor.acceptTypeReference(ref.token, ref.sourceStart);
+       // }
+       // return ref;
+       // } else {
+       // ArrayTypeReference ref =
+       // new ArrayTypeReference(
+       // identifierStack[identifierPtr],
+       // dim,
+       // identifierPositionStack[identifierPtr--]);
+       // ref.sourceEnd = endPosition;
+       // if (reportReferenceInfo) {
+       // requestor.acceptTypeReference(ref.token, ref.sourceStart);
+       // }
+       // return ref;
+       // }
+       // } else {
+       // if (length < 0) { //flag for precompiled type reference on base types
+       // TypeReference ref = TypeReference.baseTypeReference(-length, dim);
+       // ref.sourceStart = intStack[intPtr--];
+       // if (dim == 0) {
+       // ref.sourceEnd = intStack[intPtr--];
+       // } else {
+       // intPtr--; // no need to use this position as it is an array
+       // ref.sourceEnd = endPosition;
+       // }
+       // if (reportReferenceInfo){
+       // requestor.acceptTypeReference(ref.getTypeName(), ref.sourceStart,
+       // ref.sourceEnd);
+       // }
+       // return ref;
+       // } else { //Qualified variable reference
+       // char[][] tokens = new char[length][];
+       // identifierPtr -= length;
+       // long[] positions = new long[length];
+       // System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
+       // System.arraycopy(
+       // identifierPositionStack,
+       // identifierPtr + 1,
+       // positions,
+       // 0,
+       // length);
+       // if (dim == 0) {
+       // QualifiedTypeReference ref = new QualifiedTypeReference(tokens,
+       // positions);
+       // if (reportReferenceInfo) {
+       // requestor.acceptTypeReference(ref.tokens, ref.sourceStart,
+       // ref.sourceEnd);
+       // }
+       // return ref;
+       // } else {
+       // ArrayQualifiedTypeReference ref =
+       // new ArrayQualifiedTypeReference(tokens, dim, positions);
+       // ref.sourceEnd = endPosition;
+       // if (reportReferenceInfo) {
+       // requestor.acceptTypeReference(ref.tokens, ref.sourceStart,
+       // ref.sourceEnd);
+       // }
+       // return ref;
+       // }
+       // }
+       // }
+       // }
+       // public NameReference getUnspecifiedReference() {
+       // /* build a (unspecified) NameReference which may be qualified*/
+       //
+       // int length;
+       // if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
+       // // single variable reference
+       // SingleNameReference ref =
+       // new SingleNameReference(
+       // identifierStack[identifierPtr],
+       // identifierPositionStack[identifierPtr--]);
+       // if (reportReferenceInfo) {
+       // this.addUnknownRef(ref);
+       // }
+       // return ref;
+       // } else {
+       // //Qualified variable reference
+       // char[][] tokens = new char[length][];
+       // identifierPtr -= length;
+       // System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
+       // QualifiedNameReference ref =
+       // new QualifiedNameReference(
+       // tokens,
+       // (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
+       // (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
+       // if (reportReferenceInfo) {
+       // this.addUnknownRef(ref);
+       // }
+       // return ref;
+       // }
+       // }
+       // public NameReference getUnspecifiedReferenceOptimized() {
+       // /* build a (unspecified) NameReference which may be qualified
+       // The optimization occurs for qualified reference while we are
+       // certain in this case the last item of the qualified name is
+       // a field access. This optimization is IMPORTANT while it results
+       // that when a NameReference is build, the type checker should always
+       // look for that it is not a type reference */
+       //
+       // int length;
+       // if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
+       // // single variable reference
+       // SingleNameReference ref =
+       // new SingleNameReference(
+       // identifierStack[identifierPtr],
+       // identifierPositionStack[identifierPtr--]);
+       // ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+       // ref.bits |= LOCAL | FIELD;
+       // if (reportReferenceInfo) {
+       // this.addUnknownRef(ref);
+       // }
+       // return ref;
+       // }
+       //
+       // //Qualified-variable-reference
+       // //In fact it is variable-reference DOT field-ref , but it would result in
+       // a
+       // type
+       // //conflict tha can be only reduce by making a superclass (or inetrface )
+       // between
+       // //nameReference and FiledReference or putting FieldReference under
+       // NameReference
+       // //or else..........This optimisation is not really relevant so just leave
+       // as it is
+       //
+       // char[][] tokens = new char[length][];
+       // identifierPtr -= length;
+       // System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
+       // QualifiedNameReference ref =
+       // new QualifiedNameReference(
+       // tokens,
+       // (int) (identifierPositionStack[identifierPtr + 1] >> 32),
+       // // sourceStart
+       // (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
+       // ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+       // ref.bits |= LOCAL | FIELD;
+       // if (reportReferenceInfo) {
+       // this.addUnknownRef(ref);
+       // }
+       // return ref;
+       // }
+       // /**
+       // *
+       // * INTERNAL USE-ONLY
+       // */
+       // private boolean isLocalDeclaration() {
+       // int nestedDepth = nestedType;
+       // while (nestedDepth >= 0) {
+       // if (nestedMethod[nestedDepth] != 0) {
+       // return true;
+       // }
+       // nestedDepth--;
+       // }
+       // return false;
+       // }
+       /*
+        * Update the bodyStart of the corresponding parse node
+        */
+       public void notifySourceElementRequestor(
+                       CompilationUnitDeclaration parsedUnit) {
+               if (parsedUnit == null) {
+                       // when we parse a single type member declaration the compilation
+                       // unit is
+                       // null, but we still
+                       // want to be able to notify the requestor on the created ast node
+                       if (astStack[0] instanceof AbstractMethodDeclaration) {
+                               notifySourceElementRequestor((AbstractMethodDeclaration) astStack[0]);
+                               return;
+                       }
+                       return;
+               }
+               // range check
+               boolean isInRange = scanner.initialPosition <= parsedUnit.sourceStart
+                               && scanner.eofPosition >= parsedUnit.sourceEnd;
+
+               // if (reportReferenceInfo) {
+               // notifyAllUnknownReferences();
+               // }
+               // collect the top level ast nodes
+               int length = 0;
+               ASTNode[] nodes = null;
+               if (sourceType == null) {
+                       if (isInRange) {
+                               requestor.enterCompilationUnit();
+                       }
+                       // ImportReference currentPackage = parsedUnit.currentPackage;
+                       ImportReference[] imports = parsedUnit.imports;
+                       // TypeDeclaration[] types = parsedUnit.types;
+                       ArrayList types = parsedUnit.types;
+                       if (types != null) {
+                               // length =
+                               // (currentPackage == null ? 0 : 1)
+                               // + (imports == null ? 0 : imports.length)
+                               // + (types == null ? 0 : types.length);
+                               // nodes = new ASTNode[length];
+                               length = (imports == null ? 0 : imports.length) + types.size();
+                               nodes = new ASTNode[length];
+                               int index = 0;
+                               // if (currentPackage != null) {
+                               // nodes[index++] = currentPackage;
+                               // }
+                               if (imports != null) {
+                                       for (int i = 0, max = imports.length; i < max; i++) {
+                                               nodes[index++] = imports[i];
+                                       }
+                               }
+
+                               for (int i = 0, max = types.size(); i < max; i++) {
+                                       nodes[index++] = (ASTNode) types.get(i);
+                               }
+                       }
+               } else {
+                       // TypeDeclaration[] types = parsedUnit.types;
+                       ArrayList types = parsedUnit.types;
+                       if (types != null) {
+                               length = types.size();
+                               nodes = new ASTNode[length];
+                               for (int i = 0, max = types.size(); i < max; i++) {
+                                       nodes[i] = (ASTNode) types.get(i);
+                               }
+                       }
+               }
+
+               // notify the nodes in the syntactical order
+               if (nodes != null && length > 0) {
+                       quickSort(nodes, 0, length - 1);
+                       for (int i = 0; i < length; i++) {
+                               ASTNode node = nodes[i];
+                               if (node instanceof ImportReference) {
+                                       ImportReference importRef = (ImportReference) node;
+                                       // if (node == parsedUnit.currentPackage) {
+                                       // notifySourceElementRequestor(importRef, true);
+                                       // } else {
+                                       notifySourceElementRequestor(importRef, false);
+                                       // }
+                               } // else { instanceof TypeDeclaration
+                               if (node instanceof TypeDeclaration) {
+                                       notifySourceElementRequestor((TypeDeclaration) node,
+                                                       sourceType == null);
+                                       // notifySourceElementRequestor((CompilationUnitDeclaration)node,
+                                       // sourceType == null);
+                               }
+                               // jsurfer - INSERT start
+                               if (node instanceof AbstractMethodDeclaration) {
+                                       notifySourceElementRequestor((AbstractMethodDeclaration) node);
+                               }
+                               // jsurfer - INSERT end
+                       }
+               }
 
-  ISourceElementRequestor requestor;
-  int fieldCount;
-  int localIntPtr;
-  int lastFieldEndPosition;
-  ISourceType sourceType;
-  boolean reportReferenceInfo;
-  char[][] typeNames;
-  char[][] superTypeNames;
-  int nestedTypeIndex;
-  static final char[] JAVA_LANG_OBJECT = "java.lang.Object".toCharArray(); //$NON-NLS-1$
-  NameReference[] unknownRefs;
-  int unknownRefsCounter;
-  LocalDeclarationVisitor localDeclarationVisitor = null;
-  //   CompilerOptions options;
+               if (sourceType == null) {
+                       if (isInRange) {
+                               requestor.exitCompilationUnit(parsedUnit.sourceEnd);
+                       }
+               }
+       }
 
-  /**
-   * An ast visitor that visits local type declarations.
-   */
-  public class LocalDeclarationVisitor extends ASTVisitor {
-       public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
-               notifySourceElementRequestor(typeDeclaration, sourceType == null);
-               return false; // don't visit members as this was done during notifySourceElementRequestor(...)
-       }
-       public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
-               notifySourceElementRequestor(typeDeclaration, sourceType == null);
-               return false; // don't visit members as this was done during notifySourceElementRequestor(...)
-       }
-       
-  }
+       // private void notifyAllUnknownReferences() {
+       // for (int i = 0, max = this.unknownRefsCounter; i < max; i++) {
+       // NameReference nameRef = this.unknownRefs[i];
+       // if ((nameRef.bits & BindingIds.VARIABLE) != 0) {
+       // if ((nameRef.bits & BindingIds.TYPE) == 0) {
+       // // variable but not type
+       // if (nameRef instanceof SingleNameReference) {
+       // // local var or field
+       // requestor.acceptUnknownReference(((SingleNameReference) nameRef).token,
+       // nameRef.sourceStart);
+       // } else {
+       // // QualifiedNameReference
+       // // The last token is a field reference and the previous tokens are a
+       // type/variable references
+       // char[][] tokens = ((QualifiedNameReference) nameRef).tokens;
+       // int tokensLength = tokens.length;
+       // requestor.acceptFieldReference(tokens[tokensLength - 1],
+       // nameRef.sourceEnd
+       // - tokens[tokensLength - 1].length + 1);
+       // char[][] typeRef = new char[tokensLength - 1][];
+       // System.arraycopy(tokens, 0, typeRef, 0, tokensLength - 1);
+       // requestor.acceptUnknownReference(typeRef, nameRef.sourceStart,
+       // nameRef.sourceEnd - tokens[tokensLength - 1].length);
+       // }
+       // } else {
+       // // variable or type
+       // if (nameRef instanceof SingleNameReference) {
+       // requestor.acceptUnknownReference(((SingleNameReference) nameRef).token,
+       // nameRef.sourceStart);
+       // } else {
+       // //QualifiedNameReference
+       // requestor.acceptUnknownReference(((QualifiedNameReference)
+       // nameRef).tokens,
+       // nameRef.sourceStart, nameRef.sourceEnd);
+       // }
+       // }
+       // } else if ((nameRef.bits & BindingIds.TYPE) != 0) {
+       // if (nameRef instanceof SingleNameReference) {
+       // requestor.acceptTypeReference(((SingleNameReference) nameRef).token,
+       // nameRef.sourceStart);
+       // } else {
+       // // it is a QualifiedNameReference
+       // requestor.acceptTypeReference(((QualifiedNameReference) nameRef).tokens,
+       // nameRef.sourceStart, nameRef.sourceEnd);
+       // }
+       // }
+       // }
+       // }
+       /*
+        * Update the bodyStart of the corresponding parse node
+        */
+       public void notifySourceElementRequestor(
+                       AbstractMethodDeclaration methodDeclaration) {
 
-  public SourceElementParser(final ISourceElementRequestor requestor, IProblemFactory problemFactory, CompilerOptions options) {
-    // we want to notify all syntax error with the acceptProblem API
-    // To do so, we define the record method of the ProblemReporter
-    super( new ProblemReporter(DefaultErrorHandlingPolicies.exitAfterAllProblems(), options, problemFactory) {
-      public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) {
-        unitResult.record(problem, referenceContext);
-        if (requestor!=null) {
-          requestor.acceptProblem(problem);
-        }
-      }
-    });
-    // true);
-    // options.sourceLevel >= CompilerOptions.JDK1_4);
-    this.requestor = requestor;
-    typeNames = new char[4][];
-    superTypeNames = new char[4][];
-    nestedTypeIndex = 0;
-    this.options = options;
-  }
+               // range check
+               boolean isInRange = scanner.initialPosition <= methodDeclaration.declarationSourceStart
+                               && scanner.eofPosition >= methodDeclaration.declarationSourceEnd;
 
-  /**
-   * @deprecated use SourceElementParser(ISourceElementRequestor,
-   *             IProblemFactory, CompilerOptions)
-   */
-  public SourceElementParser(
-       final ISourceElementRequestor requestor,
-       IProblemFactory problemFactory) {
-               this(requestor, problemFactory, new CompilerOptions());
-  }
-  public SourceElementParser(
-       final ISourceElementRequestor requestor,
-       IProblemFactory problemFactory,
-       CompilerOptions options,
-       boolean reportLocalDeclarations) {
-               this(requestor, problemFactory, options);
-               if (reportLocalDeclarations) {
-                       this.localDeclarationVisitor = new LocalDeclarationVisitor();
-               }
-  }
-  //public void checkAnnotation() {
-  //   int firstCommentIndex = scanner.commentPtr;
-  //
-  //   super.checkAnnotation();
-  //
-  //   // modify the modifier source start to point at the first comment
-  //   if (firstCommentIndex >= 0) {
-  //           modifiersSourceStart = scanner.commentStarts[0];
-  //   }
-  //}
-  //protected void classInstanceCreation(boolean alwaysQualified) {
-  //
-  //   boolean previousFlag = reportReferenceInfo;
-  //   reportReferenceInfo = false; // not to see the type reference reported in
-  // super call to getTypeReference(...)
-  //   super.classInstanceCreation(alwaysQualified);
-  //   reportReferenceInfo = previousFlag;
-  //   if (reportReferenceInfo){
-  //           AllocationExpression alloc =
-  // (AllocationExpression)expressionStack[expressionPtr];
-  //           TypeReference typeRef = alloc.type;
-  //           requestor.acceptConstructorReference(
-  //                   typeRef instanceof SingleTypeReference
-  //                           ? ((SingleTypeReference) typeRef).token
-  //                           : CharOperation.concatWith(alloc.type.getTypeName(), '.'),
-  //                   alloc.arguments == null ? 0 : alloc.arguments.length,
-  //                   alloc.sourceStart);
-  //   }
-  //}
-  //protected void consumeConstructorHeaderName() {
-  //   // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
-  //
-  //   /* recovering - might be an empty message send */
-  //   if (currentElement != null){
-  //           if (lastIgnoredToken == TokenNamenew){ // was an allocation expression
-  //                   lastCheckPoint = scanner.startPosition; // force to restart at this exact
-  // position
-  //                   restartRecovery = true;
-  //                   return;
-  //           }
-  //   }
-  //   SourceConstructorDeclaration cd = new
-  // SourceConstructorDeclaration(this.compilationUnit.compilationResult);
-  //
-  //   //name -- this is not really revelant but we do .....
-  //   cd.selector = identifierStack[identifierPtr];
-  //   long selectorSourcePositions = identifierPositionStack[identifierPtr--];
-  //   identifierLengthPtr--;
-  //
-  //   //modifiers
-  //   cd.declarationSourceStart = intStack[intPtr--];
-  //   cd.modifiers = intStack[intPtr--];
-  //
-  //   //highlight starts at the selector starts
-  //   cd.sourceStart = (int) (selectorSourcePositions >>> 32);
-  //   cd.selectorSourceEnd = (int) selectorSourcePositions;
-  //   pushOnAstStack(cd);
-  //
-  //   cd.sourceEnd = lParenPos;
-  //   cd.bodyStart = lParenPos+1;
-  //   listLength = 0; // initialize listLength before reading parameters/throws
-  //
-  //   // recovery
-  //   if (currentElement != null){
-  //           lastCheckPoint = cd.bodyStart;
-  //           if ((currentElement instanceof RecoveredType && lastIgnoredToken !=
-  // TokenNameDOT)
-  //                   || cd.modifiers != 0){
-  //                   currentElement = currentElement.add(cd, 0);
-  //                   lastIgnoredToken = -1;
-  //           }
-  //   }
-  //}
-  ///**
-  // *
-  // * INTERNAL USE-ONLY
-  // */
-  //protected void consumeExitVariableWithInitialization() {
-  //   // ExitVariableWithInitialization ::= $empty
-  //   // the scanner is located after the comma or the semi-colon.
-  //   // we want to include the comma or the semi-colon
-  //   super.consumeExitVariableWithInitialization();
-  //   if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) &&
-  // (currentToken != TokenNameSEMICOLON)))
-  //           return;
-  //   ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition =
-  // scanner.currentPosition - 1;
-  //}
-  //protected void consumeExitVariableWithoutInitialization() {
-  //   // ExitVariableWithoutInitialization ::= $empty
-  //   // do nothing by default
-  //   super.consumeExitVariableWithoutInitialization();
-  //   if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) &&
-  // (currentToken != TokenNameSEMICOLON)))
-  //           return;
-  //   ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition =
-  // scanner.currentPosition - 1;
-  //}
-  ///**
-  // *
-  // * INTERNAL USE-ONLY
-  // */
-  //protected void consumeFieldAccess(boolean isSuperAccess) {
-  //   // FieldAccess ::= Primary '.' 'Identifier'
-  //   // FieldAccess ::= 'super' '.' 'Identifier'
-  //   super.consumeFieldAccess(isSuperAccess);
-  //   FieldReference fr = (FieldReference) expressionStack[expressionPtr];
-  //   if (reportReferenceInfo) {
-  //           requestor.acceptFieldReference(fr.token, fr.sourceStart);
-  //   }
-  //}
-  //protected void consumeMethodHeaderName() {
-  //   // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
-  //   SourceMethodDeclaration md = new
-  // SourceMethodDeclaration(this.compilationUnit.compilationResult);
-  //
-  //   //name
-  //   md.selector = identifierStack[identifierPtr];
-  //   long selectorSourcePositions = identifierPositionStack[identifierPtr--];
-  //   identifierLengthPtr--;
-  //   //type
-  //   md.returnType = getTypeReference(intStack[intPtr--]);
-  //   //modifiers
-  //   md.declarationSourceStart = intStack[intPtr--];
-  //   md.modifiers = intStack[intPtr--];
-  //
-  //   //highlight starts at selector start
-  //   md.sourceStart = (int) (selectorSourcePositions >>> 32);
-  //   md.selectorSourceEnd = (int) selectorSourcePositions;
-  //   pushOnAstStack(md);
-  //   md.sourceEnd = lParenPos;
-  //   md.bodyStart = lParenPos+1;
-  //   listLength = 0; // initialize listLength before reading parameters/throws
-  //   
-  //   // recovery
-  //   if (currentElement != null){
-  //           if (currentElement instanceof RecoveredType
-  //                   //|| md.modifiers != 0
-  //                   || (scanner.getLineNumber(md.returnType.sourceStart)
-  //                                   == scanner.getLineNumber(md.sourceStart))){
-  //                   lastCheckPoint = md.bodyStart;
-  //                   currentElement = currentElement.add(md, 0);
-  //                   lastIgnoredToken = -1;
-  //           } else {
-  //                   lastCheckPoint = md.sourceStart;
-  //                   restartRecovery = true;
-  //           }
-  //   }
-  //}
-  ///**
-  // *
-  // * INTERNAL USE-ONLY
-  // */
-  //protected void consumeMethodInvocationName() {
-  //   // MethodInvocation ::= Name '(' ArgumentListopt ')'
-  //
-  //   // when the name is only an identifier...we have a message send to "this"
-  // (implicit)
-  //   super.consumeMethodInvocationName();
-  //   MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
-  //   Expression[] args = messageSend.arguments;
-  //   if (reportReferenceInfo) {
-  //           requestor.acceptMethodReference(
-  //                   messageSend.selector,
-  //                   args == null ? 0 : args.length,
-  //                   (int)(messageSend.nameSourcePosition >>> 32));
-  //   }
-  //}
-  ///**
-  // *
-  // * INTERNAL USE-ONLY
-  // */
-  //protected void consumeMethodInvocationPrimary() {
-  //   super.consumeMethodInvocationPrimary();
-  //   MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
-  //   Expression[] args = messageSend.arguments;
-  //   if (reportReferenceInfo) {
-  //           requestor.acceptMethodReference(
-  //                   messageSend.selector,
-  //                   args == null ? 0 : args.length,
-  //                   (int)(messageSend.nameSourcePosition >>> 32));
-  //   }
-  //}
-  ///**
-  // *
-  // * INTERNAL USE-ONLY
-  // */
-  //protected void consumeMethodInvocationSuper() {
-  //   // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
-  //   super.consumeMethodInvocationSuper();
-  //   MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
-  //   Expression[] args = messageSend.arguments;
-  //   if (reportReferenceInfo) {
-  //           requestor.acceptMethodReference(
-  //                   messageSend.selector,
-  //                   args == null ? 0 : args.length,
-  //                   (int)(messageSend.nameSourcePosition >>> 32));
-  //   }
-  //}
-  //protected void consumeSingleTypeImportDeclarationName() {
-  //   // SingleTypeImportDeclarationName ::= 'import' Name
-  //   /* push an ImportRef build from the last name
-  //   stored in the identifier stack. */
-  //
-  //   super.consumeSingleTypeImportDeclarationName();
-  //   ImportReference impt = (ImportReference)astStack[astPtr];
-  //   if (reportReferenceInfo) {
-  //           requestor.acceptTypeReference(impt.tokens, impt.sourceStart,
-  // impt.sourceEnd);
-  //   }
-  //}
-  //protected void consumeTypeImportOnDemandDeclarationName() {
-  //   // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
-  //   /* push an ImportRef build from the last name
-  //   stored in the identifier stack. */
-  //
-  //   super.consumeTypeImportOnDemandDeclarationName();
-  //   ImportReference impt = (ImportReference)astStack[astPtr];
-  //   if (reportReferenceInfo) {
-  //           requestor.acceptUnknownReference(impt.tokens, impt.sourceStart,
-  // impt.sourceEnd);
-  //   }
-  //}
-  //protected FieldDeclaration createFieldDeclaration(Expression
-  // initialization, char[] name, int sourceStart, int sourceEnd) {
-  //   return new SourceFieldDeclaration(null, name, sourceStart, sourceEnd);
-  //}
-  //protected CompilationUnitDeclaration endParse(int act) {
-  //   if (sourceType != null) {
-  //           if (sourceType.isInterface()) {
-  //                   consumeInterfaceDeclaration();
-  //           } else {
-  //                   consumeClassDeclaration();
-  //           }
-  //   }
-  //   if (compilationUnit != null) {
-  //           CompilationUnitDeclaration result = super.endParse(act);
-  //           return result;
-  //   } else {
-  //           return null;
-  //   }
-  //}
-  /*
-   * Flush annotations defined prior to a given positions.
-   * 
-   * Note: annotations are stacked in syntactical order
-   * 
-   * Either answer given <position>, or the end position of a comment line
-   * immediately following the <position> (same line)
-   * 
-   * e.g. void foo(){ } // end of method foo
-   */
-  // 
-  //public int flushAnnotationsDefinedPriorTo(int position) {
-  //
-  //   return lastFieldEndPosition =
-  // super.flushAnnotationsDefinedPriorTo(position);
-  //}
-  //public TypeReference getTypeReference(int dim) {
-  //   /* build a Reference on a variable that may be qualified or not
-  //    * This variable is a type reference and dim will be its dimensions
-  //    */
-  //   int length;
-  //   if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
-  //           // single variable reference
-  //           if (dim == 0) {
-  //                   SingleTypeReference ref =
-  //                           new SingleTypeReference(
-  //                                   identifierStack[identifierPtr],
-  //                                   identifierPositionStack[identifierPtr--]);
-  //                   if (reportReferenceInfo) {
-  //                           requestor.acceptTypeReference(ref.token, ref.sourceStart);
-  //                   }
-  //                   return ref;
-  //           } else {
-  //                   ArrayTypeReference ref =
-  //                           new ArrayTypeReference(
-  //                                   identifierStack[identifierPtr],
-  //                                   dim,
-  //                                   identifierPositionStack[identifierPtr--]);
-  //                   ref.sourceEnd = endPosition;
-  //                   if (reportReferenceInfo) {
-  //                           requestor.acceptTypeReference(ref.token, ref.sourceStart);
-  //                   }
-  //                   return ref;
-  //           }
-  //   } else {
-  //           if (length < 0) { //flag for precompiled type reference on base types
-  //                   TypeReference ref = TypeReference.baseTypeReference(-length, dim);
-  //                   ref.sourceStart = intStack[intPtr--];
-  //                   if (dim == 0) {
-  //                           ref.sourceEnd = intStack[intPtr--];
-  //                   } else {
-  //                           intPtr--; // no need to use this position as it is an array
-  //                           ref.sourceEnd = endPosition;
-  //                   }
-  //                   if (reportReferenceInfo){
-  //                                   requestor.acceptTypeReference(ref.getTypeName(), ref.sourceStart,
-  // ref.sourceEnd);
-  //                   }
-  //                   return ref;
-  //           } else { //Qualified variable reference
-  //                   char[][] tokens = new char[length][];
-  //                   identifierPtr -= length;
-  //                   long[] positions = new long[length];
-  //                   System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
-  //                   System.arraycopy(
-  //                           identifierPositionStack,
-  //                           identifierPtr + 1,
-  //                           positions,
-  //                           0,
-  //                           length);
-  //                   if (dim == 0) {
-  //                           QualifiedTypeReference ref = new QualifiedTypeReference(tokens, positions);
-  //                           if (reportReferenceInfo) {
-  //                                   requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd);
-  //                           }
-  //                           return ref;
-  //                   } else {
-  //                           ArrayQualifiedTypeReference ref =
-  //                                   new ArrayQualifiedTypeReference(tokens, dim, positions);
-  //                           ref.sourceEnd = endPosition;
-  //                           if (reportReferenceInfo) {
-  //                                   requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd);
-  //                           }
-  //                           return ref;
-  //                   }
-  //           }
-  //   }
-  //}
-  //public NameReference getUnspecifiedReference() {
-  //   /* build a (unspecified) NameReference which may be qualified*/
-  //
-  //   int length;
-  //   if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
-  //           // single variable reference
-  //           SingleNameReference ref =
-  //                   new SingleNameReference(
-  //                           identifierStack[identifierPtr],
-  //                           identifierPositionStack[identifierPtr--]);
-  //           if (reportReferenceInfo) {
-  //                   this.addUnknownRef(ref);
-  //           }
-  //           return ref;
-  //   } else {
-  //           //Qualified variable reference
-  //           char[][] tokens = new char[length][];
-  //           identifierPtr -= length;
-  //           System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
-  //           QualifiedNameReference ref =
-  //                   new QualifiedNameReference(
-  //                           tokens,
-  //                           (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
-  //                           (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
-  //           if (reportReferenceInfo) {
-  //                   this.addUnknownRef(ref);
-  //           }
-  //           return ref;
-  //   }
-  //}
-  //public NameReference getUnspecifiedReferenceOptimized() {
-  //   /* build a (unspecified) NameReference which may be qualified
-  //   The optimization occurs for qualified reference while we are
-  //   certain in this case the last item of the qualified name is
-  //   a field access. This optimization is IMPORTANT while it results
-  //   that when a NameReference is build, the type checker should always
-  //   look for that it is not a type reference */
-  //
-  //   int length;
-  //   if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
-  //           // single variable reference
-  //           SingleNameReference ref =
-  //                   new SingleNameReference(
-  //                           identifierStack[identifierPtr],
-  //                           identifierPositionStack[identifierPtr--]);
-  //           ref.bits &= ~ASTNode.RestrictiveFlagMASK;
-  //           ref.bits |= LOCAL | FIELD;
-  //           if (reportReferenceInfo) {
-  //                   this.addUnknownRef(ref);
-  //           }
-  //           return ref;
-  //   }
-  //
-  //   //Qualified-variable-reference
-  //   //In fact it is variable-reference DOT field-ref , but it would result in a
-  // type
-  //   //conflict tha can be only reduce by making a superclass (or inetrface )
-  // between
-  //   //nameReference and FiledReference or putting FieldReference under
-  // NameReference
-  //   //or else..........This optimisation is not really relevant so just leave
-  // as it is
-  //
-  //   char[][] tokens = new char[length][];
-  //   identifierPtr -= length;
-  //   System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
-  //   QualifiedNameReference ref =
-  //           new QualifiedNameReference(
-  //                   tokens,
-  //                   (int) (identifierPositionStack[identifierPtr + 1] >> 32),
-  //   // sourceStart
-  //    (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
-  //   ref.bits &= ~ASTNode.RestrictiveFlagMASK;
-  //   ref.bits |= LOCAL | FIELD;
-  //   if (reportReferenceInfo) {
-  //           this.addUnknownRef(ref);
-  //   }
-  //   return ref;
-  //}
-  ///**
-  // *
-  // * INTERNAL USE-ONLY
-  // */
-  //private boolean isLocalDeclaration() {
-  //   int nestedDepth = nestedType;
-  //   while (nestedDepth >= 0) {
-  //           if (nestedMethod[nestedDepth] != 0) {
-  //                   return true;
-  //           }
-  //           nestedDepth--;
-  //   }
-  //   return false;
-  //}
-  /*
-   * Update the bodyStart of the corresponding parse node
-   */
-  public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit) {
-    if (parsedUnit == null) {
-      // when we parse a single type member declaration the compilation unit is
-      // null, but we still
-      // want to be able to notify the requestor on the created ast node
-      if (astStack[0] instanceof AbstractMethodDeclaration) {
-        notifySourceElementRequestor((AbstractMethodDeclaration) astStack[0]);
-        return;
-      }
-      return;
-    }
-    // range check
-    boolean isInRange = scanner.initialPosition <= parsedUnit.sourceStart && scanner.eofPosition >= parsedUnit.sourceEnd;
+               if (methodDeclaration.isClinit()) {
+                       this.visitIfNeeded(methodDeclaration);
+                       return;
+               }
 
-    // if (reportReferenceInfo) {
-    //         notifyAllUnknownReferences();
-    // }
-    // collect the top level ast nodes
-    int length = 0;
-    ASTNode[] nodes = null;
-    if (sourceType == null) {
-      if (isInRange) {
-        requestor.enterCompilationUnit();
-      }
-      //               ImportReference currentPackage = parsedUnit.currentPackage;
-      ImportReference[] imports = parsedUnit.imports;
-      //               TypeDeclaration[] types = parsedUnit.types;
-      ArrayList types = parsedUnit.types;
-      if (types != null) {
-        //             length =
-        //                     (currentPackage == null ? 0 : 1)
-        //                     + (imports == null ? 0 : imports.length)
-        //                     + (types == null ? 0 : types.length);
-        //             nodes = new ASTNode[length];
-        length = (imports == null ? 0 : imports.length) + types.size();
-        nodes = new ASTNode[length];
-        int index = 0;
-        //             if (currentPackage != null) {
-        //                     nodes[index++] = currentPackage;
-        //             }
-        if (imports != null) {
-          for (int i = 0, max = imports.length; i < max; i++) {
-            nodes[index++] = imports[i];
-          }
-        }
+               if (methodDeclaration.isDefaultConstructor()) {
+                       if (reportReferenceInfo) {
+                               ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
+                               ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
+                               if (constructorCall != null) {
+                                       switch (constructorCall.accessMode) {
+                                       case ExplicitConstructorCall.This:
+                                               requestor.acceptConstructorReference(
+                                                               typeNames[nestedTypeIndex - 1],
+                                                               constructorCall.arguments == null ? 0
+                                                                               : constructorCall.arguments.length,
+                                                               constructorCall.sourceStart);
+                                               break;
+                                       case ExplicitConstructorCall.Super:
+                                       case ExplicitConstructorCall.ImplicitSuper:
+                                               requestor.acceptConstructorReference(
+                                                               superTypeNames[nestedTypeIndex - 1],
+                                                               constructorCall.arguments == null ? 0
+                                                                               : constructorCall.arguments.length,
+                                                               constructorCall.sourceStart);
+                                               break;
+                                       }
+                               }
+                       }
+                       return;
+               }
+               char[][] argumentTypes = null;
+               char[][] argumentNames = null;
+               Argument[] arguments = methodDeclaration.arguments;
+               if (arguments != null) {
+                       int argumentLength = arguments.length;
+                       argumentTypes = new char[argumentLength][];
+                       argumentNames = new char[argumentLength][];
+                       for (int i = 0; i < argumentLength; i++) {
+                               argumentTypes[i] = returnTypeName(arguments[i].type);
+                               argumentNames[i] = arguments[i].name;
+                       }
+               }
+               char[][] thrownExceptionTypes = null;
+               TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+               if (thrownExceptions != null) {
+                       int thrownExceptionLength = thrownExceptions.length;
+                       thrownExceptionTypes = new char[thrownExceptionLength][];
+                       for (int i = 0; i < thrownExceptionLength; i++) {
+                               thrownExceptionTypes[i] = CharOperation.concatWith(
+                                               thrownExceptions[i].getTypeName(), '.');
+                       }
+               }
+               // by default no selector end position
+               int selectorSourceEnd = -1;
+               if (methodDeclaration.isConstructor()) {
+                       // if (methodDeclaration instanceof SourceConstructorDeclaration) {
+                       // selectorSourceEnd =
+                       // ((SourceConstructorDeclaration)
+                       // methodDeclaration).selectorSourceEnd;
+                       // }
+                       if (isInRange) {
+                               requestor.enterConstructor(
+                                               methodDeclaration.declarationSourceStart,
+                                               methodDeclaration.modifiers,
+                                               methodDeclaration.selector,
+                                               methodDeclaration.sourceStart, selectorSourceEnd,
+                                               argumentTypes, argumentNames, thrownExceptionTypes);
+                       }
+                       if (reportReferenceInfo) {
+                               ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
+                               ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
+                               if (constructorCall != null) {
+                                       switch (constructorCall.accessMode) {
+                                       case ExplicitConstructorCall.This:
+                                               requestor.acceptConstructorReference(
+                                                               typeNames[nestedTypeIndex - 1],
+                                                               constructorCall.arguments == null ? 0
+                                                                               : constructorCall.arguments.length,
+                                                               constructorCall.sourceStart);
+                                               break;
+                                       case ExplicitConstructorCall.Super:
+                                       case ExplicitConstructorCall.ImplicitSuper:
+                                               requestor.acceptConstructorReference(
+                                                               superTypeNames[nestedTypeIndex - 1],
+                                                               constructorCall.arguments == null ? 0
+                                                                               : constructorCall.arguments.length,
+                                                               constructorCall.sourceStart);
+                                               break;
+                                       }
+                               }
+                       }
+                       this.visitIfNeeded(methodDeclaration);
+                       if (isInRange) {
+                               requestor
+                                               .exitConstructor(methodDeclaration.declarationSourceEnd);
+                       }
+                       return;
+               }
+               // if (methodDeclaration instanceof SourceMethodDeclaration) {
+               // selectorSourceEnd =
+               // ((SourceMethodDeclaration) methodDeclaration).selectorSourceEnd;
+               // }
+               if (isInRange) {
+                       int modifiers = methodDeclaration.modifiers;
+                       // boolean deprecated = (modifiers & AccDeprecated) != 0; //
+                       // remember
+                       // deprecation so as to not lose it below
+                       requestor
+                                       .enterMethod(
+                                                       methodDeclaration.declarationSourceStart,
+                                                       modifiers, // deprecated
+                                                       // ?
+                                                       // (modifiers
+                                                       // &
+                                                       // AccJustFlag)
+                                                       // |
+                                                       // AccDeprecated
+                                                       // :
+                                                       // modifiers
+                                                       // &
+                                                       // AccJustFlag,
+                                                       returnTypeName(((MethodDeclaration) methodDeclaration).returnType),
+                                                       methodDeclaration.selector,
+                                                       methodDeclaration.sourceStart, selectorSourceEnd,
+                                                       argumentTypes, argumentNames, thrownExceptionTypes);
+               }
+               this.visitIfNeeded(methodDeclaration);
 
-        for (int i = 0, max = types.size(); i < max; i++) {
-          nodes[index++] = (ASTNode) types.get(i);
-        }
-      }
-    } else {
-      //               TypeDeclaration[] types = parsedUnit.types;
-      ArrayList types = parsedUnit.types;
-      if (types != null) {
-        length = types.size();
-        nodes = new ASTNode[length];
-        for (int i = 0, max = types.size(); i < max; i++) {
-          nodes[i] = (ASTNode) types.get(i);
-        }
-      }
-    }
+               if (isInRange) {
+                       requestor.exitMethod(methodDeclaration.declarationSourceEnd);
+               }
+       }
 
-    // notify the nodes in the syntactical order
-    if (nodes != null && length > 0) {
-      quickSort(nodes, 0, length - 1);
-      for (int i = 0; i < length; i++) {
-        ASTNode node = nodes[i];
-                               if (node instanceof ImportReference) {
-                                       ImportReference importRef = (ImportReference)node;
-//                                     if (node == parsedUnit.currentPackage) {
-//                                             notifySourceElementRequestor(importRef, true);
-//                                     } else {
-                                               notifySourceElementRequestor(importRef, false);
-//                                     }
-                               } //else { instanceof TypeDeclaration
-        if (node instanceof TypeDeclaration) {
-          notifySourceElementRequestor((TypeDeclaration) node, sourceType == null);
-          //                           notifySourceElementRequestor((CompilationUnitDeclaration)node,
-          // sourceType == null);
-        }
-        // jsurfer - INSERT start
-        if (node instanceof AbstractMethodDeclaration) {
-          notifySourceElementRequestor((AbstractMethodDeclaration) node);
-        }
-        //             jsurfer - INSERT end
-      }
-    }
+       /*
+        * Update the bodyStart of the corresponding parse node
+        */
+       public void notifySourceElementRequestor(FieldDeclaration fieldDeclaration) {
 
-    if (sourceType == null) {
-      if (isInRange) {
-        requestor.exitCompilationUnit(parsedUnit.sourceEnd);
-      }
-    }
-  }
+               // range check
+               boolean isInRange = scanner.initialPosition <= fieldDeclaration.declarationSourceStart
+                               && scanner.eofPosition >= fieldDeclaration.declarationSourceEnd;
 
-  //private void notifyAllUnknownReferences() {
-  //   for (int i = 0, max = this.unknownRefsCounter; i < max; i++) {
-  //           NameReference nameRef = this.unknownRefs[i];
-  //           if ((nameRef.bits & BindingIds.VARIABLE) != 0) {
-  //                   if ((nameRef.bits & BindingIds.TYPE) == 0) {
-  //                           // variable but not type
-  //                           if (nameRef instanceof SingleNameReference) {
-  //                                   // local var or field
-  //                                   requestor.acceptUnknownReference(((SingleNameReference) nameRef).token,
-  // nameRef.sourceStart);
-  //                           } else {
-  //                                   // QualifiedNameReference
-  //                                   // The last token is a field reference and the previous tokens are a
-  // type/variable references
-  //                                   char[][] tokens = ((QualifiedNameReference) nameRef).tokens;
-  //                                   int tokensLength = tokens.length;
-  //                                   requestor.acceptFieldReference(tokens[tokensLength - 1], nameRef.sourceEnd
-  // - tokens[tokensLength - 1].length + 1);
-  //                                   char[][] typeRef = new char[tokensLength - 1][];
-  //                                   System.arraycopy(tokens, 0, typeRef, 0, tokensLength - 1);
-  //                                   requestor.acceptUnknownReference(typeRef, nameRef.sourceStart,
-  // nameRef.sourceEnd - tokens[tokensLength - 1].length);
-  //                           }
-  //                   } else {
-  //                           // variable or type
-  //                           if (nameRef instanceof SingleNameReference) {
-  //                                   requestor.acceptUnknownReference(((SingleNameReference) nameRef).token,
-  // nameRef.sourceStart);
-  //                           } else {
-  //                                   //QualifiedNameReference
-  //                                   requestor.acceptUnknownReference(((QualifiedNameReference) nameRef).tokens,
-  // nameRef.sourceStart, nameRef.sourceEnd);
-  //                           }
-  //                   }
-  //           } else if ((nameRef.bits & BindingIds.TYPE) != 0) {
-  //                   if (nameRef instanceof SingleNameReference) {
-  //                           requestor.acceptTypeReference(((SingleNameReference) nameRef).token,
-  // nameRef.sourceStart);
-  //                   } else {
-  //                           // it is a QualifiedNameReference
-  //                           requestor.acceptTypeReference(((QualifiedNameReference) nameRef).tokens,
-  // nameRef.sourceStart, nameRef.sourceEnd);
-  //                   }
-  //           }
-  //   }
-  //}
-  /*
-   * Update the bodyStart of the corresponding parse node
-   */
-  public void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration) {
+               if (fieldDeclaration.isField()) {
+                       int fieldEndPosition = fieldDeclaration.declarationSourceEnd;
+                       // if (fieldDeclaration instanceof SourceFieldDeclaration) {
+                       // fieldEndPosition = ((SourceFieldDeclaration)
+                       // fieldDeclaration).fieldEndPosition;
+                       // if (fieldEndPosition == 0) {
+                       // // use the declaration source end by default
+                       // fieldEndPosition = fieldDeclaration.declarationSourceEnd;
+                       // }
+                       // }
+                       if (isInRange) {
+                               int modifiers = fieldDeclaration.modifiers;
+                               boolean deprecated = (modifiers & AccDeprecated) != 0; // remember
+                               // deprecation so
+                               // as to not lose
+                               // it below
+                               requestor.enterField(fieldDeclaration.declarationSourceStart,
+                                               deprecated ? (modifiers & AccJustFlag) | AccDeprecated
+                                                               : modifiers & AccJustFlag,
+                                               returnTypeName(fieldDeclaration.type),
+                                               fieldDeclaration.name, fieldDeclaration.sourceStart,
+                                               fieldDeclaration.sourceEnd);
+                       }
+                       // this.visitIfNeeded(fieldDeclaration);
+                       if (isInRange) {
+                               // requestor.exitField(
+                               // // filter out initializations that are not a constant (simple
+                               // check)
+                               // (fieldDeclaration.initialization == null
+                               // || fieldDeclaration.initialization instanceof
+                               // ArrayInitializer
+                               // || fieldDeclaration.initialization instanceof
+                               // AllocationExpression
+                               // || fieldDeclaration.initialization instanceof
+                               // ArrayAllocationExpression
+                               // || fieldDeclaration.initialization instanceof Assignment
+                               // || fieldDeclaration.initialization instanceof
+                               // ClassLiteralAccess
+                               // || fieldDeclaration.initialization instanceof MessageSend
+                               // || fieldDeclaration.initialization instanceof ArrayReference
+                               // || fieldDeclaration.initialization instanceof ThisReference)
+                               // ?
+                               // -1 :
+                               // fieldDeclaration.initialization.sourceStart,
+                               // fieldEndPosition,
+                               // fieldDeclaration.declarationSourceEnd);
+                               requestor.exitField(
+                                               // filter out initializations that are not a constant
+                                               // (simple check)
+                                               -1, fieldEndPosition,
+                                               fieldDeclaration.declarationSourceEnd);
+                       }
 
-    // range check
-    boolean isInRange = scanner.initialPosition <= methodDeclaration.declarationSourceStart
-        && scanner.eofPosition >= methodDeclaration.declarationSourceEnd;
+               } else {
+                       // if (isInRange){
+                       // requestor.enterInitializer(
+                       // fieldDeclaration.declarationSourceStart,
+                       // fieldDeclaration.modifiers);
+                       // }
+                       // this.visitIfNeeded((Initializer)fieldDeclaration);
+                       // if (isInRange){
+                       // requestor.exitInitializer(fieldDeclaration.declarationSourceEnd);
+                       // }
+               }
+       }
 
-    if (methodDeclaration.isClinit()) {
-      this.visitIfNeeded(methodDeclaration);
-      return;
-    }
+       public void notifySourceElementRequestor(ImportReference importReference,
+                       boolean isPackage) {
+               // if (isPackage) {
+               // requestor.acceptPackage(
+               // importReference.declarationSourceStart,
+               // importReference.declarationSourceEnd,
+               // CharOperation.concatWith(importReference.getImportName(), '.'));
+               // } else {
+               requestor.acceptImport(importReference.declarationSourceStart,
+                               importReference.declarationSourceEnd, importReference
+                                               .getIncludeName(), // CharOperation.concatWith(importReference.getImportName(),
+                                                                                       // '.'),
+                               importReference.onDemand);
+               // }
+       }
 
-    if (methodDeclaration.isDefaultConstructor()) {
-      if (reportReferenceInfo) {
-        ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
-        ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
-        if (constructorCall != null) {
-          switch (constructorCall.accessMode) {
-            case ExplicitConstructorCall.This :
-              requestor.acceptConstructorReference(typeNames[nestedTypeIndex - 1], constructorCall.arguments == null
-                  ? 0
-                  : constructorCall.arguments.length, constructorCall.sourceStart);
-              break;
-            case ExplicitConstructorCall.Super :
-            case ExplicitConstructorCall.ImplicitSuper :
-              requestor.acceptConstructorReference(superTypeNames[nestedTypeIndex - 1], constructorCall.arguments == null
-                  ? 0
-                  : constructorCall.arguments.length, constructorCall.sourceStart);
-              break;
-          }
-        }
-      }
-      return;
-    }
-    char[][] argumentTypes = null;
-    char[][] argumentNames = null;
-    Argument[] arguments = methodDeclaration.arguments;
-    if (arguments != null) {
-      int argumentLength = arguments.length;
-      argumentTypes = new char[argumentLength][];
-      argumentNames = new char[argumentLength][];
-      for (int i = 0; i < argumentLength; i++) {
-        argumentTypes[i] = returnTypeName(arguments[i].type);
-        argumentNames[i] = arguments[i].name;
-      }
-    }
-    char[][] thrownExceptionTypes = null;
-    TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
-    if (thrownExceptions != null) {
-      int thrownExceptionLength = thrownExceptions.length;
-      thrownExceptionTypes = new char[thrownExceptionLength][];
-      for (int i = 0; i < thrownExceptionLength; i++) {
-        thrownExceptionTypes[i] = CharOperation.concatWith(thrownExceptions[i].getTypeName(), '.');
-      }
-    }
-    // by default no selector end position
-    int selectorSourceEnd = -1;
-    if (methodDeclaration.isConstructor()) {
-      //               if (methodDeclaration instanceof SourceConstructorDeclaration) {
-      //                       selectorSourceEnd =
-      //                               ((SourceConstructorDeclaration) methodDeclaration).selectorSourceEnd;
-      //               }
-      if (isInRange) {
-        requestor.enterConstructor(methodDeclaration.declarationSourceStart, methodDeclaration.modifiers,
-            methodDeclaration.selector, methodDeclaration.sourceStart, selectorSourceEnd, argumentTypes, argumentNames,
-            thrownExceptionTypes);
-      }
-      if (reportReferenceInfo) {
-        ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
-        ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
-        if (constructorCall != null) {
-          switch (constructorCall.accessMode) {
-            case ExplicitConstructorCall.This :
-              requestor.acceptConstructorReference(typeNames[nestedTypeIndex - 1], constructorCall.arguments == null
-                  ? 0
-                  : constructorCall.arguments.length, constructorCall.sourceStart);
-              break;
-            case ExplicitConstructorCall.Super :
-            case ExplicitConstructorCall.ImplicitSuper :
-              requestor.acceptConstructorReference(superTypeNames[nestedTypeIndex - 1], constructorCall.arguments == null
-                  ? 0
-                  : constructorCall.arguments.length, constructorCall.sourceStart);
-              break;
-          }
-        }
-      }
-      this.visitIfNeeded(methodDeclaration);
-      if (isInRange) {
-        requestor.exitConstructor(methodDeclaration.declarationSourceEnd);
-      }
-      return;
-    }
-    // if (methodDeclaration instanceof SourceMethodDeclaration) {
-    //         selectorSourceEnd =
-    //                 ((SourceMethodDeclaration) methodDeclaration).selectorSourceEnd;
-    // }
-    if (isInRange) {
-      int modifiers = methodDeclaration.modifiers;
-      //               boolean deprecated = (modifiers & AccDeprecated) != 0; // remember
-      // deprecation so as to not lose it below
-      requestor.enterMethod(methodDeclaration.declarationSourceStart, modifiers, // deprecated
-                                                                                 // ?
-                                                                                 // (modifiers
-                                                                                 // &
-                                                                                 // AccJustFlag)
-                                                                                 // |
-                                                                                 // AccDeprecated
-                                                                                 // :
-                                                                                 // modifiers
-                                                                                 // &
-                                                                                 // AccJustFlag,
-          returnTypeName(((MethodDeclaration) methodDeclaration).returnType), methodDeclaration.selector,
-          methodDeclaration.sourceStart, selectorSourceEnd, argumentTypes, argumentNames, thrownExceptionTypes);
-    }
-    this.visitIfNeeded(methodDeclaration);
+       public void notifySourceElementRequestor(TypeDeclaration typeDeclaration,
+                       boolean notifyTypePresence) {
+               // // public void notifySourceElementRequestor(ASTNode typeDeclaration,
+               // boolean notifyTypePresence) {
 
-    if (isInRange) {
-      requestor.exitMethod(methodDeclaration.declarationSourceEnd);
-    }
-  }
-  /*
-   * Update the bodyStart of the corresponding parse node
-   */
-  public void notifySourceElementRequestor(FieldDeclaration fieldDeclaration) {
+               // range check
+               boolean isInRange = scanner.initialPosition <= typeDeclaration.declarationSourceStart
+                               && scanner.eofPosition >= typeDeclaration.declarationSourceEnd;
 
-    // range check
-    boolean isInRange = scanner.initialPosition <= fieldDeclaration.declarationSourceStart
-        && scanner.eofPosition >= fieldDeclaration.declarationSourceEnd;
+               FieldDeclaration[] fields = typeDeclaration.fields;
+               AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+               TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+               int fieldCount = fields == null ? 0 : fields.length;
+               int methodCount = methods == null ? 0 : methods.length;
+               int memberTypeCount = memberTypes == null ? 0 : memberTypes.length;
+               int fieldIndex = 0;
+               int methodIndex = 0;
+               int memberTypeIndex = 0;
+               boolean isInterface = typeDeclaration.isInterface();
 
-    if (fieldDeclaration.isField()) {
-      int fieldEndPosition = fieldDeclaration.declarationSourceEnd;
-      //               if (fieldDeclaration instanceof SourceFieldDeclaration) {
-      //                       fieldEndPosition = ((SourceFieldDeclaration)
-      // fieldDeclaration).fieldEndPosition;
-      //                       if (fieldEndPosition == 0) {
-      //                               // use the declaration source end by default
-      //                               fieldEndPosition = fieldDeclaration.declarationSourceEnd;
-      //                       }
-      //               }
-      if (isInRange) {
-        int modifiers = fieldDeclaration.modifiers;
-        boolean deprecated = (modifiers & AccDeprecated) != 0; // remember
-                                                               // deprecation so
-                                                               // as to not lose
-                                                               // it below
-        requestor.enterField(fieldDeclaration.declarationSourceStart, deprecated
-            ? (modifiers & AccJustFlag) | AccDeprecated
-            : modifiers & AccJustFlag, returnTypeName(fieldDeclaration.type), fieldDeclaration.name, fieldDeclaration.sourceStart,
-            fieldDeclaration.sourceEnd);
-      }
-      //               this.visitIfNeeded(fieldDeclaration);
-      if (isInRange) {
-        //                     requestor.exitField(
-        //                             // filter out initializations that are not a constant (simple check)
-        //                             (fieldDeclaration.initialization == null
-        //                                             || fieldDeclaration.initialization instanceof ArrayInitializer
-        //                                             || fieldDeclaration.initialization instanceof AllocationExpression
-        //                                             || fieldDeclaration.initialization instanceof
-        // ArrayAllocationExpression
-        //                                             || fieldDeclaration.initialization instanceof Assignment
-        //                                             || fieldDeclaration.initialization instanceof ClassLiteralAccess
-        //                                             || fieldDeclaration.initialization instanceof MessageSend
-        //                                             || fieldDeclaration.initialization instanceof ArrayReference
-        //                                             || fieldDeclaration.initialization instanceof ThisReference) ?
-        //                                     -1 :
-        //                                     fieldDeclaration.initialization.sourceStart,
-        //                             fieldEndPosition,
-        //                             fieldDeclaration.declarationSourceEnd);
-        requestor.exitField(
-        // filter out initializations that are not a constant (simple check)
-            -1, fieldEndPosition, fieldDeclaration.declarationSourceEnd);
-      }
+               if (notifyTypePresence) {
+                       char[][] interfaceNames = null;
+                       int superInterfacesLength = 0;
+                       TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+                       if (superInterfaces != null) {
+                               superInterfacesLength = superInterfaces.length;
+                               interfaceNames = new char[superInterfacesLength][];
+                       } else {
+                               if (typeDeclaration instanceof AnonymousLocalTypeDeclaration) {
+                                       // see PR 3442
+                                       QualifiedAllocationExpression alloc = ((AnonymousLocalTypeDeclaration) typeDeclaration).allocation;
+                                       if (alloc != null && alloc.type != null) {
+                                               superInterfaces = new TypeReference[] { ((AnonymousLocalTypeDeclaration) typeDeclaration).allocation.type };
+                                               superInterfacesLength = 1;
+                                               interfaceNames = new char[1][];
+                                       }
+                               }
+                       }
+                       if (superInterfaces != null) {
+                               for (int i = 0; i < superInterfacesLength; i++) {
+                                       interfaceNames[i] = CharOperation.concatWith(
+                                                       superInterfaces[i].getTypeName(), '.');
+                               }
+                       }
+                       if (isInterface) {
+                               if (isInRange) {
+                                       int modifiers = typeDeclaration.modifiers;
+                                       boolean deprecated = false; // (modifiers & AccDeprecated)
+                                                                                               // != 0; //
+                                       // remember deprecation so as to not lose
+                                       // it below
+                                       requestor.enterInterface(
+                                                       typeDeclaration.declarationSourceStart,
+                                                       modifiers, // deprecated
+                                                       // ?
+                                                       // (modifiers
+                                                       // &
+                                                       // AccJustFlag)
+                                                       // |
+                                                       // AccDeprecated
+                                                       // :
+                                                       // modifiers
+                                                       // &
+                                                       // AccJustFlag,
+                                                       typeDeclaration.name, typeDeclaration.sourceStart,
+                                                       typeDeclaration.sourceEnd, interfaceNames);
+                               }
+                               if (nestedTypeIndex == typeNames.length) {
+                                       // need a resize
+                                       System.arraycopy(typeNames, 0,
+                                                       (typeNames = new char[nestedTypeIndex * 2][]), 0,
+                                                       nestedTypeIndex);
+                                       System.arraycopy(superTypeNames, 0,
+                                                       (superTypeNames = new char[nestedTypeIndex * 2][]),
+                                                       0, nestedTypeIndex);
+                               }
+                               typeNames[nestedTypeIndex] = typeDeclaration.name;
+                               superTypeNames[nestedTypeIndex++] = JAVA_LANG_OBJECT;
+                       } else {
+                               TypeReference superclass = typeDeclaration.superclass;
+                               if (superclass == null) {
+                                       if (isInRange) {
+                                               requestor
+                                                               .enterClass(
+                                                                               typeDeclaration.declarationSourceStart,
+                                                                               typeDeclaration.modifiers,
+                                                                               typeDeclaration.name,
+                                                                               typeDeclaration.sourceStart,
+                                                                               typeDeclaration.sourceEnd, null,
+                                                                               interfaceNames);
+                                       }
+                               } else {
+                                       if (isInRange) {
+                                               requestor.enterClass(
+                                                               typeDeclaration.declarationSourceStart,
+                                                               typeDeclaration.modifiers,
+                                                               typeDeclaration.name,
+                                                               typeDeclaration.sourceStart,
+                                                               typeDeclaration.sourceEnd, CharOperation
+                                                                               .concatWith(superclass.getTypeName(),
+                                                                                               '.'), interfaceNames);
+                                       }
+                               }
+                               if (nestedTypeIndex == typeNames.length) {
+                                       // need a resize
+                                       System.arraycopy(typeNames, 0,
+                                                       (typeNames = new char[nestedTypeIndex * 2][]), 0,
+                                                       nestedTypeIndex);
+                                       System.arraycopy(superTypeNames, 0,
+                                                       (superTypeNames = new char[nestedTypeIndex * 2][]),
+                                                       0, nestedTypeIndex);
+                               }
+                               typeNames[nestedTypeIndex] = typeDeclaration.name;
+                               superTypeNames[nestedTypeIndex++] = superclass == null ? JAVA_LANG_OBJECT
+                                               : CharOperation.concatWith(superclass.getTypeName(),
+                                                               '.');
+                       }
+               }
+               while ((fieldIndex < fieldCount) || (memberTypeIndex < memberTypeCount)
+                               || (methodIndex < methodCount)) {
+                       FieldDeclaration nextFieldDeclaration = null;
+                       AbstractMethodDeclaration nextMethodDeclaration = null;
+                       TypeDeclaration nextMemberDeclaration = null;
 
-    } else {
-      //               if (isInRange){
-      //                       requestor.enterInitializer(
-      //                               fieldDeclaration.declarationSourceStart,
-      //                               fieldDeclaration.modifiers);
-      //               }
-      //               this.visitIfNeeded((Initializer)fieldDeclaration);
-      //               if (isInRange){
-      //                       requestor.exitInitializer(fieldDeclaration.declarationSourceEnd);
-      //               }
-    }
-  }
-  public void notifySourceElementRequestor(
-       ImportReference importReference,
-       boolean isPackage) {
-//     if (isPackage) {
-//             requestor.acceptPackage(
-//                     importReference.declarationSourceStart,
-//                     importReference.declarationSourceEnd,
-//                     CharOperation.concatWith(importReference.getImportName(), '.'));
-//     } else {
-               requestor.acceptImport(
-                       importReference.declarationSourceStart,
-                       importReference.declarationSourceEnd,
-                       importReference.getIncludeName(), //CharOperation.concatWith(importReference.getImportName(), '.'),
-                       importReference.onDemand);
-//     }
-  }
-  public void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence) {
-    //// public void notifySourceElementRequestor(ASTNode typeDeclaration,
-    // boolean notifyTypePresence) {
+                       int position = Integer.MAX_VALUE;
+                       int nextDeclarationType = -1;
+                       if (fieldIndex < fieldCount) {
+                               nextFieldDeclaration = fields[fieldIndex];
+                               if (nextFieldDeclaration.declarationSourceStart < position) {
+                                       position = nextFieldDeclaration.declarationSourceStart;
+                                       nextDeclarationType = 0; // FIELD
+                               }
+                       }
+                       if (methodIndex < methodCount) {
+                               nextMethodDeclaration = methods[methodIndex];
+                               if (nextMethodDeclaration.declarationSourceStart < position) {
+                                       position = nextMethodDeclaration.declarationSourceStart;
+                                       nextDeclarationType = 1; // METHOD
+                               }
+                       }
+                       if (memberTypeIndex < memberTypeCount) {
+                               nextMemberDeclaration = memberTypes[memberTypeIndex];
+                               if (nextMemberDeclaration.declarationSourceStart < position) {
+                                       position = nextMemberDeclaration.declarationSourceStart;
+                                       nextDeclarationType = 2; // MEMBER
+                               }
+                       }
+                       switch (nextDeclarationType) {
+                       case 0:
+                               fieldIndex++;
+                               notifySourceElementRequestor(nextFieldDeclaration);
+                               break;
+                       case 1:
+                               methodIndex++;
+                               notifySourceElementRequestor(nextMethodDeclaration);
+                               break;
+                       case 2:
+                               memberTypeIndex++;
+                               notifySourceElementRequestor(nextMemberDeclaration, true);
+                       }
+               }
+               if (notifyTypePresence) {
+                       if (isInRange) {
+                               if (isInterface) {
+                                       requestor
+                                                       .exitInterface(typeDeclaration.declarationSourceEnd);
+                               } else {
+                                       requestor.exitClass(typeDeclaration.declarationSourceEnd);
+                               }
+                       }
+                       nestedTypeIndex--;
+               }
+       }
 
-    // range check
-    boolean isInRange = scanner.initialPosition <= typeDeclaration.declarationSourceStart
-        && scanner.eofPosition >= typeDeclaration.declarationSourceEnd;
+       public void parseCompilationUnit(ICompilationUnit unit, int start, int end) {
+               // boolean needReferenceInfo) {
 
-    FieldDeclaration[] fields = typeDeclaration.fields;
-    AbstractMethodDeclaration[] methods = typeDeclaration.methods;
-    TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
-    int fieldCount = fields == null ? 0 : fields.length;
-    int methodCount = methods == null ? 0 : methods.length;
-    int memberTypeCount = memberTypes == null ? 0 : memberTypes.length;
-    int fieldIndex = 0;
-    int methodIndex = 0;
-    int memberTypeIndex = 0;
-    boolean isInterface = typeDeclaration.isInterface();
+               // reportReferenceInfo = needReferenceInfo;
+               // boolean old = diet;
+               // if (needReferenceInfo) {
+               // unknownRefs = new NameReference[10];
+               // unknownRefsCounter = 0;
+               // }
 
-    if (notifyTypePresence) {
-      char[][] interfaceNames = null;
-      int superInterfacesLength = 0;
-      TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
-      if (superInterfaces != null) {
-        superInterfacesLength = superInterfaces.length;
-        interfaceNames = new char[superInterfacesLength][];
-      } else {
-        if (typeDeclaration instanceof AnonymousLocalTypeDeclaration) {
-          // see PR 3442
-          QualifiedAllocationExpression alloc = ((AnonymousLocalTypeDeclaration) typeDeclaration).allocation;
-          if (alloc != null && alloc.type != null) {
-            superInterfaces = new TypeReference[]{((AnonymousLocalTypeDeclaration) typeDeclaration).allocation.type};
-            superInterfacesLength = 1;
-            interfaceNames = new char[1][];
-          }
-        }
-      }
-      if (superInterfaces != null) {
-        for (int i = 0; i < superInterfacesLength; i++) {
-          interfaceNames[i] = CharOperation.concatWith(superInterfaces[i].getTypeName(), '.');
-        }
-      }
-      if (isInterface) {
-        if (isInRange) {
-          int modifiers = typeDeclaration.modifiers;
-          boolean deprecated = false; //(modifiers & AccDeprecated) != 0; //
-                                      // remember deprecation so as to not lose
-                                      // it below
-          requestor.enterInterface(typeDeclaration.declarationSourceStart, modifiers, //deprecated
-                                                                                      // ?
-                                                                                      // (modifiers
-                                                                                      // &
-                                                                                      // AccJustFlag)
-                                                                                      // |
-                                                                                      // AccDeprecated
-                                                                                      // :
-                                                                                      // modifiers
-                                                                                      // &
-                                                                                      // AccJustFlag,
-              typeDeclaration.name, typeDeclaration.sourceStart, typeDeclaration.sourceEnd, interfaceNames);
-        }
-        if (nestedTypeIndex == typeNames.length) {
-          // need a resize
-          System.arraycopy(typeNames, 0, (typeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
-          System.arraycopy(superTypeNames, 0, (superTypeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
-        }
-        typeNames[nestedTypeIndex] = typeDeclaration.name;
-        superTypeNames[nestedTypeIndex++] = JAVA_LANG_OBJECT;
-      } else {
-        TypeReference superclass = typeDeclaration.superclass;
-        if (superclass == null) {
-          if (isInRange) {
-            requestor.enterClass(typeDeclaration.declarationSourceStart, typeDeclaration.modifiers, typeDeclaration.name,
-                typeDeclaration.sourceStart, typeDeclaration.sourceEnd, null, interfaceNames);
-          }
-        } else {
-          if (isInRange) {
-            requestor.enterClass(typeDeclaration.declarationSourceStart, typeDeclaration.modifiers, typeDeclaration.name,
-                typeDeclaration.sourceStart, typeDeclaration.sourceEnd, CharOperation.concatWith(superclass.getTypeName(), '.'),
-                interfaceNames);
-          }
-        }
-        if (nestedTypeIndex == typeNames.length) {
-          // need a resize
-          System.arraycopy(typeNames, 0, (typeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
-          System.arraycopy(superTypeNames, 0, (superTypeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
-        }
-        typeNames[nestedTypeIndex] = typeDeclaration.name;
-        superTypeNames[nestedTypeIndex++] = superclass == null ? JAVA_LANG_OBJECT : CharOperation.concatWith(superclass
-            .getTypeName(), '.');
-      }
-    }
-    while ((fieldIndex < fieldCount) || (memberTypeIndex < memberTypeCount) || (methodIndex < methodCount)) {
-      FieldDeclaration nextFieldDeclaration = null;
-      AbstractMethodDeclaration nextMethodDeclaration = null;
-      TypeDeclaration nextMemberDeclaration = null;
+               try {
+                       // diet = true;
+                       CompilationResult compilationUnitResult = new CompilationResult(
+                                       unit, 0, 0, 10); // this.options.maxProblemsPerUnit);
+                       CompilationUnitDeclaration parsedUnit = parse(unit,
+                                       compilationUnitResult, start, end);
+                       // if (scanner.recordLineSeparator) {
+                       // requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+                       // }
+                       // if (this.localDeclarationVisitor != null || needReferenceInfo){
+                       // diet = false;
+                       // this.getMethodBodies(parsedUnit);
+                       // }
+                       // this.scanner.resetTo(start, end);
+                       // notifySourceElementRequestor(parsedUnit);
+               } catch (AbortCompilation e) {
+               } finally {
+                       // diet = old;
+               }
+       }
 
-      int position = Integer.MAX_VALUE;
-      int nextDeclarationType = -1;
-      if (fieldIndex < fieldCount) {
-        nextFieldDeclaration = fields[fieldIndex];
-        if (nextFieldDeclaration.declarationSourceStart < position) {
-          position = nextFieldDeclaration.declarationSourceStart;
-          nextDeclarationType = 0; // FIELD
-        }
-      }
-      if (methodIndex < methodCount) {
-        nextMethodDeclaration = methods[methodIndex];
-        if (nextMethodDeclaration.declarationSourceStart < position) {
-          position = nextMethodDeclaration.declarationSourceStart;
-          nextDeclarationType = 1; // METHOD
-        }
-      }
-      if (memberTypeIndex < memberTypeCount) {
-        nextMemberDeclaration = memberTypes[memberTypeIndex];
-        if (nextMemberDeclaration.declarationSourceStart < position) {
-          position = nextMemberDeclaration.declarationSourceStart;
-          nextDeclarationType = 2; // MEMBER
-        }
-      }
-      switch (nextDeclarationType) {
-        case 0 :
-          fieldIndex++;
-          notifySourceElementRequestor(nextFieldDeclaration);
-          break;
-        case 1 :
-          methodIndex++;
-          notifySourceElementRequestor(nextMethodDeclaration);
-          break;
-        case 2 :
-          memberTypeIndex++;
-          notifySourceElementRequestor(nextMemberDeclaration, true);
-      }
-    }
-    if (notifyTypePresence) {
-      if (isInRange) {
-        if (isInterface) {
-          requestor.exitInterface(typeDeclaration.declarationSourceEnd);
-        } else {
-          requestor.exitClass(typeDeclaration.declarationSourceEnd);
-        }
-      }
-      nestedTypeIndex--;
-    }
-  }
-  public void parseCompilationUnit(ICompilationUnit unit, int start, int end) {
-    // boolean needReferenceInfo) {
+       public CompilationUnitDeclaration parseCompilationUnit(
+                       ICompilationUnit unit, boolean fullParse) {
 
-    // reportReferenceInfo = needReferenceInfo;
-    // boolean old = diet;
-    // if (needReferenceInfo) {
-    //         unknownRefs = new NameReference[10];
-    //         unknownRefsCounter = 0;
-    // }
+               // boolean old = diet;
+               // if (fullParse) {
+               // unknownRefs = new NameReference[10];
+               // unknownRefsCounter = 0;
+               // }
 
-    try {
-      //               diet = true;
-      CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, 10); //this.options.maxProblemsPerUnit);
-      CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, start, end);
-      //               if (scanner.recordLineSeparator) {
-      //                       requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
-      //               }
-      //               if (this.localDeclarationVisitor != null || needReferenceInfo){
-      //                       diet = false;
-      //                       this.getMethodBodies(parsedUnit);
-      //               }
-      //               this.scanner.resetTo(start, end);
-      //               notifySourceElementRequestor(parsedUnit);
-    } catch (AbortCompilation e) {
-    } finally {
-      //               diet = old;
-    }
-  }
-  public CompilationUnitDeclaration parseCompilationUnit(ICompilationUnit unit, boolean fullParse) {
+               try {
+                       // diet = true;
+                       this.reportReferenceInfo = fullParse;
+                       CompilationResult compilationUnitResult = new CompilationResult(
+                                       unit, 0, 0, this.options.maxProblemsPerUnit);
+                       CompilationUnitDeclaration parsedUnit = parse(unit,
+                                       compilationUnitResult, false);
+                       if (scanner.recordLineSeparator) {
+                               requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+                       }
+                       int initialStart = this.scanner.initialPosition;
+                       int initialEnd = this.scanner.eofPosition;
+                       // if (this.localDeclarationVisitor != null || fullParse){
+                       // diet = false;
+                       // this.getMethodBodies(parsedUnit);
+                       // }
+                       this.scanner.resetTo(initialStart, initialEnd);
+                       notifySourceElementRequestor(parsedUnit);
+                       return parsedUnit;
+               } catch (AbortCompilation e) {
+                       // ignore this exception
+               } finally {
+                       // diet = old;
+               }
+               return null;
+       }
 
-    //         boolean old = diet;
-    //         if (fullParse) {
-    //                 unknownRefs = new NameReference[10];
-    //                 unknownRefsCounter = 0;
-    //         }
+       public CompilationUnitDeclaration parseCompletionUnit(
+                       ICompilationUnit unit, boolean fullParse) {
 
-    try {
-      //                       diet = true;
-      this.reportReferenceInfo = fullParse;
-      CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
-      CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, false);
-      if (scanner.recordLineSeparator) {
-        requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
-      }
-      int initialStart = this.scanner.initialPosition;
-      int initialEnd = this.scanner.eofPosition;
-      //                       if (this.localDeclarationVisitor != null || fullParse){
-      //                               diet = false;
-      //                               this.getMethodBodies(parsedUnit);
-      //                       }
-      this.scanner.resetTo(initialStart, initialEnd);
-      notifySourceElementRequestor(parsedUnit);
-      return parsedUnit;
-    } catch (AbortCompilation e) {
-      // ignore this exception
-    } finally {
-      //                       diet = old;
-    }
-    return null;
-  }
+               // boolean old = diet;
+               // if (fullParse) {
+               // unknownRefs = new NameReference[10];
+               // unknownRefsCounter = 0;
+               // }
 
-  public CompilationUnitDeclaration parseCompletionUnit(ICompilationUnit unit, boolean fullParse) {
+               try {
+                       // diet = true;
+                       this.reportReferenceInfo = fullParse;
+                       CompilationResult compilationUnitResult = new CompilationResult(
+                                       unit, 0, 0, this.options.maxProblemsPerUnit);
+                       CompilationUnitDeclaration parsedUnit = parse(unit,
+                                       compilationUnitResult, false);
+                       // if (scanner.recordLineSeparator) {
+                       // requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+                       // }
+                       // int initialStart = this.scanner.initialPosition;
+                       // int initialEnd = this.scanner.eofPosition;
+                       // // if (this.localDeclarationVisitor != null || fullParse){
+                       // // diet = false;
+                       // // this.getMethodBodies(parsedUnit);
+                       // // }
+                       // this.scanner.resetTo(initialStart, initialEnd);
+                       // notifySourceElementRequestor(parsedUnit);
+                       return parsedUnit;
+               } catch (AbortCompilation e) {
+                       // ignore this exception
+               } finally {
+                       // diet = old;
+               }
+               return null;
+       }
 
-    //         boolean old = diet;
-    //         if (fullParse) {
-    //                 unknownRefs = new NameReference[10];
-    //                 unknownRefsCounter = 0;
-    //         }
+       // public void parseTypeMemberDeclarations(
+       // ISourceType sourceType,
+       // ICompilationUnit sourceUnit,
+       // int start,
+       // int end,
+       // boolean needReferenceInfo) {
+       // boolean old = diet;
+       // if (needReferenceInfo) {
+       // unknownRefs = new NameReference[10];
+       // unknownRefsCounter = 0;
+       // }
+       //      
+       // try {
+       // diet = !needReferenceInfo;
+       // reportReferenceInfo = needReferenceInfo;
+       // CompilationResult compilationUnitResult =
+       // new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit);
+       // CompilationUnitDeclaration unit =
+       // SourceTypeConverter.buildCompilationUnit(
+       // new ISourceType[]{sourceType},
+       // false, // no need for field and methods
+       // false, // no need for member types
+       // false, // no need for field initialization
+       // problemReporter(),
+       // compilationUnitResult);
+       // if ((unit == null) || (unit.types == null) || (unit.types.length != 1))
+       // return;
+       // this.sourceType = sourceType;
+       // try {
+       // /* automaton initialization */
+       // initialize();
+       // goForClassBodyDeclarations();
+       // /* scanner initialization */
+       // scanner.setSource(sourceUnit.getContents());
+       // scanner.resetTo(start, end);
+       // /* unit creation */
+       // referenceContext = compilationUnit = unit;
+       // /* initialize the astStacl */
+       // // the compilationUnitDeclaration should contain exactly one type
+       // pushOnAstStack(unit.types[0]);
+       // /* run automaton */
+       // parse();
+       // notifySourceElementRequestor(unit);
+       // } finally {
+       // unit = compilationUnit;
+       // compilationUnit = null; // reset parser
+       // }
+       // } catch (AbortCompilation e) {
+       // } finally {
+       // if (scanner.recordLineSeparator) {
+       // requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+       // }
+       // diet = old;
+       // }
+       // }
+       //
+       // public void parseTypeMemberDeclarations(
+       // char[] contents,
+       // int start,
+       // int end) {
+       //
+       // boolean old = diet;
+       //      
+       // try {
+       // diet = true;
+       //
+       // /* automaton initialization */
+       // initialize();
+       // goForClassBodyDeclarations();
+       // /* scanner initialization */
+       // scanner.setSource(contents);
+       // scanner.recordLineSeparator = false;
+       // scanner.taskTags = null;
+       // scanner.taskPriorities = null;
+       // scanner.resetTo(start, end);
+       //
+       // /* unit creation */
+       // referenceContext = null;
+       //
+       // /* initialize the astStacl */
+       // // the compilationUnitDeclaration should contain exactly one type
+       // /* run automaton */
+       // parse();
+       // notifySourceElementRequestor((CompilationUnitDeclaration)null);
+       // } catch (AbortCompilation e) {
+       // } finally {
+       // diet = old;
+       // }
+       // }
+       /**
+        * Sort the given ast nodes by their positions.
+        */
+       private static void quickSort(ASTNode[] sortedCollection, int left,
+                       int right) {
+               int original_left = left;
+               int original_right = right;
+               ASTNode mid = sortedCollection[(left + right) / 2];
+               do {
+                       while (sortedCollection[left].sourceStart < mid.sourceStart) {
+                               left++;
+                       }
+                       while (mid.sourceStart < sortedCollection[right].sourceStart) {
+                               right--;
+                       }
+                       if (left <= right) {
+                               ASTNode tmp = sortedCollection[left];
+                               sortedCollection[left] = sortedCollection[right];
+                               sortedCollection[right] = tmp;
+                               left++;
+                               right--;
+                       }
+               } while (left <= right);
+               if (original_left < right) {
+                       quickSort(sortedCollection, original_left, right);
+               }
+               if (left < original_right) {
+                       quickSort(sortedCollection, left, original_right);
+               }
+       }
 
-    try {
-      //                       diet = true;
-      this.reportReferenceInfo = fullParse;
-      CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
-      CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, false);
-//      if (scanner.recordLineSeparator) {
-//        requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
-//      }
-//      int initialStart = this.scanner.initialPosition;
-//      int initialEnd = this.scanner.eofPosition;
-//      //                     if (this.localDeclarationVisitor != null || fullParse){
-//      //                             diet = false;
-//      //                             this.getMethodBodies(parsedUnit);
-//      //                     }
-//      this.scanner.resetTo(initialStart, initialEnd);
-//      notifySourceElementRequestor(parsedUnit);
-      return parsedUnit;
-    } catch (AbortCompilation e) {
-      // ignore this exception
-    } finally {
-      //                       diet = old;
-    }
-    return null;
-  }
-  //public void parseTypeMemberDeclarations(
-  //   ISourceType sourceType,
-  //   ICompilationUnit sourceUnit,
-  //   int start,
-  //   int end,
-  //   boolean needReferenceInfo) {
-  //   boolean old = diet;
-  //   if (needReferenceInfo) {
-  //           unknownRefs = new NameReference[10];
-  //           unknownRefsCounter = 0;
-  //   }
-  //   
-  //   try {
-  //           diet = !needReferenceInfo;
-  //           reportReferenceInfo = needReferenceInfo;
-  //           CompilationResult compilationUnitResult =
-  //                   new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit);
-  //           CompilationUnitDeclaration unit =
-  //                   SourceTypeConverter.buildCompilationUnit(
-  //                           new ISourceType[]{sourceType},
-  //                           false, // no need for field and methods
-  //                           false, // no need for member types
-  //                           false, // no need for field initialization
-  //                           problemReporter(),
-  //                           compilationUnitResult);
-  //           if ((unit == null) || (unit.types == null) || (unit.types.length != 1))
-  //                   return;
-  //           this.sourceType = sourceType;
-  //           try {
-  //                   /* automaton initialization */
-  //                   initialize();
-  //                   goForClassBodyDeclarations();
-  //                   /* scanner initialization */
-  //                   scanner.setSource(sourceUnit.getContents());
-  //                   scanner.resetTo(start, end);
-  //                   /* unit creation */
-  //                   referenceContext = compilationUnit = unit;
-  //                   /* initialize the astStacl */
-  //                   // the compilationUnitDeclaration should contain exactly one type
-  //                   pushOnAstStack(unit.types[0]);
-  //                   /* run automaton */
-  //                   parse();
-  //                   notifySourceElementRequestor(unit);
-  //           } finally {
-  //                   unit = compilationUnit;
-  //                   compilationUnit = null; // reset parser
-  //           }
-  //   } catch (AbortCompilation e) {
-  //   } finally {
-  //           if (scanner.recordLineSeparator) {
-  //                   requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
-  //           }
-  //           diet = old;
-  //   }
-  //}
-  //
-  //public void parseTypeMemberDeclarations(
-  //   char[] contents,
-  //   int start,
-  //   int end) {
-  //
-  //   boolean old = diet;
-  //   
-  //   try {
-  //           diet = true;
-  //
-  //           /* automaton initialization */
-  //           initialize();
-  //           goForClassBodyDeclarations();
-  //           /* scanner initialization */
-  //           scanner.setSource(contents);
-  //           scanner.recordLineSeparator = false;
-  //           scanner.taskTags = null;
-  //           scanner.taskPriorities = null;
-  //           scanner.resetTo(start, end);
-  //
-  //           /* unit creation */
-  //           referenceContext = null;
-  //
-  //           /* initialize the astStacl */
-  //           // the compilationUnitDeclaration should contain exactly one type
-  //           /* run automaton */
-  //           parse();
-  //           notifySourceElementRequestor((CompilationUnitDeclaration)null);
-  //   } catch (AbortCompilation e) {
-  //   } finally {
-  //           diet = old;
-  //   }
-  //}
-  /**
-   * Sort the given ast nodes by their positions.
-   */
-  private static void quickSort(ASTNode[] sortedCollection, int left, int right) {
-    int original_left = left;
-    int original_right = right;
-    ASTNode mid = sortedCollection[(left + right) / 2];
-    do {
-      while (sortedCollection[left].sourceStart < mid.sourceStart) {
-        left++;
-      }
-      while (mid.sourceStart < sortedCollection[right].sourceStart) {
-        right--;
-      }
-      if (left <= right) {
-        ASTNode tmp = sortedCollection[left];
-        sortedCollection[left] = sortedCollection[right];
-        sortedCollection[right] = tmp;
-        left++;
-        right--;
-      }
-    } while (left <= right);
-    if (original_left < right) {
-      quickSort(sortedCollection, original_left, right);
-    }
-    if (left < original_right) {
-      quickSort(sortedCollection, left, original_right);
-    }
-  }
-  /*
-   * Answer a char array representation of the type name formatted like: - type
-   * name + dimensions Example: "A[][]".toCharArray()
-   * "java.lang.String".toCharArray()
-   */
-  private char[] returnTypeName(TypeReference type) {
-    if (type == null)
-      return null;
-    int dimension = type.dimensions();
-    if (dimension != 0) {
-      char[] dimensionsArray = new char[dimension * 2];
-      for (int i = 0; i < dimension; i++) {
-        dimensionsArray[i * 2] = '[';
-        dimensionsArray[(i * 2) + 1] = ']';
-      }
-      return CharOperation.concat(CharOperation.concatWith(type.getTypeName(), '.'), dimensionsArray);
-    }
-    return CharOperation.concatWith(type.getTypeName(), '.');
-  }
+       /*
+        * Answer a char array representation of the type name formatted like: -
+        * type name + dimensions Example: "A[][]".toCharArray()
+        * "java.lang.String".toCharArray()
+        */
+       private char[] returnTypeName(TypeReference type) {
+               if (type == null)
+                       return null;
+               int dimension = type.dimensions();
+               if (dimension != 0) {
+                       char[] dimensionsArray = new char[dimension * 2];
+                       for (int i = 0; i < dimension; i++) {
+                               dimensionsArray[i * 2] = '[';
+                               dimensionsArray[(i * 2) + 1] = ']';
+                       }
+                       return CharOperation.concat(CharOperation.concatWith(type
+                                       .getTypeName(), '.'), dimensionsArray);
+               }
+               return CharOperation.concatWith(type.getTypeName(), '.');
+       }
 
-  public void addUnknownRef(NameReference nameRef) {
-    if (this.unknownRefs.length == this.unknownRefsCounter) {
-      // resize
-      System.arraycopy(this.unknownRefs, 0, (this.unknownRefs = new NameReference[this.unknownRefsCounter * 2]), 0,
-          this.unknownRefsCounter);
-    }
-    this.unknownRefs[this.unknownRefsCounter++] = nameRef;
-  }
+       public void addUnknownRef(NameReference nameRef) {
+               if (this.unknownRefs.length == this.unknownRefsCounter) {
+                       // resize
+                       System
+                                       .arraycopy(
+                                                       this.unknownRefs,
+                                                       0,
+                                                       (this.unknownRefs = new NameReference[this.unknownRefsCounter * 2]),
+                                                       0, this.unknownRefsCounter);
+               }
+               this.unknownRefs[this.unknownRefsCounter++] = nameRef;
+       }
 
-  private void visitIfNeeded(AbstractMethodDeclaration method) {
-    if (this.localDeclarationVisitor != null && (method.bits & ASTNode.HasLocalTypeMASK) != 0) {
-      if (method.statements != null) {
-        int statementsLength = method.statements.length;
-        for (int i = 0; i < statementsLength; i++)
-          method.statements[i].traverse(this.localDeclarationVisitor, method.scope);
-      }
-    }
-  }
+       private void visitIfNeeded(AbstractMethodDeclaration method) {
+               if (this.localDeclarationVisitor != null
+                               && (method.bits & ASTNode.HasLocalTypeMASK) != 0) {
+                       if (method.statements != null) {
+                               int statementsLength = method.statements.length;
+                               for (int i = 0; i < statementsLength; i++)
+                                       method.statements[i].traverse(this.localDeclarationVisitor,
+                                                       method.scope);
+                       }
+               }
+       }
 
-  //private void visitIfNeeded(FieldDeclaration field) {
-  //   if (this.localDeclarationVisitor != null
-  //           && (field.bits & ASTNode.HasLocalTypeMASK) != 0) {
-  //                   if (field.initialization != null) {
-  //                           field.initialization.traverse(this.localDeclarationVisitor, null);
-  //                   }
-  //   }
-  //}
-  //
-  //private void visitIfNeeded(Initializer initializer) {
-  //   if (this.localDeclarationVisitor != null
-  //           && (initializer.bits & ASTNode.HasLocalTypeMASK) != 0) {
-  //                   if (initializer.block != null) {
-  //                           initializer.block.traverse(this.localDeclarationVisitor, null);
-  //                   }
-  //   }
-  //}
-  //
-  //protected void reportSyntaxError(int act, int currentKind, int
-  // stateStackTop) {
-  //   if (compilationUnit == null) return;
-  //   super.reportSyntaxError(act, currentKind,stateStackTop);
-  //}
-  protected CompilationUnitDeclaration endParse(int act) {
-    // if (sourceType != null) {
-    //         if (sourceType.isInterface()) {
-    //                 consumeInterfaceDeclaration();
-    //         } else {
-    //                 consumeClassDeclaration();
-    //         }
-    // }
-    if (compilationUnit != null) {
-      CompilationUnitDeclaration result = super.endParse(act);
-      return result;
-    } else {
-      return null;
-    }
-  }
+       // private void visitIfNeeded(FieldDeclaration field) {
+       // if (this.localDeclarationVisitor != null
+       // && (field.bits & ASTNode.HasLocalTypeMASK) != 0) {
+       // if (field.initialization != null) {
+       // field.initialization.traverse(this.localDeclarationVisitor, null);
+       // }
+       // }
+       // }
+       //
+       // private void visitIfNeeded(Initializer initializer) {
+       // if (this.localDeclarationVisitor != null
+       // && (initializer.bits & ASTNode.HasLocalTypeMASK) != 0) {
+       // if (initializer.block != null) {
+       // initializer.block.traverse(this.localDeclarationVisitor, null);
+       // }
+       // }
+       // }
+       //
+       // protected void reportSyntaxError(int act, int currentKind, int
+       // stateStackTop) {
+       // if (compilationUnit == null) return;
+       // super.reportSyntaxError(act, currentKind,stateStackTop);
+       // }
+       protected CompilationUnitDeclaration endParse(int act) {
+               // if (sourceType != null) {
+               // if (sourceType.isInterface()) {
+               // consumeInterfaceDeclaration();
+               // } else {
+               // consumeClassDeclaration();
+               // }
+               // }
+               if (compilationUnit != null) {
+                       CompilationUnitDeclaration result = super.endParse(act);
+                       return result;
+               } else {
+                       return null;
+               }
+       }
 }
\ No newline at end of file