811db7afd8ba31cc79d28f7571a644a63d03b0fb
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / ASTConverter.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.core.dom;
13
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.OperationCanceledException;
22 import net.sourceforge.phpdt.core.JavaCore;
23 import net.sourceforge.phpdt.core.compiler.CategorizedProblem;
24 import net.sourceforge.phpdt.core.compiler.CharOperation;
25 import net.sourceforge.phpdt.core.compiler.IProblem;
26 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
27 import net.sourceforge.phpdt.core.dom.Modifier.ModifierKeyword;
28 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
29 import net.sourceforge.phpdt.internal.compiler.ast.AbstractVariableDeclaration;
30 import net.sourceforge.phpdt.internal.compiler.ast.Argument;
31 import net.sourceforge.phpdt.internal.compiler.ast.ForeachStatement;
32 import net.sourceforge.phpdt.internal.compiler.ast.JavadocArgumentExpression;
33 import net.sourceforge.phpdt.internal.compiler.ast.JavadocFieldReference;
34 import net.sourceforge.phpdt.internal.compiler.ast.JavadocMessageSend;
35 import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration;
36 import net.sourceforge.phpdt.internal.compiler.ast.MessageSend;
37 import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
38 import net.sourceforge.phpdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
39 import net.sourceforge.phpdt.internal.compiler.ast.ParameterizedSingleTypeReference;
40 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression;
41 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference;
42 import net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference;
43 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
44 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralConcatenation;
45 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
46 import net.sourceforge.phpdt.internal.compiler.ast.Wildcard;
47 import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
48 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
49 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
50 import net.sourceforge.phpdt.internal.compiler.lookup.ExtraCompilerModifiers;
51 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
52 import net.sourceforge.phpdt.internal.compiler.parser.RecoveryScanner;
53 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
54 import net.sourceforge.phpdt.internal.compiler.parser.TerminalTokens;
55
56 /**
57  * Internal class for converting internal compiler ASTs into public ASTs.
58  */
59 class ASTConverter {
60
61         protected AST ast;
62         protected Comment[] commentsTable;
63         char[] compilationUnitSource;
64         int compilationUnitSourceLength;
65         protected DocCommentParser docParser;
66         // comments
67         protected boolean insideComments;
68         protected IProgressMonitor monitor;
69         protected Set pendingNameScopeResolution;       
70         protected Set pendingThisExpressionScopeResolution;
71         protected boolean resolveBindings;
72         Scanner scanner;
73         private DefaultCommentMapper commentMapper;
74
75         public ASTConverter(Map options, boolean resolveBindings, IProgressMonitor monitor) {
76                 this.resolveBindings = resolveBindings;
77                 Object sourceModeSetting = options.get(JavaCore.COMPILER_SOURCE);
78                 long sourceLevel = CompilerOptions.versionToJdkLevel(sourceModeSetting);
79                 if (sourceLevel == 0) {
80                         // unknown sourceModeSetting
81                         sourceLevel = ClassFileConstants.JDK1_3;
82                 }
83                 this.scanner = new Scanner(
84                         true /*comment*/,
85                         false /*whitespace*/,
86                         false /*nls*/,
87                         sourceLevel /*sourceLevel*/,
88                         null /*taskTags*/,
89                         null/*taskPriorities*/,
90                         true/*taskCaseSensitive*/);
91                 this.monitor = monitor;
92                 this.insideComments = JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_DOC_COMMENT_SUPPORT));
93         }
94         
95         protected void adjustSourcePositionsForParent(net.sourceforge.phpdt.internal.compiler.ast.Expression expression) {
96                 int start = expression.sourceStart;
97                 int end = expression.sourceEnd;
98                 int leftParentCount = 1;
99                 int rightParentCount = 0;
100                 this.scanner.resetTo(start, end);
101                 try {
102                         int token = this.scanner.getNextToken();
103                         expression.sourceStart = this.scanner.currentPosition;
104                         boolean stop = false;
105                         while (!stop && ((token  = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) {
106                                 switch(token) {
107                                         case TerminalTokens.TokenNameLPAREN:
108                                                 leftParentCount++;
109                                                 break;
110                                         case TerminalTokens.TokenNameRPAREN:
111                                                 rightParentCount++;
112                                                 if (rightParentCount == leftParentCount) {
113                                                         // we found the matching parenthesis
114                                                         stop = true;
115                                                 }
116                                 }
117                         }
118                         expression.sourceEnd = this.scanner.startPosition - 1;
119                 } catch(InvalidInputException e) {
120                         // ignore
121                 }
122         }
123
124         protected void buildBodyDeclarations(net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDeclaration, AbstractTypeDeclaration typeDecl) {
125                 // add body declaration in the lexical order
126                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration[] members = typeDeclaration.memberTypes;
127                 net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration[] fields = typeDeclaration.fields;
128                 net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = typeDeclaration.methods;
129                 
130                 int fieldsLength = fields == null? 0 : fields.length;
131                 int methodsLength = methods == null? 0 : methods.length;
132                 int membersLength = members == null ? 0 : members.length;
133                 int fieldsIndex = 0;
134                 int methodsIndex = 0;
135                 int membersIndex = 0;
136                 
137                 while ((fieldsIndex < fieldsLength)
138                         || (membersIndex < membersLength)
139                         || (methodsIndex < methodsLength)) {
140                         net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
141                         net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
142                         net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
143                 
144                         int position = Integer.MAX_VALUE;
145                         int nextDeclarationType = -1;
146                         if (fieldsIndex < fieldsLength) {
147                                 nextFieldDeclaration = fields[fieldsIndex];
148                                 if (nextFieldDeclaration.declarationSourceStart < position) {
149                                         position = nextFieldDeclaration.declarationSourceStart;
150                                         nextDeclarationType = 0; // FIELD
151                                 }
152                         }
153                         if (methodsIndex < methodsLength) {
154                                 nextMethodDeclaration = methods[methodsIndex];
155                                 if (nextMethodDeclaration.declarationSourceStart < position) {
156                                         position = nextMethodDeclaration.declarationSourceStart;
157                                         nextDeclarationType = 1; // METHOD
158                                 }
159                         }
160                         if (membersIndex < membersLength) {
161                                 nextMemberDeclaration = members[membersIndex];
162                                 if (nextMemberDeclaration.declarationSourceStart < position) {
163                                         position = nextMemberDeclaration.declarationSourceStart;
164                                         nextDeclarationType = 2; // MEMBER
165                                 }
166                         }
167                         switch (nextDeclarationType) {
168                                 case 0 :
169                                         if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
170                                                 typeDecl.bodyDeclarations().add(convert(nextFieldDeclaration));
171                                         } else {
172                                                 checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, typeDecl.bodyDeclarations());
173                                         }
174                                         fieldsIndex++;
175                                         break;
176                                 case 1 :
177                                         methodsIndex++;
178                                         if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
179                                                 typeDecl.bodyDeclarations().add(convert(nextMethodDeclaration));
180                                         }
181                                         break;
182                                 case 2 :
183                                         membersIndex++;
184                                         ASTNode node = convert(nextMemberDeclaration);
185                                         if (node == null) {
186                                                 typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
187                                         } else {
188                                                 typeDecl.bodyDeclarations().add(node);
189                                         }
190                         }
191                 }
192                 // Convert javadoc
193                 convert(typeDeclaration.javadoc, typeDecl);
194         }
195         
196         protected void buildBodyDeclarations(net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration enumDeclaration2, EnumDeclaration enumDeclaration) {
197                 // add body declaration in the lexical order
198                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration[] members = enumDeclaration2.memberTypes;
199                 net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration[] fields = enumDeclaration2.fields;
200                 net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = enumDeclaration2.methods;
201                 
202                 int fieldsLength = fields == null? 0 : fields.length;
203                 int methodsLength = methods == null? 0 : methods.length;
204                 int membersLength = members == null ? 0 : members.length;
205                 int fieldsIndex = 0;
206                 int methodsIndex = 0;
207                 int membersIndex = 0;
208                 
209                 while ((fieldsIndex < fieldsLength)
210                         || (membersIndex < membersLength)
211                         || (methodsIndex < methodsLength)) {
212                         net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
213                         net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
214                         net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
215                 
216                         int position = Integer.MAX_VALUE;
217                         int nextDeclarationType = -1;
218                         if (fieldsIndex < fieldsLength) {
219                                 nextFieldDeclaration = fields[fieldsIndex];
220                                 if (nextFieldDeclaration.declarationSourceStart < position) {
221                                         position = nextFieldDeclaration.declarationSourceStart;
222                                         nextDeclarationType = 0; // FIELD
223                                 }
224                         }
225                         if (methodsIndex < methodsLength) {
226                                 nextMethodDeclaration = methods[methodsIndex];
227                                 if (nextMethodDeclaration.declarationSourceStart < position) {
228                                         position = nextMethodDeclaration.declarationSourceStart;
229                                         nextDeclarationType = 1; // METHOD
230                                 }
231                         }
232                         if (membersIndex < membersLength) {
233                                 nextMemberDeclaration = members[membersIndex];
234                                 if (nextMemberDeclaration.declarationSourceStart < position) {
235                                         position = nextMemberDeclaration.declarationSourceStart;
236                                         nextDeclarationType = 2; // MEMBER
237                                 }
238                         }
239                         switch (nextDeclarationType) {
240                                 case 0 :
241                                         if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
242                                                 enumDeclaration.enumConstants().add(convert(nextFieldDeclaration));
243                                         } else {
244                                                 checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, enumDeclaration.bodyDeclarations());
245                                         }
246                                         fieldsIndex++;
247                                         break;
248                                 case 1 :
249                                         methodsIndex++;
250                                         if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
251                                                 enumDeclaration.bodyDeclarations().add(convert(nextMethodDeclaration));
252                                         }
253                                         break;
254                                 case 2 :
255                                         membersIndex++;
256                                         enumDeclaration.bodyDeclarations().add(convert(nextMemberDeclaration));
257                                         break;
258                         }
259                 }
260                 convert(enumDeclaration2.javadoc, enumDeclaration);
261         }
262         
263         protected void buildBodyDeclarations(net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration expression, AnonymousClassDeclaration anonymousClassDeclaration) {
264                 // add body declaration in the lexical order
265                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration[] members = expression.memberTypes;
266                 net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration[] fields = expression.fields;
267                 net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = expression.methods;
268                 
269                 int fieldsLength = fields == null? 0 : fields.length;
270                 int methodsLength = methods == null? 0 : methods.length;
271                 int membersLength = members == null ? 0 : members.length;
272                 int fieldsIndex = 0;
273                 int methodsIndex = 0;
274                 int membersIndex = 0;
275                 
276                 while ((fieldsIndex < fieldsLength)
277                         || (membersIndex < membersLength)
278                         || (methodsIndex < methodsLength)) {
279                         net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
280                         net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
281                         net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
282                 
283                         int position = Integer.MAX_VALUE;
284                         int nextDeclarationType = -1;
285                         if (fieldsIndex < fieldsLength) {
286                                 nextFieldDeclaration = fields[fieldsIndex];
287                                 if (nextFieldDeclaration.declarationSourceStart < position) {
288                                         position = nextFieldDeclaration.declarationSourceStart;
289                                         nextDeclarationType = 0; // FIELD
290                                 }
291                         }
292                         if (methodsIndex < methodsLength) {
293                                 nextMethodDeclaration = methods[methodsIndex];
294                                 if (nextMethodDeclaration.declarationSourceStart < position) {
295                                         position = nextMethodDeclaration.declarationSourceStart;
296                                         nextDeclarationType = 1; // METHOD
297                                 }
298                         }
299                         if (membersIndex < membersLength) {
300                                 nextMemberDeclaration = members[membersIndex];
301                                 if (nextMemberDeclaration.declarationSourceStart < position) {
302                                         position = nextMemberDeclaration.declarationSourceStart;
303                                         nextDeclarationType = 2; // MEMBER
304                                 }
305                         }
306                         switch (nextDeclarationType) {
307                                 case 0 :
308                                         if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
309                                                 anonymousClassDeclaration.bodyDeclarations().add(convert(nextFieldDeclaration));
310                                         } else {
311                                                 checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, anonymousClassDeclaration.bodyDeclarations());
312                                         }
313                                         fieldsIndex++;
314                                         break;
315                                 case 1 :
316                                         methodsIndex++;
317                                         if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
318                                                 anonymousClassDeclaration.bodyDeclarations().add(convert(nextMethodDeclaration));
319                                         }
320                                         break;
321                                 case 2 :
322                                         membersIndex++;
323                                         ASTNode node = convert(nextMemberDeclaration);
324                                         if (node == null) {
325                                                 anonymousClassDeclaration.setFlags(anonymousClassDeclaration.getFlags() | ASTNode.MALFORMED);
326                                         } else {
327                                                 anonymousClassDeclaration.bodyDeclarations().add(node);
328                                         }
329                         }
330                 }
331         }
332         
333         /**
334          * @param compilationUnit
335          * @param comments
336          */
337         void buildCommentsTable(CompilationUnit compilationUnit, int[][] comments) {
338                 // Build comment table
339                 this.commentsTable = new Comment[comments.length];
340                 int nbr = 0;
341                 for (int i = 0; i < comments.length; i++) {
342                         Comment comment = createComment(comments[i]);
343                         if (comment != null) {
344                                 comment.setAlternateRoot(compilationUnit);
345                                 this.commentsTable[nbr++] = comment;
346                         }
347                 }
348                 // Resize table if  necessary
349                 if (nbr<comments.length) {
350                         Comment[] newCommentsTable = new Comment[nbr];
351                         System.arraycopy(this.commentsTable, 0, newCommentsTable, 0, nbr);
352                         this.commentsTable = newCommentsTable;
353                 }
354                 compilationUnit.setCommentTable(this.commentsTable);
355         }
356         
357         protected void checkAndAddMultipleFieldDeclaration(net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration[] fields, int index, List bodyDeclarations) {
358                 if (fields[index] instanceof net.sourceforge.phpdt.internal.compiler.ast.Initializer) {
359                         net.sourceforge.phpdt.internal.compiler.ast.Initializer oldInitializer = (net.sourceforge.phpdt.internal.compiler.ast.Initializer) fields[index];
360                         Initializer initializer = new Initializer(this.ast);
361                         initializer.setBody(convert(oldInitializer.block));
362                         setModifiers(initializer, oldInitializer);
363                         initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
364                         // The javadoc comment is now got from list store in compilation unit declaration
365                         convert(oldInitializer.javadoc, initializer);
366                         bodyDeclarations.add(initializer);
367                         return;
368                 }
369                 if (index > 0 && fields[index - 1].declarationSourceStart == fields[index].declarationSourceStart) {
370                         // we have a multiple field declaration
371                         // We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
372                         FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclarations.get(bodyDeclarations.size() - 1);
373                         fieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fields[index]));
374                 } else {
375                         // we can create a new FieldDeclaration
376                         bodyDeclarations.add(convertToFieldDeclaration(fields[index]));
377                 }
378         }
379
380         protected void checkAndAddMultipleLocalDeclaration(net.sourceforge.phpdt.internal.compiler.ast.Statement[] stmts, int index, List blockStatements) {
381                 if (index > 0
382                                 && stmts[index - 1] instanceof net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) {
383                         net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration local1 = (net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) stmts[index - 1];
384                         net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration local2 = (net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) stmts[index];
385                         if (local1.declarationSourceStart == local2.declarationSourceStart) {
386                                 // we have a multiple local declarations
387                                 // We retrieve the existing VariableDeclarationStatement to add the new VariableDeclarationFragment
388                                 VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) blockStatements.get(blockStatements.size() - 1);
389                                 variableDeclarationStatement.fragments().add(convertToVariableDeclarationFragment((net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
390                         } else {
391                                 // we can create a new FieldDeclaration
392                                 blockStatements.add(convertToVariableDeclarationStatement((net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
393                         }
394                 } else {
395                         // we can create a new FieldDeclaration
396                         blockStatements.add(convertToVariableDeclarationStatement((net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
397                 }
398         }
399
400         protected void checkCanceled() {
401                 if (this.monitor != null && this.monitor.isCanceled())
402                         throw new OperationCanceledException();
403         }
404
405         protected void completeRecord(ArrayType arrayType, net.sourceforge.phpdt.internal.compiler.ast.ASTNode astNode) {
406                 ArrayType array = arrayType;
407                 int dimensions = array.getDimensions();
408                 for (int i = 0; i < dimensions; i++) {
409                         Type componentType = array.getComponentType();
410                         this.recordNodes(componentType, astNode);
411                         if (componentType.isArrayType()) {
412                                 array = (ArrayType) componentType;
413                         }
414                 }
415         }
416                 
417         public ASTNode convert(net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) {
418                 checkCanceled();
419                 if (methodDeclaration instanceof net.sourceforge.phpdt.internal.compiler.ast.AnnotationMethodDeclaration) {
420                         return convert((net.sourceforge.phpdt.internal.compiler.ast.AnnotationMethodDeclaration) methodDeclaration);
421                 }
422                 MethodDeclaration methodDecl = new MethodDeclaration(this.ast);
423                 setModifiers(methodDecl, methodDeclaration);
424                 boolean isConstructor = methodDeclaration.isConstructor();
425                 methodDecl.setConstructor(isConstructor);
426                 final SimpleName methodName = new SimpleName(this.ast);
427                 methodName.internalSetIdentifier(new String(methodDeclaration.selector));
428                 int start = methodDeclaration.sourceStart;
429                 int end = retrieveIdentifierEndPosition(start, methodDeclaration.sourceEnd);
430                 methodName.setSourceRange(start, end - start + 1);
431                 methodDecl.setName(methodName);
432                 net.sourceforge.phpdt.internal.compiler.ast.TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
433                 int methodHeaderEnd = methodDeclaration.sourceEnd;
434                 int thrownExceptionsLength = thrownExceptions == null ? 0 : thrownExceptions.length;
435                 if (thrownExceptionsLength > 0) {
436                         Name thrownException;
437                         int i = 0;
438                         do {
439                                 thrownException = convert(thrownExceptions[i++]);
440                                 methodDecl.thrownExceptions().add(thrownException);
441                         } while (i < thrownExceptionsLength);
442                         methodHeaderEnd = thrownException.getStartPosition() + thrownException.getLength();
443                 }
444                 net.sourceforge.phpdt.internal.compiler.ast.Argument[] parameters = methodDeclaration.arguments;
445                 int parametersLength = parameters == null ? 0 : parameters.length;
446                 if (parametersLength > 0) {
447                         SingleVariableDeclaration parameter;
448                         int i = 0;
449                         do {
450                                 parameter = convert(parameters[i++]);
451                                 methodDecl.parameters().add(parameter);
452                         } while (i < parametersLength);
453                         if (thrownExceptionsLength == 0) {
454                                 methodHeaderEnd = parameter.getStartPosition() + parameter.getLength();
455                         }
456                 }
457                 net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall explicitConstructorCall = null;
458                 if (isConstructor) {
459                         net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration constructorDeclaration = (net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration) methodDeclaration;
460                         explicitConstructorCall = constructorDeclaration.constructorCall;
461                         switch(this.ast.apiLevel) {
462                                 case AST.JLS2_INTERNAL :
463                                         // set the return type to VOID
464                                         PrimitiveType returnType = new PrimitiveType(this.ast);
465                                         returnType.setPrimitiveTypeCode(PrimitiveType.VOID);
466                                         returnType.setSourceRange(methodDeclaration.sourceStart, 0);
467                                         methodDecl.internalSetReturnType(returnType);
468                                         break;
469                                 case AST.JLS3 :
470                                         methodDecl.setReturnType2(null);
471                         }
472                 } else if (methodDeclaration instanceof net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration) {
473                         net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration method = (net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration) methodDeclaration;
474                         net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeReference = method.returnType;
475                         if (typeReference != null) {
476                                 Type returnType = convertType(typeReference);
477                                 // get the positions of the right parenthesis
478                                 int rightParenthesisPosition = retrieveEndOfRightParenthesisPosition(end, method.bodyEnd);
479                                 int extraDimensions = retrieveExtraDimension(rightParenthesisPosition, method.bodyEnd);
480                                 methodDecl.setExtraDimensions(extraDimensions);
481                                 setTypeForMethodDeclaration(methodDecl, returnType, extraDimensions);
482                         } else {
483                                 switch(this.ast.apiLevel) {
484                                         case AST.JLS2_INTERNAL :
485                                                 methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
486                                                 break;
487                                         case AST.JLS3 :
488                                                 methodDecl.setReturnType2(null);
489                                 }
490                         }
491                 }
492                 int declarationSourceStart = methodDeclaration.declarationSourceStart;
493                 int declarationSourceEnd = methodDeclaration.bodyEnd;
494                 methodDecl.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
495                 int closingPosition = retrieveRightBraceOrSemiColonPosition(methodDeclaration.bodyEnd + 1, methodDeclaration.declarationSourceEnd);
496                 if (closingPosition != -1) {
497                         int startPosition = methodDecl.getStartPosition();
498                         methodDecl.setSourceRange(startPosition, closingPosition - startPosition + 1);
499
500                         net.sourceforge.phpdt.internal.compiler.ast.Statement[] statements = methodDeclaration.statements;
501                         
502                         start = retrieveStartBlockPosition(methodHeaderEnd, methodDeclaration.bodyStart);
503                         if (start == -1) start = methodDeclaration.bodyStart; // use recovery position for body start
504                         end = retrieveRightBrace(methodDeclaration.bodyEnd, methodDeclaration.declarationSourceEnd);
505                         Block block = null;
506                         if (start != -1 && end != -1) {
507                                 /*
508                                  * start or end can be equal to -1 if we have an interface's method.
509                                  */
510                                 block = new Block(this.ast);
511                                 block.setSourceRange(start, closingPosition - start + 1);
512                                 methodDecl.setBody(block);
513                         }
514                         if (block != null && (statements != null || explicitConstructorCall != null)) {
515                                 if (explicitConstructorCall != null && explicitConstructorCall.accessMode != net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall.ImplicitSuper) {
516                                         block.statements().add(convert(explicitConstructorCall));
517                                 }
518                                 int statementsLength = statements == null ? 0 : statements.length;
519                                 for (int i = 0; i < statementsLength; i++) {
520                                         if (statements[i] instanceof net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) {
521                                                 checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
522                                         } else {
523                                                 final Statement statement = convert(statements[i]);
524                                                 if (statement != null) {
525                                                         block.statements().add(statement);
526                                                 }
527                                         }
528                                 }
529                         }
530                         if (block != null && (Modifier.isAbstract(methodDecl.getModifiers()) || Modifier.isNative(methodDecl.getModifiers()))) {
531                                 methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
532                         }
533                 } else {
534                         // syntax error in this method declaration
535                         methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
536                         if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract()) {
537                                 start = retrieveStartBlockPosition(methodHeaderEnd, declarationSourceEnd);
538                                 if (start == -1) start = methodDeclaration.bodyStart; // use recovery position for body start
539                                 end = methodDeclaration.bodyEnd;
540                                 // try to get the best end position
541                                 CategorizedProblem[] problems = methodDeclaration.compilationResult().problems;
542                                 if (problems != null) {
543                                         for (int i = 0, max = methodDeclaration.compilationResult().problemCount; i < max; i++) {
544                                                 CategorizedProblem currentProblem = problems[i];
545                                                 if (currentProblem.getSourceStart() == start && currentProblem.getID() == IProblem.ParsingErrorInsertToComplete) {
546                                                         end = currentProblem.getSourceEnd();
547                                                         break;
548                                                 }
549                                         }
550                                 }
551                                 int startPosition = methodDecl.getStartPosition();
552                                 methodDecl.setSourceRange(startPosition, end - startPosition + 1);
553                                 if (start != -1 && end != -1) {
554                                         /*
555                                          * start or end can be equal to -1 if we have an interface's method.
556                                          */
557                                         Block block = new Block(this.ast);
558                                         block.setSourceRange(start, end - start + 1);
559                                         methodDecl.setBody(block);
560                                 }
561                         }                       
562                 }
563
564                 net.sourceforge.phpdt.internal.compiler.ast.TypeParameter[] typeParameters = methodDeclaration.typeParameters();
565                 if (typeParameters != null) {
566                         switch(this.ast.apiLevel) {
567                                 case AST.JLS2_INTERNAL :
568                                         methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
569                                         break;
570                                 case AST.JLS3 :
571                                         for (int i = 0, max = typeParameters.length; i < max; i++) {
572                                                 methodDecl.typeParameters().add(convert(typeParameters[i]));
573                                         }
574                         }
575                 }
576                 
577                 // The javadoc comment is now got from list store in compilation unit declaration
578                 convert(methodDeclaration.javadoc, methodDecl);
579                 if (this.resolveBindings) {
580                         recordNodes(methodDecl, methodDeclaration);
581                         recordNodes(methodName, methodDeclaration);
582                         methodDecl.resolveBinding();
583                 }
584                 return methodDecl;
585         }       
586         
587         public ClassInstanceCreation convert(net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression expression) {
588                 ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
589                 if (this.resolveBindings) {
590                         recordNodes(classInstanceCreation, expression);
591                 }
592                 if (expression.typeArguments != null) {
593                         switch(this.ast.apiLevel) {
594                                 case AST.JLS2_INTERNAL :
595                                         classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
596                                         break;
597                                 case AST.JLS3 :
598                                         for (int i = 0, max = expression.typeArguments.length; i < max; i++) {
599                                                 classInstanceCreation.typeArguments().add(convertType(expression.typeArguments[i]));
600                                         }
601                         }
602                 }
603                 switch(this.ast.apiLevel) {
604                         case AST.JLS2_INTERNAL :
605                                 classInstanceCreation.internalSetName(convert(expression.type));
606                                 break;
607                         case AST.JLS3 :
608                                 classInstanceCreation.setType(convertType(expression.type));
609                 }
610                 classInstanceCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
611                 net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
612                 if (arguments != null) {
613                         int length = arguments.length;
614                         for (int i = 0; i < length; i++) {
615                                 classInstanceCreation.arguments().add(convert(arguments[i]));
616                         }
617                 }
618                 removeTrailingCommentFromExpressionEndingWithAParen(classInstanceCreation);
619                 return classInstanceCreation;
620         }
621
622         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression expression) {
623                 InfixExpression infixExpression = new InfixExpression(this.ast);
624                 infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
625                 if (this.resolveBindings) {
626                         this.recordNodes(infixExpression, expression);
627                 }
628                 final int expressionOperatorID = (expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
629                 if (expression.left instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression
630                                 && ((expression.left.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
631                         // create an extended string literal equivalent => use the extended operands list
632                         infixExpression.extendedOperands().add(convert(expression.right));
633                         net.sourceforge.phpdt.internal.compiler.ast.Expression leftOperand = expression.left;
634                         net.sourceforge.phpdt.internal.compiler.ast.Expression rightOperand = null;
635                         do {
636                                 rightOperand = ((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
637                                 if ((((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
638                                                         && ((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
639                                          || ((rightOperand instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression
640                                                         && ((rightOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
641                                                         && ((rightOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
642                                         List extendedOperands = infixExpression.extendedOperands();
643                                         InfixExpression temp = new InfixExpression(this.ast);
644                                         if (this.resolveBindings) {
645                                                 this.recordNodes(temp, expression);
646                                         }
647                                         temp.setOperator(getOperatorFor(expressionOperatorID));
648                                         Expression leftSide = convert(leftOperand);
649                                         temp.setLeftOperand(leftSide);
650                                         temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
651                                         int size = extendedOperands.size();
652                                         for (int i = 0; i < size - 1; i++) {
653                                                 Expression expr = temp;
654                                                 temp = new InfixExpression(this.ast);
655                                                 
656                                                 if (this.resolveBindings) {
657                                                         this.recordNodes(temp, expression);
658                                                 }                                       
659                                                 temp.setLeftOperand(expr);
660                                                 temp.setOperator(getOperatorFor(expressionOperatorID));
661                                                 temp.setSourceRange(expr.getStartPosition(), expr.getLength());
662                                         }
663                                         infixExpression = temp;
664                                         for (int i = 0; i < size; i++) {
665                                                 Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
666                                                 temp.setRightOperand(extendedOperand);
667                                                 int startPosition = temp.getLeftOperand().getStartPosition();
668                                                 temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
669                                                 if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
670                                                         temp = (InfixExpression) temp.getLeftOperand();
671                                                 }
672                                         }
673                                         int startPosition = infixExpression.getLeftOperand().getStartPosition();
674                                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
675                                         if (this.resolveBindings) {
676                                                 this.recordNodes(infixExpression, expression);
677                                         }
678                                         return infixExpression;
679                                 }
680                                 infixExpression.extendedOperands().add(0, convert(rightOperand));
681                                 leftOperand = ((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
682                         } while (leftOperand instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
683                         Expression leftExpression = convert(leftOperand);
684                         infixExpression.setLeftOperand(leftExpression);
685                         infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
686                         int startPosition = leftExpression.getStartPosition();
687                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
688                         return infixExpression;
689                 }
690                 Expression leftExpression = convert(expression.left);
691                 infixExpression.setLeftOperand(leftExpression);
692                 infixExpression.setRightOperand(convert(expression.right));
693                 infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
694                 int startPosition = leftExpression.getStartPosition();
695                 infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
696                 return infixExpression;
697         }
698
699         public AnnotationTypeDeclaration convertToAnnotationDeclaration(net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
700                 checkCanceled();
701                 AnnotationTypeDeclaration typeDecl = this.ast.newAnnotationTypeDeclaration();
702                 setModifiers(typeDecl, typeDeclaration);
703                 final SimpleName typeName = new SimpleName(this.ast);
704                 typeName.internalSetIdentifier(new String(typeDeclaration.name));
705                 typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
706                 typeDecl.setName(typeName);
707                 typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
708                 
709                 buildBodyDeclarations(typeDeclaration, typeDecl);
710                 // The javadoc comment is now got from list store in compilation unit declaration
711                 if (this.resolveBindings) {
712                         recordNodes(typeDecl, typeDeclaration);
713                         recordNodes(typeName, typeDeclaration);
714                         typeDecl.resolveBinding();
715                 }
716                 return typeDecl;
717         }
718         
719         public ASTNode convert(net.sourceforge.phpdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
720                 checkCanceled();
721                 if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
722                         return null;
723                 }
724                 AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration2 = new AnnotationTypeMemberDeclaration(this.ast);
725                 setModifiers(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
726                 final SimpleName methodName = new SimpleName(this.ast);
727                 methodName.internalSetIdentifier(new String(annotationTypeMemberDeclaration.selector));
728                 int start = annotationTypeMemberDeclaration.sourceStart;
729                 int end = retrieveIdentifierEndPosition(start, annotationTypeMemberDeclaration.sourceEnd);
730                 methodName.setSourceRange(start, end - start + 1);
731                 annotationTypeMemberDeclaration2.setName(methodName);
732                 net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeReference = annotationTypeMemberDeclaration.returnType;
733                 if (typeReference != null) {
734                         Type returnType = convertType(typeReference);
735                         setTypeForMethodDeclaration(annotationTypeMemberDeclaration2, returnType, 0);
736                 }
737                 int declarationSourceStart = annotationTypeMemberDeclaration.declarationSourceStart;
738                 int declarationSourceEnd = annotationTypeMemberDeclaration.bodyEnd;
739                 annotationTypeMemberDeclaration2.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
740                 // The javadoc comment is now got from list store in compilation unit declaration
741                 convert(annotationTypeMemberDeclaration.javadoc, annotationTypeMemberDeclaration2);
742                 net.sourceforge.phpdt.internal.compiler.ast.Expression memberValue = annotationTypeMemberDeclaration.defaultValue;
743                 if (memberValue != null) {
744                         annotationTypeMemberDeclaration2.setDefault(convert(memberValue));
745                 }
746                 if (this.resolveBindings) {
747                         recordNodes(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
748                         recordNodes(methodName, annotationTypeMemberDeclaration);
749                         annotationTypeMemberDeclaration2.resolveBinding();
750                 }
751                 return annotationTypeMemberDeclaration2;
752         }
753         
754         public SingleVariableDeclaration convert(net.sourceforge.phpdt.internal.compiler.ast.Argument argument) {
755                 SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
756                 setModifiers(variableDecl, argument);
757                 final SimpleName name = new SimpleName(this.ast);
758                 name.internalSetIdentifier(new String(argument.name));
759                 int start = argument.sourceStart;
760                 int nameEnd = argument.sourceEnd;
761                 name.setSourceRange(start, nameEnd - start + 1);
762                 variableDecl.setName(name);
763                 final int typeSourceEnd = argument.type.sourceEnd;
764                 final int extraDimensions = retrieveExtraDimension(nameEnd + 1, typeSourceEnd);
765                 variableDecl.setExtraDimensions(extraDimensions);
766                 final boolean isVarArgs = argument.isVarArgs();
767                 if (isVarArgs && extraDimensions == 0) {
768                         // remove the ellipsis from the type source end
769                         argument.type.sourceEnd = retrieveEllipsisStartPosition(argument.type.sourceStart, typeSourceEnd);
770                 }
771                 Type type = convertType(argument.type);
772                 int typeEnd = type.getStartPosition() + type.getLength() - 1;
773                 int rightEnd = Math.max(typeEnd, argument.declarationSourceEnd);
774                 /*
775                  * There is extra work to do to set the proper type positions
776                  * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
777                  */
778                 if (isVarArgs) {
779                         setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions + 1);
780                         if (extraDimensions != 0) {
781                                 variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
782                         }
783                 } else {
784                         setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
785                 }
786                 variableDecl.setSourceRange(argument.declarationSourceStart, rightEnd - argument.declarationSourceStart + 1);
787                 
788                 if (isVarArgs) {
789                         switch(this.ast.apiLevel) {
790                                 case AST.JLS2_INTERNAL :
791                                         variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
792                                         break;
793                                 case AST.JLS3 :
794                                         variableDecl.setVarargs(true);
795                         }
796                 }
797                 if (this.resolveBindings) {
798                         recordNodes(name, argument);
799                         recordNodes(variableDecl, argument);
800                         variableDecl.resolveBinding();
801                 }
802                 return variableDecl;
803         }
804
805         
806         public Annotation convert(net.sourceforge.phpdt.internal.compiler.ast.Annotation annotation) {
807                 if (annotation instanceof net.sourceforge.phpdt.internal.compiler.ast.SingleMemberAnnotation) {
808                         return convert((net.sourceforge.phpdt.internal.compiler.ast.SingleMemberAnnotation) annotation);
809                 } else if (annotation instanceof net.sourceforge.phpdt.internal.compiler.ast.MarkerAnnotation) {
810                         return convert((net.sourceforge.phpdt.internal.compiler.ast.MarkerAnnotation) annotation);
811                 } else {
812                         return convert((net.sourceforge.phpdt.internal.compiler.ast.NormalAnnotation) annotation);
813                 }
814         }
815
816         public ArrayCreation convert(net.sourceforge.phpdt.internal.compiler.ast.ArrayAllocationExpression expression) {
817                 ArrayCreation arrayCreation = new ArrayCreation(this.ast);
818                 if (this.resolveBindings) {
819                         recordNodes(arrayCreation, expression);
820                 }
821                 arrayCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
822                 net.sourceforge.phpdt.internal.compiler.ast.Expression[] dimensions = expression.dimensions;
823                 
824                 int dimensionsLength = dimensions.length;
825                 for (int i = 0; i < dimensionsLength; i++) {
826                         if (dimensions[i] != null) {
827                                 Expression dimension = convert(dimensions[i]);
828                                 if (this.resolveBindings) {
829                                         recordNodes(dimension, dimensions[i]);
830                                 }
831                                 arrayCreation.dimensions().add(dimension);
832                         }
833                 }
834                 Type type = convertType(expression.type);
835                 if (this.resolveBindings) {
836                         recordNodes(type, expression.type);
837                 }               
838                 ArrayType arrayType = null;
839                 if (type.isArrayType()) {
840                         arrayType = (ArrayType) type;
841                 } else {
842                         arrayType = this.ast.newArrayType(type, dimensionsLength);
843                         if (this.resolveBindings) {
844                                 completeRecord(arrayType, expression);
845                         }                       
846                         int start = type.getStartPosition();
847                         int end = type.getStartPosition() + type.getLength();
848                         int previousSearchStart = end - 1;
849                         ArrayType componentType = (ArrayType) type.getParent();
850                         for (int i = 0; i < dimensionsLength; i++) {
851                                 previousSearchStart = retrieveRightBracketPosition(previousSearchStart + 1, this.compilationUnitSourceLength);
852                                 componentType.setSourceRange(start, previousSearchStart - start + 1);
853                                 componentType = (ArrayType) componentType.getParent();
854                         }
855                 }
856                 arrayCreation.setType(arrayType);
857                 if (this.resolveBindings) {
858                         recordNodes(arrayType, expression);
859                 }       
860                 if (expression.initializer != null) {
861                         arrayCreation.setInitializer(convert(expression.initializer));
862                 }
863                 return arrayCreation;
864         }
865
866         public ArrayInitializer convert(net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer expression) {
867                 ArrayInitializer arrayInitializer = new ArrayInitializer(this.ast);
868                 if (this.resolveBindings) {
869                         recordNodes(arrayInitializer, expression);
870                 }
871                 arrayInitializer.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
872                 net.sourceforge.phpdt.internal.compiler.ast.Expression[] expressions = expression.expressions;
873                 if (expressions != null) {
874                         int length = expressions.length;
875                         for (int i = 0; i < length; i++) {
876                                 Expression expr = convert(expressions[i]);
877                                 if (this.resolveBindings) {
878                                         recordNodes(expr, expressions[i]);
879                                 }
880                                 arrayInitializer.expressions().add(expr);
881                         }
882                 }
883                 return arrayInitializer;
884         }
885
886         public ArrayAccess convert(net.sourceforge.phpdt.internal.compiler.ast.ArrayReference reference) {
887                 ArrayAccess arrayAccess = new ArrayAccess(this.ast);
888                 if (this.resolveBindings) {
889                         recordNodes(arrayAccess, reference);
890                 }
891                 arrayAccess.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
892                 arrayAccess.setArray(convert(reference.receiver));
893                 arrayAccess.setIndex(convert(reference.position));
894                 return arrayAccess;
895         }
896
897         public AssertStatement convert(net.sourceforge.phpdt.internal.compiler.ast.AssertStatement statement) {
898                 AssertStatement assertStatement = new AssertStatement(this.ast);
899                 final Expression assertExpression = convert(statement.assertExpression);
900                 Expression searchingNode = assertExpression;
901                 assertStatement.setExpression(assertExpression);
902                 net.sourceforge.phpdt.internal.compiler.ast.Expression exceptionArgument = statement.exceptionArgument;
903                 if (exceptionArgument != null) {
904                         final Expression exceptionMessage = convert(exceptionArgument);
905                         assertStatement.setMessage(exceptionMessage);
906                         searchingNode = exceptionMessage;
907                 }
908                 int start = statement.sourceStart;
909                 int sourceEnd = retrieveSemiColonPosition(searchingNode);
910                 if (sourceEnd == -1) {
911                         sourceEnd = searchingNode.getStartPosition() + searchingNode.getLength() - 1;
912                         assertStatement.setSourceRange(start, sourceEnd - start + 1);
913                 } else {
914                         assertStatement.setSourceRange(start, sourceEnd - start + 1);
915                 }
916                 return assertStatement;
917         }
918         
919         public Assignment convert(net.sourceforge.phpdt.internal.compiler.ast.Assignment expression) {
920                 Assignment assignment = new Assignment(this.ast);
921                 if (this.resolveBindings) {
922                         recordNodes(assignment, expression);
923                 }
924                 Expression lhs = convert(expression.lhs);
925                 assignment.setLeftHandSide(lhs);
926                 assignment.setOperator(Assignment.Operator.ASSIGN);
927                 assignment.setRightHandSide(convert(expression.expression));
928                 int start = lhs.getStartPosition();
929                 assignment.setSourceRange(start, expression.sourceEnd - start + 1);
930                 return assignment;
931         }
932
933         /*
934          * Internal use only
935          * Used to convert class body declarations
936          */
937         public TypeDeclaration convert(net.sourceforge.phpdt.internal.compiler.ast.ASTNode[] nodes) {
938                 final TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
939                 typeDecl.setInterface(false);
940                 int nodesLength = nodes.length;
941                 for (int i = 0; i < nodesLength; i++) {
942                         net.sourceforge.phpdt.internal.compiler.ast.ASTNode node = nodes[i];
943                         if (node instanceof net.sourceforge.phpdt.internal.compiler.ast.Initializer) {
944                                 net.sourceforge.phpdt.internal.compiler.ast.Initializer oldInitializer = (net.sourceforge.phpdt.internal.compiler.ast.Initializer) node;
945                                 Initializer initializer = new Initializer(this.ast);
946                                 initializer.setBody(convert(oldInitializer.block));
947                                 setModifiers(initializer, oldInitializer);
948                                 initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
949 //                              setJavaDocComment(initializer);
950 //                              initializer.setJavadoc(convert(oldInitializer.javadoc));
951                                 convert(oldInitializer.javadoc, initializer);
952                                 typeDecl.bodyDeclarations().add(initializer);
953                         } else if (node instanceof net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration) {
954                                 net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration) node;
955                                 if (i > 0
956                                         && (nodes[i - 1] instanceof net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration)
957                                         && ((net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration)nodes[i - 1]).declarationSourceStart == fieldDeclaration.declarationSourceStart) {
958                                         // we have a multiple field declaration
959                                         // We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
960                                         FieldDeclaration currentFieldDeclaration = (FieldDeclaration) typeDecl.bodyDeclarations().get(typeDecl.bodyDeclarations().size() - 1);
961                                         currentFieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fieldDeclaration));
962                                 } else {
963                                         // we can create a new FieldDeclaration
964                                         typeDecl.bodyDeclarations().add(convertToFieldDeclaration(fieldDeclaration));
965                                 }
966                         } else if(node instanceof net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration) {
967                                 AbstractMethodDeclaration nextMethodDeclaration = (AbstractMethodDeclaration) node;
968                                 if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
969                                         typeDecl.bodyDeclarations().add(convert(nextMethodDeclaration));
970                                 }
971                         } else if(node instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) {
972                                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = (net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) node;
973                                 ASTNode nextMemberDeclarationNode = convert(nextMemberDeclaration);
974                                 if (nextMemberDeclarationNode == null) {
975                                         typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
976                                 } else {
977                                         typeDecl.bodyDeclarations().add(nextMemberDeclarationNode);
978                                 }
979                         }
980                 }
981                 return typeDecl;
982         }
983         
984         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression expression) {
985                 InfixExpression infixExpression = new InfixExpression(this.ast);
986                 if (this.resolveBindings) {
987                         this.recordNodes(infixExpression, expression);
988                 }
989
990                 int expressionOperatorID = (expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
991                 switch (expressionOperatorID) {
992                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
993                                 infixExpression.setOperator(InfixExpression.Operator.EQUALS);
994                                 break;
995                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
996                                 infixExpression.setOperator(InfixExpression.Operator.LESS_EQUALS);
997                                 break;
998                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
999                                 infixExpression.setOperator(InfixExpression.Operator.GREATER_EQUALS);
1000                                 break;
1001                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
1002                                 infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
1003                                 break;
1004                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
1005                                 infixExpression.setOperator(InfixExpression.Operator.LEFT_SHIFT);
1006                                 break;
1007                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
1008                                 infixExpression.setOperator(InfixExpression.Operator.RIGHT_SHIFT_SIGNED);
1009                                 break;
1010                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
1011                                 infixExpression.setOperator(InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED);
1012                                 break;
1013                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.OR_OR :
1014                                 infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
1015                                 break;
1016                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.AND_AND :
1017                                 infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
1018                                 break;
1019                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.PLUS :
1020                                 infixExpression.setOperator(InfixExpression.Operator.PLUS);
1021                                 break;
1022                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MINUS :
1023                                 infixExpression.setOperator(InfixExpression.Operator.MINUS);
1024                                 break;
1025                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.REMAINDER :
1026                                 infixExpression.setOperator(InfixExpression.Operator.REMAINDER);
1027                                 break;
1028                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.XOR :
1029                                 infixExpression.setOperator(InfixExpression.Operator.XOR);
1030                                 break;
1031                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.AND :
1032                                 infixExpression.setOperator(InfixExpression.Operator.AND);
1033                                 break;
1034                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MULTIPLY :
1035                                 infixExpression.setOperator(InfixExpression.Operator.TIMES);
1036                                 break;
1037                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.OR :
1038                                 infixExpression.setOperator(InfixExpression.Operator.OR);
1039                                 break;
1040                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.DIVIDE :
1041                                 infixExpression.setOperator(InfixExpression.Operator.DIVIDE);
1042                                 break;
1043                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.GREATER :
1044                                 infixExpression.setOperator(InfixExpression.Operator.GREATER);
1045                                 break;
1046                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LESS :
1047                                 infixExpression.setOperator(InfixExpression.Operator.LESS);
1048                 }
1049                 
1050                 if (expression.left instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression
1051                                 && ((expression.left.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
1052                         // create an extended string literal equivalent => use the extended operands list
1053                         infixExpression.extendedOperands().add(convert(expression.right));
1054                         net.sourceforge.phpdt.internal.compiler.ast.Expression leftOperand = expression.left;
1055                         net.sourceforge.phpdt.internal.compiler.ast.Expression rightOperand = null;
1056                         do {
1057                                 rightOperand = ((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
1058                                 if ((((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
1059                                                         && ((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
1060                                          || ((rightOperand instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression
1061                                                         && ((rightOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
1062                                                         && ((rightOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
1063                                         List extendedOperands = infixExpression.extendedOperands();
1064                                         InfixExpression temp = new InfixExpression(this.ast);
1065                                         if (this.resolveBindings) {
1066                                                 this.recordNodes(temp, expression);
1067                                         }
1068                                         temp.setOperator(getOperatorFor(expressionOperatorID));
1069                                         Expression leftSide = convert(leftOperand);
1070                                         temp.setLeftOperand(leftSide);
1071                                         temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
1072                                         int size = extendedOperands.size();
1073                                         for (int i = 0; i < size - 1; i++) {
1074                                                 Expression expr = temp;
1075                                                 temp = new InfixExpression(this.ast);
1076                                                 
1077                                                 if (this.resolveBindings) {
1078                                                         this.recordNodes(temp, expression);
1079                                                 }                                       
1080                                                 temp.setLeftOperand(expr);
1081                                                 temp.setOperator(getOperatorFor(expressionOperatorID));
1082                                                 temp.setSourceRange(expr.getStartPosition(), expr.getLength());
1083                                         }
1084                                         infixExpression = temp;
1085                                         for (int i = 0; i < size; i++) {
1086                                                 Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
1087                                                 temp.setRightOperand(extendedOperand);
1088                                                 int startPosition = temp.getLeftOperand().getStartPosition();
1089                                                 temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
1090                                                 if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
1091                                                         temp = (InfixExpression) temp.getLeftOperand();
1092                                                 }
1093                                         }
1094                                         int startPosition = infixExpression.getLeftOperand().getStartPosition();
1095                                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1096                                         if (this.resolveBindings) {
1097                                                 this.recordNodes(infixExpression, expression);
1098                                         }
1099                                         return infixExpression;
1100                                 }
1101                                 infixExpression.extendedOperands().add(0, convert(rightOperand));
1102                                 leftOperand = ((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
1103                         } while (leftOperand instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
1104                         Expression leftExpression = convert(leftOperand);
1105                         infixExpression.setLeftOperand(leftExpression);
1106                         infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
1107                         int startPosition = leftExpression.getStartPosition();
1108                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1109                         return infixExpression;
1110                 } else if (expression.left instanceof StringLiteralConcatenation
1111                                 && ((expression.left.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)
1112                                 && (OperatorIds.PLUS == expressionOperatorID)) {
1113                         StringLiteralConcatenation literal = (StringLiteralConcatenation) expression.left;
1114                         final net.sourceforge.phpdt.internal.compiler.ast.Expression[] stringLiterals = literal.literals;
1115                         infixExpression.setLeftOperand(convert(stringLiterals[0]));
1116                         infixExpression.setRightOperand(convert(stringLiterals[1]));
1117                         for (int i = 2; i < literal.counter; i++) {
1118                                 infixExpression.extendedOperands().add(convert(stringLiterals[i]));
1119                         }
1120                         infixExpression.extendedOperands().add(convert(expression.right));
1121                         int startPosition = literal.sourceStart;
1122                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1123                         return infixExpression;
1124                 }
1125                 Expression leftExpression = convert(expression.left);
1126                 infixExpression.setLeftOperand(leftExpression);
1127                 infixExpression.setRightOperand(convert(expression.right));
1128                 int startPosition = leftExpression.getStartPosition();
1129                 infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1130                 return infixExpression;
1131         }
1132
1133         public Block convert(net.sourceforge.phpdt.internal.compiler.ast.Block statement) {
1134                 Block block = new Block(this.ast);
1135                 if (statement.sourceEnd > 0) {
1136                         block.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1137                 }
1138                 net.sourceforge.phpdt.internal.compiler.ast.Statement[] statements = statement.statements;
1139                 if (statements != null) {
1140                         int statementsLength = statements.length;
1141                         for (int i = 0; i < statementsLength; i++) {
1142                                 if (statements[i] instanceof net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) {
1143                                         checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
1144                                 } else {
1145                                         Statement statement2 = convert(statements[i]);
1146                                         if (statement2 != null) {
1147                                                 block.statements().add(statement2);
1148                                         }
1149                                 }                               
1150                         }
1151                 }
1152                 return block;
1153         }
1154         
1155         public BreakStatement convert(net.sourceforge.phpdt.internal.compiler.ast.BreakStatement statement)  {
1156                 BreakStatement breakStatement = new BreakStatement(this.ast);
1157                 breakStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1158                 if (statement.label != null) {
1159                         final SimpleName name = new SimpleName(this.ast);
1160                         name.internalSetIdentifier(new String(statement.label));
1161                         retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
1162                         breakStatement.setLabel(name);
1163                 }
1164                 return breakStatement;
1165         }
1166                 
1167                 
1168         public SwitchCase convert(net.sourceforge.phpdt.internal.compiler.ast.CaseStatement statement) {
1169                 SwitchCase switchCase = new SwitchCase(this.ast);
1170                 net.sourceforge.phpdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
1171                 if (constantExpression == null) {
1172                         switchCase.setExpression(null);
1173                 } else {
1174                         switchCase.setExpression(convert(constantExpression));
1175                 }
1176                 switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1177                 retrieveColonPosition(switchCase);
1178                 return switchCase;
1179         }
1180
1181         public CastExpression convert(net.sourceforge.phpdt.internal.compiler.ast.CastExpression expression) {
1182                 CastExpression castExpression = new CastExpression(this.ast);
1183                 castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1184                 net.sourceforge.phpdt.internal.compiler.ast.Expression type = expression.type;
1185                 trimWhiteSpacesAndComments(type);
1186                 if (type instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeReference ) {
1187                         castExpression.setType(convertType((net.sourceforge.phpdt.internal.compiler.ast.TypeReference)type));
1188                 } else if (type instanceof net.sourceforge.phpdt.internal.compiler.ast.NameReference) {
1189                         castExpression.setType(convertToType((net.sourceforge.phpdt.internal.compiler.ast.NameReference)type));
1190                 }
1191                 castExpression.setExpression(convert(expression.expression));
1192                 if (this.resolveBindings) {
1193                         recordNodes(castExpression, expression);
1194                 }
1195                 return castExpression;
1196         }
1197
1198         public CharacterLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.CharLiteral expression) {
1199                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1200                 int sourceStart = expression.sourceStart;
1201                 CharacterLiteral literal = new CharacterLiteral(this.ast);
1202                 if (this.resolveBindings) {
1203                         this.recordNodes(literal, expression);
1204                 }
1205                 literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
1206                 literal.setSourceRange(sourceStart, length);
1207                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1208                 return literal;
1209         }
1210         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.ClassLiteralAccess expression) {
1211                 TypeLiteral typeLiteral = new TypeLiteral(this.ast);
1212                 if (this.resolveBindings) {
1213                         this.recordNodes(typeLiteral, expression);
1214                 }
1215                 typeLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1216                 typeLiteral.setType(convertType(expression.type));
1217                 return typeLiteral;
1218         }
1219         
1220         public CompilationUnit convert(net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
1221                 if(unit.compilationResult.recoveryScannerData != null) {
1222                         RecoveryScanner recoveryScanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused());
1223                         this.scanner = recoveryScanner;
1224                         this.docParser.scanner = this.scanner;
1225                 }
1226                 this.compilationUnitSource = source;
1227                 this.compilationUnitSourceLength = source.length;
1228                 this.scanner.setSource(source, unit.compilationResult);
1229                 CompilationUnit compilationUnit = new CompilationUnit(this.ast);
1230
1231                 // Parse comments
1232                 int[][] comments = unit.comments;
1233                 if (comments != null) {
1234                         buildCommentsTable(compilationUnit, comments);
1235                 }
1236
1237                 // handle the package declaration immediately
1238                 // There is no node corresponding to the package declaration
1239                 if (this.resolveBindings) {
1240                         recordNodes(compilationUnit, unit);
1241                 }
1242                 if (unit.currentPackage != null) {
1243                         PackageDeclaration packageDeclaration = convertPackage(unit);
1244                         compilationUnit.setPackage(packageDeclaration);
1245                 }
1246                 net.sourceforge.phpdt.internal.compiler.ast.ImportReference[] imports = unit.imports;
1247                 if (imports != null) {
1248                         int importLength = imports.length;
1249                         for (int i = 0; i < importLength; i++) {
1250                                 compilationUnit.imports().add(convertImport(imports[i]));
1251                         }
1252                 }
1253
1254                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration[] types = unit.types;
1255                 if (types != null) {
1256                         int typesLength = types.length;
1257                         for (int i = 0; i < typesLength; i++) {
1258                                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration declaration = types[i];
1259                                 if (CharOperation.equals(declaration.name, TypeConstants.PACKAGE_INFO_NAME)) {
1260                                         continue;
1261                                 }
1262                                 ASTNode type = convert(declaration);
1263                                 if (type == null) {
1264                                         compilationUnit.setFlags(compilationUnit.getFlags() | ASTNode.MALFORMED);
1265                                 } else {
1266                                         compilationUnit.types().add(type);
1267                                 }
1268                         }
1269                 }
1270                 compilationUnit.setSourceRange(unit.sourceStart, unit.sourceEnd - unit.sourceStart  + 1);
1271                 
1272                 int problemLength = unit.compilationResult.problemCount;
1273                 if (problemLength != 0) {
1274                         CategorizedProblem[] resizedProblems = null;
1275                         final CategorizedProblem[] problems = unit.compilationResult.getProblems();
1276                         final int realProblemLength=problems.length;
1277                         if (realProblemLength == problemLength) {
1278                                 resizedProblems = problems;
1279                         } else {
1280                                 System.arraycopy(problems, 0, (resizedProblems = new CategorizedProblem[realProblemLength]), 0, realProblemLength);
1281                         }
1282                         ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
1283                         compilationUnit.accept(syntaxErrorPropagator);
1284                         ASTRecoveryPropagator recoveryPropagator =
1285                                 new ASTRecoveryPropagator(resizedProblems, unit.compilationResult.recoveryScannerData);
1286                         compilationUnit.accept(recoveryPropagator);
1287                         compilationUnit.setProblems(resizedProblems);
1288                 }
1289                 if (this.resolveBindings) {
1290                         lookupForScopes();
1291                 }
1292                 compilationUnit.initCommentMapper(this.scanner);
1293                 return compilationUnit;
1294         }
1295
1296         public Assignment convert(net.sourceforge.phpdt.internal.compiler.ast.CompoundAssignment expression) {
1297                 Assignment assignment = new Assignment(this.ast);
1298                 Expression lhs = convert(expression.lhs);
1299                 assignment.setLeftHandSide(lhs);
1300                 int start = lhs.getStartPosition();
1301                 assignment.setSourceRange(start, expression.sourceEnd - start + 1);
1302                 switch (expression.operator) {
1303                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.PLUS :
1304                                 assignment.setOperator(Assignment.Operator.PLUS_ASSIGN);
1305                                 break;
1306                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MINUS :
1307                                 assignment.setOperator(Assignment.Operator.MINUS_ASSIGN);
1308                                 break;
1309                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MULTIPLY :
1310                                 assignment.setOperator(Assignment.Operator.TIMES_ASSIGN);
1311                                 break;
1312                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.DIVIDE :
1313                                 assignment.setOperator(Assignment.Operator.DIVIDE_ASSIGN);
1314                                 break;
1315                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.AND :
1316                                 assignment.setOperator(Assignment.Operator.BIT_AND_ASSIGN);
1317                                 break;
1318                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.OR :
1319                                 assignment.setOperator(Assignment.Operator.BIT_OR_ASSIGN);
1320                                 break;
1321                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.XOR :
1322                                 assignment.setOperator(Assignment.Operator.BIT_XOR_ASSIGN);
1323                                 break;
1324                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.REMAINDER :
1325                                 assignment.setOperator(Assignment.Operator.REMAINDER_ASSIGN);
1326                                 break;
1327                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
1328                                 assignment.setOperator(Assignment.Operator.LEFT_SHIFT_ASSIGN);
1329                                 break;
1330                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
1331                                 assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN);
1332                                 break;
1333                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
1334                                 assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN);
1335                                 break;
1336                 }
1337                 assignment.setRightHandSide(convert(expression.expression));
1338                 if (this.resolveBindings) {
1339                         recordNodes(assignment, expression);
1340                 }
1341                 return assignment;
1342         }
1343
1344         public ConditionalExpression convert(net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression expression) {
1345                 ConditionalExpression conditionalExpression = new ConditionalExpression(this.ast);
1346                 if (this.resolveBindings) {
1347                         recordNodes(conditionalExpression, expression);
1348                 }
1349                 conditionalExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1350                 conditionalExpression.setExpression(convert(expression.condition));
1351                 conditionalExpression.setThenExpression(convert(expression.valueIfTrue));
1352                 conditionalExpression.setElseExpression(convert(expression.valueIfFalse));
1353                 return conditionalExpression;
1354         }
1355
1356         public ContinueStatement convert(net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement statement)  {
1357                 ContinueStatement continueStatement = new ContinueStatement(this.ast);
1358                 continueStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1359                 if (statement.label != null) {
1360                         final SimpleName name = new SimpleName(this.ast);
1361                         name.internalSetIdentifier(new String(statement.label));
1362                         retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
1363                         continueStatement.setLabel(name);
1364                 }
1365                 return continueStatement;
1366         }
1367         
1368         public DoStatement convert(net.sourceforge.phpdt.internal.compiler.ast.DoStatement statement) {
1369                 DoStatement doStatement = new DoStatement(this.ast);
1370                 doStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1371                 doStatement.setExpression(convert(statement.condition));
1372                 final Statement action = convert(statement.action);
1373                 if (action == null) return null;
1374                 doStatement.setBody(action);
1375                 return doStatement;
1376         }
1377
1378         public NumberLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.DoubleLiteral expression) {
1379                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1380                 int sourceStart = expression.sourceStart;
1381                 NumberLiteral literal = new NumberLiteral(this.ast);
1382                 literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
1383                 if (this.resolveBindings) {
1384                         this.recordNodes(literal, expression);
1385                 }
1386                 literal.setSourceRange(sourceStart, length);
1387                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1388                 return literal;
1389         }
1390         
1391         public EmptyStatement convert(net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement statement) {
1392                 EmptyStatement emptyStatement = new EmptyStatement(this.ast);
1393                 emptyStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1394                 return emptyStatement;
1395         }
1396         
1397         // field is an enum constant
1398         public EnumConstantDeclaration convert(net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration enumConstant) {
1399                 checkCanceled();
1400                 EnumConstantDeclaration enumConstantDeclaration = new EnumConstantDeclaration(this.ast);
1401                 final SimpleName typeName = new SimpleName(this.ast);
1402                 typeName.internalSetIdentifier(new String(enumConstant.name));
1403                 typeName.setSourceRange(enumConstant.sourceStart, enumConstant.sourceEnd - enumConstant.sourceStart + 1);
1404                 enumConstantDeclaration.setName(typeName);
1405                 int declarationSourceStart = enumConstant.declarationSourceStart;
1406                 int declarationSourceEnd = enumConstant.declarationSourceEnd;
1407                 final net.sourceforge.phpdt.internal.compiler.ast.Expression initialization = enumConstant.initialization;
1408                 if (initialization != null) {
1409                         if (initialization instanceof QualifiedAllocationExpression) {
1410                                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration anonymousType = ((QualifiedAllocationExpression) initialization).anonymousType;
1411                                 if (anonymousType != null) {
1412                                         AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
1413                                         int start = retrieveStartBlockPosition(anonymousType.sourceEnd, anonymousType.bodyEnd);
1414                                         int end = retrieveRightBrace(anonymousType.bodyEnd, declarationSourceEnd);
1415                                         if (end == -1) end = anonymousType.bodyEnd;
1416                                         anonymousClassDeclaration.setSourceRange(start, end - start + 1);
1417                                         enumConstantDeclaration.setAnonymousClassDeclaration(anonymousClassDeclaration);
1418                                         buildBodyDeclarations(anonymousType, anonymousClassDeclaration);
1419                                         if (this.resolveBindings) {
1420                                                 recordNodes(anonymousClassDeclaration, anonymousType);
1421                                                 anonymousClassDeclaration.resolveBinding();
1422                                         }
1423                                         enumConstantDeclaration.setSourceRange(declarationSourceStart, end - declarationSourceStart + 1);
1424                                 }
1425                         } else {
1426                                 enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
1427                         }
1428                         final net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = ((net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression) initialization).arguments;
1429                         if (arguments != null) {
1430                                 for (int i = 0, max = arguments.length; i < max; i++) {
1431                                         enumConstantDeclaration.arguments().add(convert(arguments[i]));
1432                                 }
1433                         }
1434                 } else {
1435                         enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
1436                 }
1437                 setModifiers(enumConstantDeclaration, enumConstant);
1438                 if (this.resolveBindings) {
1439                         recordNodes(enumConstantDeclaration, enumConstant);
1440                         recordNodes(typeName, enumConstant);
1441                         enumConstantDeclaration.resolveVariable();
1442                 }
1443                 convert(enumConstant.javadoc, enumConstantDeclaration);
1444                 return enumConstantDeclaration;
1445         }
1446
1447         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.EqualExpression expression) {
1448                 InfixExpression infixExpression = new InfixExpression(this.ast);
1449                 if (this.resolveBindings) {
1450                         recordNodes(infixExpression, expression);
1451                 }
1452                 Expression leftExpression = convert(expression.left);
1453                 infixExpression.setLeftOperand(leftExpression);
1454                 infixExpression.setRightOperand(convert(expression.right));
1455                 int startPosition = leftExpression.getStartPosition();
1456                 infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1457                 switch ((expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
1458                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
1459                                 infixExpression.setOperator(InfixExpression.Operator.EQUALS);
1460                                 break;
1461                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
1462                                 infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
1463                 }
1464                 return infixExpression;
1465         
1466         }
1467         
1468         public Statement convert(net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall statement) {
1469                 Statement newStatement;
1470                 int sourceStart = statement.sourceStart;
1471                 if (statement.isSuperAccess() || statement.isSuper()) {
1472                         SuperConstructorInvocation superConstructorInvocation = new SuperConstructorInvocation(this.ast);
1473                         if (statement.qualification != null) {
1474                                 superConstructorInvocation.setExpression(convert(statement.qualification));
1475                         }
1476                         net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
1477                         if (arguments != null) {
1478                                 int length = arguments.length;
1479                                 for (int i = 0; i < length; i++) {
1480                                         superConstructorInvocation.arguments().add(convert(arguments[i]));
1481                                 }
1482                         }
1483                         if (statement.typeArguments != null) {
1484                                 if (sourceStart > statement.typeArgumentsSourceStart) {
1485                                         sourceStart = statement.typeArgumentsSourceStart;
1486                                 }
1487                                 switch(this.ast.apiLevel) {
1488                                         case AST.JLS2_INTERNAL :
1489                                                 superConstructorInvocation.setFlags(superConstructorInvocation.getFlags() | ASTNode.MALFORMED);
1490                                                 break;
1491                                         case AST.JLS3 :
1492                                                 for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
1493                                                         superConstructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
1494                                                 }
1495                                                 break;
1496                                 }
1497                         }
1498                         newStatement = superConstructorInvocation;
1499                 } else {
1500                         ConstructorInvocation constructorInvocation = new ConstructorInvocation(this.ast);
1501                         net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
1502                         if (arguments != null) {
1503                                 int length = arguments.length;
1504                                 for (int i = 0; i < length; i++) {
1505                                         constructorInvocation.arguments().add(convert(arguments[i]));
1506                                 }
1507                         }
1508                         if (statement.typeArguments != null) {
1509                                 if (sourceStart > statement.typeArgumentsSourceStart) {
1510                                         sourceStart = statement.typeArgumentsSourceStart;
1511                                 }
1512                                 switch(this.ast.apiLevel) {
1513                                         case AST.JLS2_INTERNAL :
1514                                                 constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
1515                                                 break;
1516                                         case AST.JLS3 :
1517                                                 for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
1518                                                         constructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
1519                                                 }
1520                                         break;
1521                                 }
1522                         }
1523                         if (statement.qualification != null) {
1524                                 // this is an error
1525                                 constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
1526                         }
1527                         newStatement = constructorInvocation;
1528                 }
1529                 newStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
1530                 if (this.resolveBindings) {
1531                         recordNodes(newStatement, statement);
1532                 }
1533                 return newStatement;
1534         }
1535
1536         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.Expression expression) {
1537                 if ((expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
1538                         return convertToParenthesizedExpression(expression);
1539                 }
1540                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.Annotation) {
1541                         return convert((net.sourceforge.phpdt.internal.compiler.ast.Annotation) expression);
1542                 }               
1543                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.CastExpression) {
1544                         return convert((net.sourceforge.phpdt.internal.compiler.ast.CastExpression) expression);
1545                 }
1546                 // switch between all types of expression
1547                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.ArrayAllocationExpression) {
1548                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ArrayAllocationExpression) expression);
1549                 }
1550                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression) {
1551                         return convert((net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression) expression);
1552                 }
1553                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression) {
1554                         return convert((net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression) expression);
1555                 }
1556                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer) {
1557                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer) expression);
1558                 }
1559                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression) {
1560                         return convert((net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression) expression);
1561                 }
1562                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression) {
1563                         return convert((net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression) expression);
1564                 }
1565                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.CompoundAssignment) {
1566                         return convert((net.sourceforge.phpdt.internal.compiler.ast.CompoundAssignment) expression);
1567                 }
1568                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.Assignment) {
1569                         return convert((net.sourceforge.phpdt.internal.compiler.ast.Assignment) expression);
1570                 }
1571                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.ClassLiteralAccess) {
1572                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ClassLiteralAccess) expression);
1573                 }
1574                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral) {
1575                         return convert((net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral) expression);
1576                 }
1577                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral) {
1578                         return convert((net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral) expression);
1579                 }
1580                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.NullLiteral) {
1581                         return convert((net.sourceforge.phpdt.internal.compiler.ast.NullLiteral) expression);
1582                 }
1583                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.CharLiteral) {
1584                         return convert((net.sourceforge.phpdt.internal.compiler.ast.CharLiteral) expression);
1585                 }
1586                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.DoubleLiteral) {
1587                         return convert((net.sourceforge.phpdt.internal.compiler.ast.DoubleLiteral) expression);
1588                 }
1589                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.FloatLiteral) {
1590                         return convert((net.sourceforge.phpdt.internal.compiler.ast.FloatLiteral) expression);
1591                 }
1592                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.IntLiteralMinValue) {
1593                         return convert((net.sourceforge.phpdt.internal.compiler.ast.IntLiteralMinValue) expression);
1594                 }
1595                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.IntLiteral) {
1596                         return convert((net.sourceforge.phpdt.internal.compiler.ast.IntLiteral) expression);
1597                 }
1598                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.LongLiteralMinValue) {
1599                         return convert((net.sourceforge.phpdt.internal.compiler.ast.LongLiteralMinValue) expression);
1600                 }                               
1601                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.LongLiteral) {
1602                         return convert((net.sourceforge.phpdt.internal.compiler.ast.LongLiteral) expression);
1603                 }
1604                 if (expression instanceof StringLiteralConcatenation) {
1605                         return convert((StringLiteralConcatenation) expression);
1606                 }
1607                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.ExtendedStringLiteral) {
1608                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ExtendedStringLiteral) expression);
1609                 }       
1610                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.StringLiteral) {
1611                         return convert((net.sourceforge.phpdt.internal.compiler.ast.StringLiteral) expression);
1612                 }                               
1613                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression) {
1614                         return convert((net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression) expression);
1615                 }                               
1616                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression) {
1617                         return convert((net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression) expression);
1618                 }                               
1619                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.EqualExpression) {
1620                         return convert((net.sourceforge.phpdt.internal.compiler.ast.EqualExpression) expression);
1621                 }                               
1622                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) {
1623                         return convert((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) expression);
1624                 }                               
1625                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression) {
1626                         return convert((net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression) expression);
1627                 }                               
1628                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.UnaryExpression) {
1629                         return convert((net.sourceforge.phpdt.internal.compiler.ast.UnaryExpression) expression);
1630                 }                               
1631                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression) {
1632                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression) expression);
1633                 }                               
1634                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.MessageSend) {
1635                         return convert((net.sourceforge.phpdt.internal.compiler.ast.MessageSend) expression);
1636                 }                               
1637                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.Reference) {
1638                         return convert((net.sourceforge.phpdt.internal.compiler.ast.Reference) expression);
1639                 }
1640                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeReference) {
1641                         return convert((net.sourceforge.phpdt.internal.compiler.ast.TypeReference) expression);
1642                 }
1643                 return null;
1644         }
1645
1646         public StringLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.ExtendedStringLiteral expression) {
1647                 expression.computeConstant();
1648                 StringLiteral literal = new StringLiteral(this.ast);
1649                 if (this.resolveBindings) {
1650                         this.recordNodes(literal, expression);
1651                 }
1652                 literal.setLiteralValue(expression.constant.stringValue());
1653                 literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1654                 return literal;
1655         }
1656
1657         public BooleanLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral expression) {
1658                 final BooleanLiteral literal =  new BooleanLiteral(this.ast);
1659                 literal.setBooleanValue(false);
1660                 if (this.resolveBindings) {
1661                         this.recordNodes(literal, expression);
1662                 }
1663                 literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1664                 return literal; 
1665         }
1666         
1667         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.FieldReference reference) {
1668                 if (reference.receiver.isSuper()) {
1669                         final SuperFieldAccess superFieldAccess = new SuperFieldAccess(this.ast);
1670                         if (this.resolveBindings) {
1671                                 recordNodes(superFieldAccess, reference);
1672                         }
1673                         if (reference.receiver instanceof net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference) {
1674                                 Name qualifier = convert((net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference) reference.receiver);
1675                                 superFieldAccess.setQualifier(qualifier);
1676                                 if (this.resolveBindings) {
1677                                         recordNodes(qualifier, reference.receiver);
1678                                 }
1679                         }
1680                         final SimpleName simpleName = new SimpleName(this.ast);
1681                         simpleName.internalSetIdentifier(new String(reference.token));
1682                         int sourceStart = (int)(reference.nameSourcePosition>>>32);
1683                         int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
1684                         simpleName.setSourceRange(sourceStart, length);
1685                         superFieldAccess.setName(simpleName);
1686                         if (this.resolveBindings) {
1687                                 recordNodes(simpleName, reference);
1688                         }
1689                         superFieldAccess.setSourceRange(reference.receiver.sourceStart, reference.sourceEnd - reference.receiver.sourceStart + 1);
1690                         return superFieldAccess;
1691                 } else {
1692                         final FieldAccess fieldAccess = new FieldAccess(this.ast);
1693                         if (this.resolveBindings) {
1694                                 recordNodes(fieldAccess, reference);
1695                         }
1696                         Expression receiver = convert(reference.receiver);
1697                         fieldAccess.setExpression(receiver);
1698                         final SimpleName simpleName = new SimpleName(this.ast);
1699                         simpleName.internalSetIdentifier(new String(reference.token));
1700                         int sourceStart = (int)(reference.nameSourcePosition>>>32);
1701                         int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
1702                         simpleName.setSourceRange(sourceStart, length);
1703                         fieldAccess.setName(simpleName);
1704                         if (this.resolveBindings) {
1705                                 recordNodes(simpleName, reference);
1706                         }
1707                         fieldAccess.setSourceRange(receiver.getStartPosition(), reference.sourceEnd - receiver.getStartPosition() + 1);
1708                         return fieldAccess;
1709                 }
1710         }
1711
1712         public NumberLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.FloatLiteral expression) {
1713                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1714                 int sourceStart = expression.sourceStart;
1715                 NumberLiteral literal = new NumberLiteral(this.ast);
1716                 literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
1717                 if (this.resolveBindings) {
1718                         this.recordNodes(literal, expression);
1719                 }
1720                 literal.setSourceRange(sourceStart, length);
1721                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1722                 return literal;
1723         }
1724         
1725         public Statement convert(ForeachStatement statement) {
1726                 switch(this.ast.apiLevel) {
1727                         case AST.JLS2_INTERNAL :
1728                                 return createFakeEmptyStatement(statement);
1729                         case AST.JLS3 :
1730                                 EnhancedForStatement enhancedForStatement = new EnhancedForStatement(this.ast);
1731                                 enhancedForStatement.setParameter(convertToSingleVariableDeclaration(statement.elementVariable));
1732                                 net.sourceforge.phpdt.internal.compiler.ast.Expression collection = statement.collection;
1733                                 if (collection == null) return null;
1734                                 enhancedForStatement.setExpression(convert(collection));
1735                                 final Statement action = convert(statement.action);
1736                                 if (action == null) return null;
1737                                 enhancedForStatement.setBody(action);
1738                                 int start = statement.sourceStart;
1739                                 int end = statement.sourceEnd;
1740                                 enhancedForStatement.setSourceRange(start, end - start + 1);
1741                                 return enhancedForStatement;
1742                         default:
1743                                 return createFakeEmptyStatement(statement);
1744                 }
1745         }
1746         
1747         public ForStatement convert(net.sourceforge.phpdt.internal.compiler.ast.ForStatement statement) {
1748                 ForStatement forStatement = new ForStatement(this.ast);
1749                 forStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1750                 net.sourceforge.phpdt.internal.compiler.ast.Statement[] initializations = statement.initializations;
1751                 if (initializations != null) {
1752                         // we know that we have at least one initialization
1753                         if (initializations[0] instanceof net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) {
1754                                 net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration initialization = (net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) initializations[0];
1755                                 VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression(initialization);
1756                                 int initializationsLength = initializations.length;
1757                                 for (int i = 1; i < initializationsLength; i++) {
1758                                         initialization = (net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration)initializations[i];
1759                                         variableDeclarationExpression.fragments().add(convertToVariableDeclarationFragment(initialization));
1760                                 }
1761                                 if (initializationsLength != 1) {
1762                                         int start = variableDeclarationExpression.getStartPosition();
1763                                         int end = ((net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) initializations[initializationsLength - 1]).declarationSourceEnd;
1764                                         variableDeclarationExpression.setSourceRange(start, end - start + 1);
1765                                 }
1766                                 forStatement.initializers().add(variableDeclarationExpression);
1767                         } else {
1768                                 int initializationsLength = initializations.length;
1769                                 for (int i = 0; i < initializationsLength; i++) {
1770                                         Expression initializer = convertToExpression(initializations[i]);
1771                                         if (initializer != null) {
1772                                                 forStatement.initializers().add(initializer);
1773                                         } else {
1774                                                 forStatement.setFlags(forStatement.getFlags() | ASTNode.MALFORMED);
1775                                         }
1776                                 }
1777                         }
1778                 }
1779                 if (statement.condition != null) {
1780                         forStatement.setExpression(convert(statement.condition));
1781                 }
1782                 net.sourceforge.phpdt.internal.compiler.ast.Statement[] increments = statement.increments;
1783                 if (increments != null) {
1784                         int incrementsLength = increments.length;
1785                         for (int i = 0; i < incrementsLength; i++) {
1786                                 forStatement.updaters().add(convertToExpression(increments[i]));                                
1787                         }
1788                 }
1789                 final Statement action = convert(statement.action);
1790                 if (action == null) return null;
1791                 forStatement.setBody(action);
1792                 return forStatement;
1793         }
1794         
1795         public IfStatement convert(net.sourceforge.phpdt.internal.compiler.ast.IfStatement statement) {
1796                 IfStatement ifStatement = new IfStatement(this.ast);
1797                 ifStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1798                 ifStatement.setExpression(convert(statement.condition));
1799                 final Statement thenStatement = convert(statement.thenStatement);
1800                 if (thenStatement == null) return null;
1801                 ifStatement.setThenStatement(thenStatement);
1802                 net.sourceforge.phpdt.internal.compiler.ast.Statement statement2 = statement.elseStatement;
1803                 if (statement2 != null) {
1804                         final Statement elseStatement = convert(statement2);
1805                         if (elseStatement != null) {
1806                                 ifStatement.setElseStatement(elseStatement);
1807                         }
1808                 }
1809                 return ifStatement;
1810         }
1811         
1812         public InstanceofExpression convert(net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression expression) {
1813                 InstanceofExpression instanceOfExpression = new InstanceofExpression(this.ast);
1814                 if (this.resolveBindings) {
1815                         recordNodes(instanceOfExpression, expression);
1816                 }
1817                 Expression leftExpression = convert(expression.expression);
1818                 instanceOfExpression.setLeftOperand(leftExpression);
1819                 final Type convertType = convertType(expression.type);
1820                 instanceOfExpression.setRightOperand(convertType);
1821                 int startPosition = leftExpression.getStartPosition();
1822                 int sourceEnd = convertType.getStartPosition() + convertType.getLength() - 1;
1823                 instanceOfExpression.setSourceRange(startPosition, sourceEnd - startPosition + 1);
1824                 return instanceOfExpression;
1825         }
1826
1827         public NumberLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.IntLiteral expression) {
1828                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1829                 int sourceStart = expression.sourceStart;
1830                 final NumberLiteral literal = new NumberLiteral(this.ast);
1831                 literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
1832                 if (this.resolveBindings) {
1833                         this.recordNodes(literal, expression);
1834                 }
1835                 literal.setSourceRange(sourceStart, length);
1836                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1837                 return literal;
1838         }
1839
1840         public NumberLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.IntLiteralMinValue expression) {
1841                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1842                 int sourceStart = expression.sourceStart;
1843                 NumberLiteral literal = new NumberLiteral(this.ast);
1844                 literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
1845                 if (this.resolveBindings) {
1846                         this.recordNodes(literal, expression);
1847                 }
1848                 literal.setSourceRange(sourceStart, length);
1849                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1850                 return literal;
1851         }
1852
1853         public void convert(net.sourceforge.phpdt.internal.compiler.ast.Javadoc javadoc, BodyDeclaration bodyDeclaration) {
1854                 if (bodyDeclaration.getJavadoc() == null) {
1855                         if (javadoc != null) {
1856                                 if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
1857                                         this.commentMapper = new DefaultCommentMapper(this.commentsTable);
1858                                 }
1859                                 Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
1860                                 if (comment != null && comment.isDocComment() && comment.getParent() == null) {
1861                                         Javadoc docComment = (Javadoc) comment;
1862                                         if (this.resolveBindings) {
1863                                                 recordNodes(docComment, javadoc);
1864                                                 // resolve member and method references binding
1865                                                 Iterator tags = docComment.tags().listIterator();
1866                                                 while (tags.hasNext()) {
1867                                                         recordNodes(javadoc, (TagElement) tags.next());
1868                                                 }
1869                                         }
1870                                         bodyDeclaration.setJavadoc(docComment);
1871                                 }
1872                         }
1873                 }
1874         }
1875
1876         public void convert(net.sourceforge.phpdt.internal.compiler.ast.Javadoc javadoc, PackageDeclaration packageDeclaration) {
1877                 if (ast.apiLevel == AST.JLS3 && packageDeclaration.getJavadoc() == null) {
1878                         if (javadoc != null) {
1879                                 if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
1880                                         this.commentMapper = new DefaultCommentMapper(this.commentsTable);
1881                                 }
1882                                 Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
1883                                 if (comment != null && comment.isDocComment() && comment.getParent() == null) {
1884                                         Javadoc docComment = (Javadoc) comment;
1885                                         if (this.resolveBindings) {
1886                                                 recordNodes(docComment, javadoc);
1887                                                 // resolve member and method references binding
1888                                                 Iterator tags = docComment.tags().listIterator();
1889                                                 while (tags.hasNext()) {
1890                                                         recordNodes(javadoc, (TagElement) tags.next());
1891                                                 }
1892                                         }
1893                                         packageDeclaration.setJavadoc(docComment);
1894                                 }
1895                         }
1896                 }
1897         }
1898         
1899         public LabeledStatement convert(net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement statement) {
1900                 LabeledStatement labeledStatement = new LabeledStatement(this.ast);
1901                 final int sourceStart = statement.sourceStart;
1902                 labeledStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
1903                 Statement body = convert(statement.statement);
1904                 if (body == null) return null;
1905                 labeledStatement.setBody(body);
1906                 final SimpleName name = new SimpleName(this.ast);
1907                 name.internalSetIdentifier(new String(statement.label));
1908                 name.setSourceRange(sourceStart, statement.labelEnd - sourceStart + 1);
1909                 labeledStatement.setLabel(name);
1910                 return labeledStatement;
1911         }
1912
1913         public NumberLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.LongLiteral expression) {
1914                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1915                 int sourceStart = expression.sourceStart;
1916                 final NumberLiteral literal = new NumberLiteral(this.ast);
1917                 literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
1918                 if (this.resolveBindings) {
1919                         this.recordNodes(literal, expression);
1920                 }
1921                 literal.setSourceRange(sourceStart, length);
1922                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1923                 return literal;
1924         }
1925
1926         public NumberLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.LongLiteralMinValue expression) {
1927                 int length = expression.sourceEnd - expression.sourceStart + 1; 
1928                 int sourceStart = expression.sourceStart;
1929                 final NumberLiteral literal = new NumberLiteral(this.ast);
1930                 literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
1931                 if (this.resolveBindings) {
1932                         this.recordNodes(literal, expression);
1933                 }
1934                 literal.setSourceRange(sourceStart, length);
1935                 removeLeadingAndTrailingCommentsFromLiteral(literal);
1936                 return literal;
1937         }
1938
1939         public Expression convert(MessageSend expression) {
1940                 // will return a MethodInvocation or a SuperMethodInvocation or
1941                 Expression expr;
1942                 int sourceStart = expression.sourceStart;
1943                 if (expression.isSuperAccess()) {
1944                         // returns a SuperMethodInvocation
1945                         final SuperMethodInvocation superMethodInvocation = new SuperMethodInvocation(this.ast);
1946                         if (this.resolveBindings) {
1947                                 recordNodes(superMethodInvocation, expression);
1948                         }
1949                         final SimpleName name = new SimpleName(this.ast);
1950                         name.internalSetIdentifier(new String(expression.selector));
1951                         int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
1952                         int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
1953                         name.setSourceRange(nameSourceStart, nameSourceLength);
1954                         if (this.resolveBindings) {
1955                                 recordNodes(name, expression);
1956                         }
1957                         superMethodInvocation.setName(name);
1958                         // expression.receiver is either a QualifiedSuperReference or a SuperReference
1959                         // so the casting cannot fail
1960                         if (expression.receiver instanceof net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference) {
1961                                 Name qualifier = convert((net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference) expression.receiver);
1962                                 superMethodInvocation.setQualifier(qualifier);
1963                                 if (this.resolveBindings) {
1964                                         recordNodes(qualifier, expression.receiver);
1965                                 }
1966                                 if (qualifier != null) {
1967                                         sourceStart = qualifier.getStartPosition();
1968                                 }                       
1969                         }
1970                         net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
1971                         if (arguments != null) {
1972                                 int argumentsLength = arguments.length;
1973                                 for (int i = 0; i < argumentsLength; i++) {
1974                                         Expression expri = convert(arguments[i]);
1975                                         if (this.resolveBindings) {
1976                                                 recordNodes(expri, arguments[i]);
1977                                         }
1978                                         superMethodInvocation.arguments().add(expri);
1979                                 }
1980                         }
1981                         final TypeReference[] typeArguments = expression.typeArguments;
1982                         if (typeArguments != null) {
1983                                 switch(this.ast.apiLevel) {
1984                                         case AST.JLS2_INTERNAL :
1985                                                 superMethodInvocation.setFlags(superMethodInvocation.getFlags() | ASTNode.MALFORMED);
1986                                                 break;
1987                                         case AST.JLS3 :
1988                                                 for (int i = 0, max = typeArguments.length; i < max; i++) {
1989                                                         superMethodInvocation.typeArguments().add(convertType(typeArguments[i]));
1990                                                 }
1991                                                 break;
1992                                 }
1993                         }
1994                         expr = superMethodInvocation;
1995                 } else {
1996                         // returns a MethodInvocation
1997                         final MethodInvocation methodInvocation = new MethodInvocation(this.ast);
1998                         if (this.resolveBindings) {
1999                                 recordNodes(methodInvocation, expression);
2000                         }
2001                         final SimpleName name = new SimpleName(this.ast);
2002                         name.internalSetIdentifier(new String(expression.selector));
2003                         int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
2004                         int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
2005                         name.setSourceRange(nameSourceStart, nameSourceLength);
2006                         methodInvocation.setName(name);
2007                         if (this.resolveBindings) {
2008                                 recordNodes(name, expression);
2009                         }
2010                         net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
2011                         if (arguments != null) {
2012                                 int argumentsLength = arguments.length;
2013                                 for (int i = 0; i < argumentsLength; i++) {
2014                                         Expression expri = convert(arguments[i]);
2015                                         if (this.resolveBindings) {
2016                                                 recordNodes(expri, arguments[i]);
2017                                         }
2018                                         methodInvocation.arguments().add(expri);
2019                                 }
2020                         }
2021                         Expression qualifier = null;
2022                         net.sourceforge.phpdt.internal.compiler.ast.Expression receiver = expression.receiver;
2023                         if (receiver instanceof MessageSend) {
2024                                 if ((receiver.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
2025                                         qualifier = convertToParenthesizedExpression(receiver);
2026                                 } else {
2027                                         qualifier = convert((MessageSend) receiver);
2028                                 }
2029                         } else {
2030                                 qualifier = convert(receiver);
2031                         }
2032                         if (qualifier instanceof Name && this.resolveBindings) {
2033                                 recordNodes(qualifier, receiver);
2034                         }
2035                         methodInvocation.setExpression(qualifier);
2036                         if (qualifier != null) {
2037                                 sourceStart = qualifier.getStartPosition();
2038                         }
2039                         final TypeReference[] typeArguments = expression.typeArguments;
2040                         if (typeArguments != null) {
2041                                 switch(this.ast.apiLevel) {
2042                                         case AST.JLS2_INTERNAL :
2043                                                 methodInvocation.setFlags(methodInvocation.getFlags() | ASTNode.MALFORMED);
2044                                                 break;
2045                                         case AST.JLS3 :
2046                                                 for (int i = 0, max = typeArguments.length; i < max; i++) {
2047                                                         methodInvocation.typeArguments().add(convertType(typeArguments[i]));
2048                                                 }
2049                                                 break;
2050                                 }
2051                         }
2052                         expr = methodInvocation;
2053                 }
2054                 expr.setSourceRange(sourceStart, expression.sourceEnd - sourceStart + 1);       
2055                 removeTrailingCommentFromExpressionEndingWithAParen(expr);
2056                 return expr;
2057         }
2058
2059         public MarkerAnnotation convert(net.sourceforge.phpdt.internal.compiler.ast.MarkerAnnotation annotation) {
2060                 final MarkerAnnotation markerAnnotation = new MarkerAnnotation(this.ast);
2061                 setTypeNameForAnnotation(annotation, markerAnnotation);
2062                 int start = annotation.sourceStart;
2063                 int end = annotation.declarationSourceEnd;
2064                 markerAnnotation.setSourceRange(start, end - start + 1);
2065                 if (this.resolveBindings) {
2066                         recordNodes(markerAnnotation, annotation);
2067                         markerAnnotation.resolveAnnotationBinding();
2068                 }
2069                 return markerAnnotation;
2070         }
2071
2072         public MemberValuePair convert(net.sourceforge.phpdt.internal.compiler.ast.MemberValuePair memberValuePair) {
2073                 final MemberValuePair pair = new MemberValuePair(this.ast);
2074                 final SimpleName simpleName = new SimpleName(this.ast);
2075                 simpleName.internalSetIdentifier(new String(memberValuePair.name));
2076                 int start = memberValuePair.sourceStart;
2077                 int end = memberValuePair.sourceEnd;
2078                 simpleName.setSourceRange(start, end - start + 1);
2079                 pair.setName(simpleName);
2080                 final Expression value = convert(memberValuePair.value);
2081                 pair.setValue(value);
2082                 start = memberValuePair.sourceStart;
2083                 end = value.getStartPosition() + value.getLength() - 1;
2084                 pair.setSourceRange(start, end - start + 1);
2085                 
2086                 if (memberValuePair.value instanceof SingleNameReference &&
2087                                 ((SingleNameReference)memberValuePair.value).token == RecoveryScanner.FAKE_IDENTIFIER) {
2088                         pair.setFlags(pair.getFlags() | ASTNode.RECOVERED);
2089                 }
2090                 
2091                 if (this.resolveBindings) {
2092                         recordNodes(simpleName, memberValuePair);
2093                         recordNodes(pair, memberValuePair);
2094                 }
2095                 return pair;
2096         }
2097
2098         public Name convert(net.sourceforge.phpdt.internal.compiler.ast.NameReference reference) {
2099                 if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference) {
2100                         return convert((net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference) reference);
2101                 } else {
2102                         return convert((net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference) reference);
2103                 }
2104         }
2105
2106         public InfixExpression convert(StringLiteralConcatenation expression) {
2107                 expression.computeConstant();
2108                 final InfixExpression infixExpression = new InfixExpression(this.ast);
2109                 infixExpression.setOperator(InfixExpression.Operator.PLUS);
2110                 net.sourceforge.phpdt.internal.compiler.ast.Expression[] stringLiterals = expression.literals;
2111                 infixExpression.setLeftOperand(convert(stringLiterals[0]));
2112                 infixExpression.setRightOperand(convert(stringLiterals[1]));
2113                 for (int i = 2; i < expression.counter; i++) {
2114                         infixExpression.extendedOperands().add(convert(stringLiterals[i]));
2115                 }
2116                 if (this.resolveBindings) {
2117                         this.recordNodes(infixExpression, expression);
2118                 }
2119                 infixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2120                 return infixExpression;
2121         }
2122         
2123         public NormalAnnotation convert(net.sourceforge.phpdt.internal.compiler.ast.NormalAnnotation annotation) {
2124                 final NormalAnnotation normalAnnotation = new NormalAnnotation(this.ast);
2125                 setTypeNameForAnnotation(annotation, normalAnnotation);
2126                 
2127                 int start = annotation.sourceStart;
2128                 int end = annotation.declarationSourceEnd;
2129                 
2130                 net.sourceforge.phpdt.internal.compiler.ast.MemberValuePair[] memberValuePairs = annotation.memberValuePairs;
2131                 if (memberValuePairs != null) {
2132                         for (int i = 0, max = memberValuePairs.length; i < max; i++) {
2133                                 MemberValuePair memberValuePair = convert(memberValuePairs[i]);
2134                                 int memberValuePairEnd = memberValuePair.getStartPosition() + memberValuePair.getLength() - 1;
2135                                 if (end == memberValuePairEnd) {
2136                                         normalAnnotation.setFlags(normalAnnotation.getFlags() | ASTNode.RECOVERED);
2137                                 }
2138                                 normalAnnotation.values().add(memberValuePair);
2139                         }
2140                 }
2141                 
2142                 normalAnnotation.setSourceRange(start, end - start + 1);
2143                 if (this.resolveBindings) {
2144                         recordNodes(normalAnnotation, annotation);
2145                         normalAnnotation.resolveAnnotationBinding();
2146                 }
2147                 return normalAnnotation;
2148         }
2149
2150         public NullLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.NullLiteral expression) {
2151                 final NullLiteral literal = new NullLiteral(this.ast);
2152                 if (this.resolveBindings) {
2153                         this.recordNodes(literal, expression);
2154                 }
2155                 literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2156                 return literal;         
2157         }
2158
2159         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression expression) {
2160                 InfixExpression infixExpression = new InfixExpression(this.ast);
2161                 infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
2162                 if (this.resolveBindings) {
2163                         this.recordNodes(infixExpression, expression);
2164                 }
2165                 final int expressionOperatorID = (expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
2166                 if (expression.left instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression
2167                                 && ((expression.left.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
2168                         // create an extended string literal equivalent => use the extended operands list
2169                         infixExpression.extendedOperands().add(convert(expression.right));
2170                         net.sourceforge.phpdt.internal.compiler.ast.Expression leftOperand = expression.left;
2171                         net.sourceforge.phpdt.internal.compiler.ast.Expression rightOperand = null;
2172                         do {
2173                                 rightOperand = ((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
2174                                 if ((((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
2175                                                         && ((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
2176                                          || ((rightOperand instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression
2177                                                         && ((rightOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
2178                                                         && ((rightOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
2179                                         List extendedOperands = infixExpression.extendedOperands();
2180                                         InfixExpression temp = new InfixExpression(this.ast);
2181                                         if (this.resolveBindings) {
2182                                                 this.recordNodes(temp, expression);
2183                                         }
2184                                         temp.setOperator(getOperatorFor(expressionOperatorID));
2185                                         Expression leftSide = convert(leftOperand);
2186                                         temp.setLeftOperand(leftSide);
2187                                         temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
2188                                         int size = extendedOperands.size();
2189                                         for (int i = 0; i < size - 1; i++) {
2190                                                 Expression expr = temp;
2191                                                 temp = new InfixExpression(this.ast);
2192                                                 
2193                                                 if (this.resolveBindings) {
2194                                                         this.recordNodes(temp, expression);
2195                                                 }                                       
2196                                                 temp.setLeftOperand(expr);
2197                                                 temp.setOperator(getOperatorFor(expressionOperatorID));
2198                                                 temp.setSourceRange(expr.getStartPosition(), expr.getLength());
2199                                         }
2200                                         infixExpression = temp;
2201                                         for (int i = 0; i < size; i++) {
2202                                                 Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
2203                                                 temp.setRightOperand(extendedOperand);
2204                                                 int startPosition = temp.getLeftOperand().getStartPosition();
2205                                                 temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
2206                                                 if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
2207                                                         temp = (InfixExpression) temp.getLeftOperand();
2208                                                 }
2209                                         }
2210                                         int startPosition = infixExpression.getLeftOperand().getStartPosition();
2211                                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
2212                                         if (this.resolveBindings) {
2213                                                 this.recordNodes(infixExpression, expression);
2214                                         }
2215                                         return infixExpression;
2216                                 }
2217                                 infixExpression.extendedOperands().add(0, convert(rightOperand));
2218                                 leftOperand = ((net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
2219                         } while (leftOperand instanceof net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
2220                         Expression leftExpression = convert(leftOperand);
2221                         infixExpression.setLeftOperand(leftExpression);
2222                         infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
2223                         int startPosition = leftExpression.getStartPosition();
2224                         infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
2225                         return infixExpression;
2226                 }
2227                 Expression leftExpression = convert(expression.left);
2228                 infixExpression.setLeftOperand(leftExpression);
2229                 infixExpression.setRightOperand(convert(expression.right));
2230                 infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
2231                 int startPosition = leftExpression.getStartPosition();
2232                 infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
2233                 return infixExpression;
2234         }
2235
2236         public PostfixExpression convert(net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression expression) {
2237                 final PostfixExpression postfixExpression = new PostfixExpression(this.ast);
2238                 if (this.resolveBindings) {
2239                         recordNodes(postfixExpression, expression);
2240                 }
2241                 postfixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2242                 postfixExpression.setOperand(convert(expression.lhs));
2243                 switch (expression.operator) {
2244                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.PLUS :
2245                                 postfixExpression.setOperator(PostfixExpression.Operator.INCREMENT);
2246                                 break;
2247                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MINUS :
2248                                 postfixExpression.setOperator(PostfixExpression.Operator.DECREMENT);
2249                                 break;
2250                 }
2251                 return postfixExpression;
2252         }
2253
2254         public PrefixExpression convert(net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression expression) {
2255                 final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
2256                 if (this.resolveBindings) {
2257                         recordNodes(prefixExpression, expression);
2258                 }
2259                 prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2260                 prefixExpression.setOperand(convert(expression.lhs));
2261                 switch (expression.operator) {
2262                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.PLUS :
2263                                 prefixExpression.setOperator(PrefixExpression.Operator.INCREMENT);
2264                                 break;
2265                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MINUS :
2266                                 prefixExpression.setOperator(PrefixExpression.Operator.DECREMENT);
2267                                 break;
2268                 }
2269                 return prefixExpression;
2270         }
2271
2272         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression allocation) {
2273                 final ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
2274                 if (allocation.enclosingInstance != null) {
2275                         classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
2276                 }
2277                 switch(this.ast.apiLevel) {
2278                         case AST.JLS2_INTERNAL :
2279                                 classInstanceCreation.internalSetName(convert(allocation.type));
2280                                 break;
2281                         case AST.JLS3 :
2282                                 classInstanceCreation.setType(convertType(allocation.type));
2283                 }
2284                 net.sourceforge.phpdt.internal.compiler.ast.Expression[] arguments = allocation.arguments;
2285                 if (arguments != null) {
2286                         int length = arguments.length;
2287                         for (int i = 0; i < length; i++) {
2288                                 Expression argument = convert(arguments[i]);
2289                                 if (this.resolveBindings) {
2290                                         recordNodes(argument, arguments[i]);
2291                                 }
2292                                 classInstanceCreation.arguments().add(argument);
2293                         }
2294                 }
2295                 if (allocation.typeArguments != null) {
2296                         switch(this.ast.apiLevel) {
2297                                 case AST.JLS2_INTERNAL :
2298                                         classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
2299                                         break;
2300                                 case AST.JLS3 :
2301                                         for (int i = 0, max = allocation.typeArguments.length; i < max; i++) {
2302                                                 classInstanceCreation.typeArguments().add(convertType(allocation.typeArguments[i]));
2303                                         }
2304                         }                       
2305                 }
2306                 if (allocation.anonymousType != null) {
2307                         int declarationSourceStart = allocation.sourceStart;
2308                         classInstanceCreation.setSourceRange(declarationSourceStart, allocation.anonymousType.bodyEnd - declarationSourceStart + 1);
2309                         final AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
2310                         int start = retrieveStartBlockPosition(allocation.anonymousType.sourceEnd, allocation.anonymousType.bodyEnd);
2311                         anonymousClassDeclaration.setSourceRange(start, allocation.anonymousType.bodyEnd - start + 1);
2312                         classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
2313                         buildBodyDeclarations(allocation.anonymousType, anonymousClassDeclaration);
2314                         if (this.resolveBindings) {
2315                                 recordNodes(classInstanceCreation, allocation.anonymousType);
2316                                 recordNodes(anonymousClassDeclaration, allocation.anonymousType);
2317                                 anonymousClassDeclaration.resolveBinding();
2318                         }
2319                         return classInstanceCreation;                   
2320                 } else {
2321                         final int start = allocation.sourceStart;
2322                         classInstanceCreation.setSourceRange(start, allocation.sourceEnd - start + 1);
2323                         if (this.resolveBindings) {
2324                                 recordNodes(classInstanceCreation, allocation);
2325                         }
2326                         removeTrailingCommentFromExpressionEndingWithAParen(classInstanceCreation);
2327                         return classInstanceCreation;
2328                 }
2329         }
2330
2331         public Name convert(net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference nameReference) {
2332                 return setQualifiedNameNameAndSourceRanges(nameReference.tokens, nameReference.sourcePositions, nameReference);
2333         }
2334
2335         public Name convert(net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference reference) {
2336                 return convert(reference.qualification);
2337         }
2338
2339         public ThisExpression convert(net.sourceforge.phpdt.internal.compiler.ast.QualifiedThisReference reference) {
2340                 final ThisExpression thisExpression = new ThisExpression(this.ast);
2341                 thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
2342                 thisExpression.setQualifier(convert(reference.qualification));
2343                 if (this.resolveBindings) {
2344                         recordNodes(thisExpression, reference);
2345                         recordPendingThisExpressionScopeResolution(thisExpression);
2346                 }
2347                 return thisExpression;
2348         }
2349         
2350         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.Reference reference) {
2351                 if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.NameReference) {
2352                         return convert((net.sourceforge.phpdt.internal.compiler.ast.NameReference) reference);
2353                 }
2354                 if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.ThisReference) {
2355                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ThisReference) reference);
2356                 }
2357                 if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.ArrayReference) {
2358                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ArrayReference) reference);
2359                 }
2360                 if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.FieldReference) {
2361                         return convert((net.sourceforge.phpdt.internal.compiler.ast.FieldReference) reference);
2362                 }
2363                 return null; // cannot be reached
2364         }
2365         
2366         public ReturnStatement convert(net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement statement) {
2367                 final ReturnStatement returnStatement = new ReturnStatement(this.ast);
2368                 returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1); 
2369                 if (statement.expression != null) {
2370                         returnStatement.setExpression(convert(statement.expression));
2371                 }
2372                 return returnStatement;
2373         }
2374         
2375         public SingleMemberAnnotation convert(net.sourceforge.phpdt.internal.compiler.ast.SingleMemberAnnotation annotation) {
2376                 final SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(this.ast);
2377                 setTypeNameForAnnotation(annotation, singleMemberAnnotation);
2378                 singleMemberAnnotation.setValue(convert(annotation.memberValue));
2379                 int start = annotation.sourceStart;
2380                 int end = annotation.declarationSourceEnd;
2381                 singleMemberAnnotation.setSourceRange(start, end - start + 1);
2382                 if (this.resolveBindings) {
2383                         recordNodes(singleMemberAnnotation, annotation);
2384                         singleMemberAnnotation.resolveAnnotationBinding();
2385                 }
2386                 return singleMemberAnnotation;
2387         }
2388
2389         public SimpleName convert(net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference nameReference) {
2390                 final SimpleName name = new SimpleName(this.ast);
2391                 name.internalSetIdentifier(new String(nameReference.token));
2392                 if (this.resolveBindings) {
2393                         recordNodes(name, nameReference);
2394                 }
2395                 name.setSourceRange(nameReference.sourceStart, nameReference.sourceEnd - nameReference.sourceStart + 1);
2396                 return name;
2397         }
2398
2399         public Statement convert(net.sourceforge.phpdt.internal.compiler.ast.Statement statement) {
2400                 if (statement instanceof ForeachStatement) {
2401                         return convert((ForeachStatement) statement);
2402                 }
2403                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) {
2404                         net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration localDeclaration = (net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration)statement;
2405                         return convertToVariableDeclarationStatement(localDeclaration);
2406                 }
2407                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.AssertStatement) {
2408                         return convert((net.sourceforge.phpdt.internal.compiler.ast.AssertStatement) statement);
2409                 }
2410                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.Block) {
2411                         return convert((net.sourceforge.phpdt.internal.compiler.ast.Block) statement);
2412                 }
2413                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.BreakStatement) {
2414                         return convert((net.sourceforge.phpdt.internal.compiler.ast.BreakStatement) statement);
2415                 }
2416                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement) {
2417                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement) statement);
2418                 }
2419                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.CaseStatement) {
2420                         return convert((net.sourceforge.phpdt.internal.compiler.ast.CaseStatement) statement);
2421                 }
2422                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.DoStatement) {
2423                         return convert((net.sourceforge.phpdt.internal.compiler.ast.DoStatement) statement);
2424                 }
2425                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement) {
2426                         return convert((net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement) statement);
2427                 }
2428                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall) {
2429                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall) statement);
2430                 }
2431                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.ForStatement) {
2432                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ForStatement) statement);
2433                 }
2434                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.IfStatement) {
2435                         return convert((net.sourceforge.phpdt.internal.compiler.ast.IfStatement) statement);
2436                 }
2437                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement) {
2438                         return convert((net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement) statement);
2439                 }
2440                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement) {
2441                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement) statement);
2442                 }
2443                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement) {
2444                         return convert((net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement) statement);
2445                 }
2446                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.SynchronizedStatement) {
2447                         return convert((net.sourceforge.phpdt.internal.compiler.ast.SynchronizedStatement) statement);
2448                 }
2449                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement) {
2450                         return convert((net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement) statement);
2451                 }
2452                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.TryStatement) {
2453                         return convert((net.sourceforge.phpdt.internal.compiler.ast.TryStatement) statement);
2454                 }
2455                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) {
2456                         ASTNode result = convert((net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) statement);
2457                         if (result == null) {
2458                                 return createFakeEmptyStatement(statement);
2459                         }
2460                         switch(result.getNodeType()) {
2461                                 case ASTNode.ENUM_DECLARATION:
2462                                         switch(this.ast.apiLevel) {
2463                                                 case AST.JLS2_INTERNAL :
2464                                                         return createFakeEmptyStatement(statement);
2465                                                 case AST.JLS3 :
2466                                                         final TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
2467                                                         typeDeclarationStatement.setDeclaration((EnumDeclaration) result);
2468                                                         AbstractTypeDeclaration typeDecl = typeDeclarationStatement.getDeclaration();
2469                                                         typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
2470                                                         return typeDeclarationStatement;
2471                                         }
2472                                         break;
2473                                 case ASTNode.ANNOTATION_TYPE_DECLARATION :
2474                                         switch(this.ast.apiLevel) {
2475                                                 case AST.JLS2_INTERNAL :
2476                                                         return createFakeEmptyStatement(statement);
2477                                                 case AST.JLS3 :
2478                                                         TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
2479                                                         typeDeclarationStatement.setDeclaration((AnnotationTypeDeclaration) result);
2480                                                         AbstractTypeDeclaration typeDecl = typeDeclarationStatement.getDeclaration();
2481                                                         typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
2482                                                         return typeDeclarationStatement;
2483                                         }
2484                                         break;
2485                                 default:
2486                                         TypeDeclaration typeDeclaration = (TypeDeclaration) result;
2487                                         TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
2488                                         typeDeclarationStatement.setDeclaration(typeDeclaration);
2489                                         switch(this.ast.apiLevel) {
2490                                                 case AST.JLS2_INTERNAL :
2491                                                         TypeDeclaration typeDecl = typeDeclarationStatement.internalGetTypeDeclaration();
2492                                                         typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());                                     
2493                                                         break;
2494                                                 case AST.JLS3 :
2495                                                         AbstractTypeDeclaration typeDeclAST3 = typeDeclarationStatement.getDeclaration();
2496                                                         typeDeclarationStatement.setSourceRange(typeDeclAST3.getStartPosition(), typeDeclAST3.getLength());
2497                                                         break;
2498                                         }
2499                                         return typeDeclarationStatement;
2500                         }
2501                 }
2502                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.WhileStatement) {
2503                         return convert((net.sourceforge.phpdt.internal.compiler.ast.WhileStatement) statement);
2504                 }
2505                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.Expression) {
2506                         net.sourceforge.phpdt.internal.compiler.ast.Expression statement2 = (net.sourceforge.phpdt.internal.compiler.ast.Expression) statement;
2507                         final Expression expr = convert(statement2);
2508                         final ExpressionStatement stmt = new ExpressionStatement(this.ast);
2509                         stmt.setExpression(expr);
2510                         int sourceStart = expr.getStartPosition();
2511                         int sourceEnd = statement2.statementEnd;
2512                         stmt.setSourceRange(sourceStart, sourceEnd - sourceStart + 1);
2513                         return stmt;
2514                 }
2515                 return createFakeEmptyStatement(statement);
2516         }
2517
2518         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.StringLiteral expression) {
2519                 if (expression instanceof StringLiteralConcatenation) {
2520                         return convert((StringLiteralConcatenation) expression);
2521                 }
2522                 int length = expression.sourceEnd - expression.sourceStart + 1; 
2523                 int sourceStart = expression.sourceStart;
2524                 StringLiteral literal = new StringLiteral(this.ast);
2525                 if (this.resolveBindings) {
2526                         this.recordNodes(literal, expression);
2527                 }
2528                 literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
2529                 literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2530                 return literal;
2531         }
2532         
2533         public SwitchStatement convert(net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement statement) {
2534                 SwitchStatement switchStatement = new SwitchStatement(this.ast);
2535                 switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1); 
2536                 switchStatement.setExpression(convert(statement.expression));
2537                 net.sourceforge.phpdt.internal.compiler.ast.Statement[] statements = statement.statements;
2538                 if (statements != null) {
2539                         int statementsLength = statements.length;
2540                         for (int i = 0; i < statementsLength; i++) {
2541                                 if (statements[i] instanceof net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration) {
2542                                         checkAndAddMultipleLocalDeclaration(statements, i, switchStatement.statements());
2543                                 } else {
2544                                         final Statement currentStatement = convert(statements[i]);
2545                                         if (currentStatement != null) {
2546                                                 switchStatement.statements().add(currentStatement);
2547                                         }
2548                                 }
2549                         }
2550                 }
2551                 return switchStatement;
2552         }
2553         
2554         public SynchronizedStatement convert(net.sourceforge.phpdt.internal.compiler.ast.SynchronizedStatement statement) {
2555                 SynchronizedStatement synchronizedStatement = new SynchronizedStatement(this.ast);
2556                 synchronizedStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);   
2557                 synchronizedStatement.setBody(convert(statement.block));
2558                 synchronizedStatement.setExpression(convert(statement.expression));
2559                 return synchronizedStatement;
2560         }
2561         
2562         public Expression convert(net.sourceforge.phpdt.internal.compiler.ast.ThisReference reference) {
2563                 if (reference.isImplicitThis()) {
2564                         // There is no source associated with an implicit this
2565                         return null;
2566                 } else if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference) {
2567                         return convert((net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference) reference);
2568                 } else if (reference instanceof net.sourceforge.phpdt.internal.compiler.ast.QualifiedThisReference) {
2569                         return convert((net.sourceforge.phpdt.internal.compiler.ast.QualifiedThisReference) reference);
2570                 }  else {
2571                         ThisExpression thisExpression = new ThisExpression(this.ast);
2572                         thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
2573                         if (this.resolveBindings) {
2574                                 recordNodes(thisExpression, reference);
2575                                 recordPendingThisExpressionScopeResolution(thisExpression);
2576                         }
2577                         return thisExpression;
2578                 }
2579         }
2580         
2581         public ThrowStatement convert(net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement statement) {
2582                 final ThrowStatement throwStatement = new ThrowStatement(this.ast);
2583                 throwStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2584                 throwStatement.setExpression(convert(statement.exception));
2585                 return throwStatement;
2586         }
2587                 
2588         public BooleanLiteral convert(net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral expression) {
2589                 final BooleanLiteral literal = new BooleanLiteral(this.ast);
2590                 literal.setBooleanValue(true);
2591                 if (this.resolveBindings) {
2592                         this.recordNodes(literal, expression);
2593                 }
2594                 literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2595                 return literal;         
2596         }
2597         
2598         public TryStatement convert(net.sourceforge.phpdt.internal.compiler.ast.TryStatement statement) {
2599                 final TryStatement tryStatement = new TryStatement(this.ast);
2600                 tryStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);    
2601
2602                 tryStatement.setBody(convert(statement.tryBlock));
2603                 net.sourceforge.phpdt.internal.compiler.ast.Argument[] catchArguments = statement.catchArguments;
2604                 if (catchArguments != null) {
2605                         int catchArgumentsLength = catchArguments.length;
2606                         net.sourceforge.phpdt.internal.compiler.ast.Block[] catchBlocks = statement.catchBlocks;
2607                         int start = statement.tryBlock.sourceEnd;
2608                         for (int i = 0; i < catchArgumentsLength; i++) {
2609                                 CatchClause catchClause = new CatchClause(this.ast);
2610                                 int catchClauseSourceStart = retrieveStartingCatchPosition(start, catchArguments[i].sourceStart);
2611                                 catchClause.setSourceRange(catchClauseSourceStart, catchBlocks[i].sourceEnd - catchClauseSourceStart + 1);      
2612                                 catchClause.setBody(convert(catchBlocks[i]));
2613                                 catchClause.setException(convert(catchArguments[i]));
2614                                 tryStatement.catchClauses().add(catchClause);
2615                                 start = catchBlocks[i].sourceEnd;
2616                         }
2617                 }
2618                 if (statement.finallyBlock != null) {
2619                         tryStatement.setFinally(convert(statement.finallyBlock));
2620                 }
2621                 return tryStatement;
2622         }
2623
2624         public ASTNode convert(net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
2625                 int kind = net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration.kind(typeDeclaration.modifiers);
2626                 switch (kind) {
2627                         case net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration.ENUM_DECL :
2628                                 if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
2629                                         return null;
2630                                 } else {
2631                                         return convertToEnumDeclaration(typeDeclaration);
2632                                 }
2633                         case net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration.ANNOTATION_TYPE_DECL :
2634                                 if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
2635                                         return null;
2636                                 } else {
2637                                         return convertToAnnotationDeclaration(typeDeclaration);
2638                                 }
2639                 }
2640
2641                 checkCanceled();
2642                 TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
2643                 if (typeDeclaration.modifiersSourceStart != -1) {
2644                         setModifiers(typeDecl, typeDeclaration);
2645                 }
2646                 typeDecl.setInterface(kind == net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration.INTERFACE_DECL);
2647                 final SimpleName typeName = new SimpleName(this.ast);
2648                 typeName.internalSetIdentifier(new String(typeDeclaration.name));
2649                 typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
2650                 typeDecl.setName(typeName);
2651                 typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
2652                 
2653                 // need to set the superclass and super interfaces here since we cannot distinguish them at
2654                 // the type references level.
2655                 if (typeDeclaration.superclass != null) {
2656                         switch(this.ast.apiLevel) {
2657                                 case AST.JLS2_INTERNAL :
2658                                         typeDecl.internalSetSuperclass(convert(typeDeclaration.superclass));
2659                                         break;
2660                                 case AST.JLS3 :
2661                                         typeDecl.setSuperclassType(convertType(typeDeclaration.superclass));
2662                                         break;
2663                         }
2664                 }
2665                 
2666                 net.sourceforge.phpdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
2667                 if (superInterfaces != null) {
2668                         switch(this.ast.apiLevel) {
2669                                 case AST.JLS2_INTERNAL :
2670                                         for (int index = 0, length = superInterfaces.length; index < length; index++) {
2671                                                 typeDecl.internalSuperInterfaces().add(convert(superInterfaces[index]));
2672                                         }
2673                                         break;
2674                                 case AST.JLS3 :
2675                                         for (int index = 0, length = superInterfaces.length; index < length; index++) {
2676                                                 typeDecl.superInterfaceTypes().add(convertType(superInterfaces[index]));
2677                                         }
2678                         }                                       
2679                 }
2680                 net.sourceforge.phpdt.internal.compiler.ast.TypeParameter[] typeParameters = typeDeclaration.typeParameters;
2681                 if (typeParameters != null) {
2682                         switch(this.ast.apiLevel) {
2683                                 case AST.JLS2_INTERNAL :
2684                                         typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
2685                                         break;
2686                                 case AST.JLS3 :
2687                                         for (int index = 0, length = typeParameters.length; index < length; index++) {
2688                                                 typeDecl.typeParameters().add(convert(typeParameters[index]));
2689                                         }
2690                         }
2691                 }
2692                 buildBodyDeclarations(typeDeclaration, typeDecl);
2693                 if (this.resolveBindings) {
2694                         recordNodes(typeDecl, typeDeclaration);
2695                         recordNodes(typeName, typeDeclaration);
2696                         typeDecl.resolveBinding();
2697                 }
2698                 return typeDecl;
2699         }
2700
2701         public TypeParameter convert(net.sourceforge.phpdt.internal.compiler.ast.TypeParameter typeParameter) {
2702                 final TypeParameter typeParameter2 = new TypeParameter(this.ast);
2703                 final SimpleName simpleName = new SimpleName(this.ast);
2704                 simpleName.internalSetIdentifier(new String(typeParameter.name));
2705                 int start = typeParameter.sourceStart;
2706                 int end = typeParameter.sourceEnd;
2707                 simpleName.setSourceRange(start, end - start + 1);
2708                 typeParameter2.setName(simpleName);
2709                 final TypeReference superType = typeParameter.type;
2710                 end = typeParameter.declarationSourceEnd;
2711                 if (superType != null) {
2712                         Type type = convertType(superType);
2713                         typeParameter2.typeBounds().add(type);
2714                         end = type.getStartPosition() + type.getLength() - 1;
2715                 }
2716                 TypeReference[] bounds = typeParameter.bounds;
2717                 if (bounds != null) {
2718                         Type type = null;
2719                         for (int index = 0, length = bounds.length; index < length; index++) {
2720                                 type = convertType(bounds[index]);
2721                                 typeParameter2.typeBounds().add(type);
2722                                 end = type.getStartPosition() + type.getLength() - 1;
2723                         }
2724                 }
2725                 start = typeParameter.declarationSourceStart;
2726                 end = retrieveClosingAngleBracketPosition(end);
2727                 typeParameter2.setSourceRange(start, end - start + 1);
2728                 if (this.resolveBindings) {
2729                         recordName(simpleName, typeParameter);
2730                         recordNodes(typeParameter2, typeParameter);
2731                         typeParameter2.resolveBinding();
2732                 }
2733                 return typeParameter2;
2734         }
2735         
2736         public Name convert(net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeReference) {
2737                 char[][] typeName = typeReference.getTypeName();
2738                 int length = typeName.length;
2739                 if (length > 1) {
2740                         // QualifiedName
2741                         net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference) typeReference;
2742                         final long[] positions = qualifiedTypeReference.sourcePositions;
2743                         return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
2744                 } else {
2745                         final SimpleName name = new SimpleName(this.ast);
2746                         name.internalSetIdentifier(new String(typeName[0]));
2747                         name.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);
2748                         name.index = 1;
2749                         if (this.resolveBindings) {
2750                                 recordNodes(name, typeReference);
2751                         }
2752                         return name;
2753                 }
2754         }
2755                         
2756         public PrefixExpression convert(net.sourceforge.phpdt.internal.compiler.ast.UnaryExpression expression) {
2757                 final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
2758                 if (this.resolveBindings) {
2759                         this.recordNodes(prefixExpression, expression);
2760                 }
2761                 prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2762                 prefixExpression.setOperand(convert(expression.expression));
2763                 switch ((expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
2764                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.PLUS :
2765                                 prefixExpression.setOperator(PrefixExpression.Operator.PLUS);
2766                                 break;
2767                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MINUS :
2768                                 prefixExpression.setOperator(PrefixExpression.Operator.MINUS);
2769                                 break;
2770                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.NOT :
2771                                 prefixExpression.setOperator(PrefixExpression.Operator.NOT);
2772                                 break;
2773                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.TWIDDLE :
2774                                 prefixExpression.setOperator(PrefixExpression.Operator.COMPLEMENT);
2775                 }
2776                 return prefixExpression;
2777         }
2778         
2779         public WhileStatement convert(net.sourceforge.phpdt.internal.compiler.ast.WhileStatement statement) {
2780                 final WhileStatement whileStatement = new WhileStatement(this.ast);
2781                 whileStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2782                 whileStatement.setExpression(convert(statement.condition));
2783                 final Statement action = convert(statement.action);
2784                 if (action == null) return null;
2785                 whileStatement.setBody(action);
2786                 return whileStatement;
2787         }
2788         
2789         public ImportDeclaration convertImport(net.sourceforge.phpdt.internal.compiler.ast.ImportReference importReference) {
2790                 final ImportDeclaration importDeclaration = new ImportDeclaration(this.ast);
2791                 final boolean onDemand = (importReference.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.OnDemand) != 0;
2792                 final char[][] tokens = importReference.tokens;
2793                 int length = importReference.tokens.length;
2794                 final long[] positions = importReference.sourcePositions;
2795                 if (length > 1) {
2796                         importDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
2797                 } else {
2798                         final SimpleName name = new SimpleName(this.ast);
2799                         name.internalSetIdentifier(new String(tokens[0]));
2800                         final int start = (int)(positions[0]>>>32);
2801                         final int end = (int)(positions[0] & 0xFFFFFFFF);
2802                         name.setSourceRange(start, end - start + 1);
2803                         name.index = 1;
2804                         importDeclaration.setName(name);
2805                         if (this.resolveBindings) {
2806                                 recordNodes(name, importReference);
2807                         }
2808                 }
2809                 importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
2810                 importDeclaration.setOnDemand(onDemand);
2811                 int modifiers = importReference.modifiers;
2812                 if (modifiers != ClassFileConstants.AccDefault) {
2813                         switch(this.ast.apiLevel) {
2814                                 case AST.JLS2_INTERNAL :
2815                                         importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
2816                                         break;
2817                                 case AST.JLS3 :
2818                                         if (modifiers == ClassFileConstants.AccStatic) {
2819                                                 importDeclaration.setStatic(true);
2820                                         } else {
2821                                                 importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
2822                                         }
2823                         }
2824                 }
2825                 if (this.resolveBindings) {
2826                         recordNodes(importDeclaration, importReference);
2827                 }
2828                 return importDeclaration;
2829         }
2830
2831         public PackageDeclaration convertPackage(net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration) {
2832                 net.sourceforge.phpdt.internal.compiler.ast.ImportReference importReference = compilationUnitDeclaration.currentPackage;
2833                 final PackageDeclaration packageDeclaration = new PackageDeclaration(this.ast);
2834                 final char[][] tokens = importReference.tokens;
2835                 final int length = importReference.tokens.length;
2836                 long[] positions = importReference.sourcePositions;
2837                 if (length > 1) {
2838                         packageDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
2839                 } else {
2840                         final SimpleName name = new SimpleName(this.ast);
2841                         name.internalSetIdentifier(new String(tokens[0]));
2842                         int start = (int)(positions[0]>>>32);
2843                         int end = (int)(positions[length - 1] & 0xFFFFFFFF);
2844                         name.setSourceRange(start, end - start + 1);
2845                         name.index = 1;
2846                         packageDeclaration.setName(name);
2847                         if (this.resolveBindings) {
2848                                 recordNodes(name, compilationUnitDeclaration);
2849                         }
2850                 }
2851                 packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
2852                 net.sourceforge.phpdt.internal.compiler.ast.Annotation[] annotations = importReference.annotations;
2853                 if (annotations != null) {
2854                         switch(this.ast.apiLevel) {
2855                                 case AST.JLS2_INTERNAL :
2856                                         packageDeclaration.setFlags(packageDeclaration.getFlags() & ASTNode.MALFORMED);
2857                                         break;
2858                                 case AST.JLS3 :
2859                                         for (int i = 0, max = annotations.length; i < max; i++) {
2860                                                 packageDeclaration.annotations().add(convert(annotations[i]));
2861                                         }
2862                         }
2863                 }
2864                 if (this.resolveBindings) {
2865                         recordNodes(packageDeclaration, importReference);
2866                 }
2867                 // Set javadoc
2868                 convert(compilationUnitDeclaration.javadoc, packageDeclaration);
2869                 return packageDeclaration;
2870         }
2871         
2872         private EnumDeclaration convertToEnumDeclaration(net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
2873                 checkCanceled();
2874                 final EnumDeclaration enumDeclaration2 = new EnumDeclaration(this.ast);
2875                 setModifiers(enumDeclaration2, typeDeclaration);
2876                 final SimpleName typeName = new SimpleName(this.ast);
2877                 typeName.internalSetIdentifier(new String(typeDeclaration.name));
2878                 typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
2879                 enumDeclaration2.setName(typeName);
2880                 enumDeclaration2.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
2881                 
2882                 net.sourceforge.phpdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
2883                 if (superInterfaces != null) {
2884                         for (int index = 0, length = superInterfaces.length; index < length; index++) {
2885                                 enumDeclaration2.superInterfaceTypes().add(convertType(superInterfaces[index]));
2886                         }                                       
2887                 }
2888                 buildBodyDeclarations(typeDeclaration, enumDeclaration2);
2889                 if (this.resolveBindings) {
2890                         recordNodes(enumDeclaration2, typeDeclaration);
2891                         recordNodes(typeName, typeDeclaration);
2892                         enumDeclaration2.resolveBinding();
2893                 }
2894                 return enumDeclaration2;
2895         }
2896         public Expression convertToExpression(net.sourceforge.phpdt.internal.compiler.ast.Statement statement) {
2897                 if (statement instanceof net.sourceforge.phpdt.internal.compiler.ast.Expression) {
2898                         return convert((net.sourceforge.phpdt.internal.compiler.ast.Expression) statement);
2899                 } else {
2900                         return null;
2901                 }
2902         }
2903
2904         protected FieldDeclaration convertToFieldDeclaration(net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
2905                 VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
2906                 final FieldDeclaration fieldDeclaration = new FieldDeclaration(this.ast);
2907                 fieldDeclaration.fragments().add(variableDeclarationFragment);
2908                 if (this.resolveBindings) {
2909                         recordNodes(variableDeclarationFragment, fieldDecl);
2910                         variableDeclarationFragment.resolveBinding();
2911                 }
2912                 fieldDeclaration.setSourceRange(fieldDecl.declarationSourceStart, fieldDecl.declarationEnd - fieldDecl.declarationSourceStart + 1);
2913                 Type type = convertType(fieldDecl.type);
2914                 setTypeForField(fieldDeclaration, type, variableDeclarationFragment.getExtraDimensions());
2915                 setModifiers(fieldDeclaration, fieldDecl);
2916                 convert(fieldDecl.javadoc, fieldDeclaration);
2917                 return fieldDeclaration;
2918         }
2919
2920         public ParenthesizedExpression convertToParenthesizedExpression(net.sourceforge.phpdt.internal.compiler.ast.Expression expression) {
2921                 final ParenthesizedExpression parenthesizedExpression = new ParenthesizedExpression(this.ast);
2922                 if (this.resolveBindings) {
2923                         recordNodes(parenthesizedExpression, expression);
2924                 }
2925                 parenthesizedExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
2926                 adjustSourcePositionsForParent(expression);
2927                 trimWhiteSpacesAndComments(expression);
2928                 // decrement the number of parenthesis
2929                 int numberOfParenthesis = (expression.bits & net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) >> net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
2930                 expression.bits &= ~net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedMASK;
2931                 expression.bits |= (numberOfParenthesis - 1) << net.sourceforge.phpdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
2932                 parenthesizedExpression.setExpression(convert(expression));
2933                 return parenthesizedExpression;
2934         }
2935                 
2936         public Type convertToType(net.sourceforge.phpdt.internal.compiler.ast.NameReference reference) {
2937                 Name name = convert(reference);
2938                 final SimpleType type = new SimpleType(this.ast);
2939                 type.setName(name);
2940                 type.setSourceRange(name.getStartPosition(), name.getLength());
2941                 if (this.resolveBindings) {
2942                         this.recordNodes(type, reference);
2943                 }
2944                 return type;
2945         }
2946         
2947         protected VariableDeclarationExpression convertToVariableDeclarationExpression(net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
2948                 final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
2949                 final VariableDeclarationExpression variableDeclarationExpression = new VariableDeclarationExpression(this.ast);
2950                 variableDeclarationExpression.fragments().add(variableDeclarationFragment);
2951                 if (this.resolveBindings) {
2952                         recordNodes(variableDeclarationFragment, localDeclaration);
2953                 }
2954                 variableDeclarationExpression.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
2955                 Type type = convertType(localDeclaration.type);
2956                 setTypeForVariableDeclarationExpression(variableDeclarationExpression, type, variableDeclarationFragment.getExtraDimensions());
2957                 if (localDeclaration.modifiersSourceStart != -1) {
2958                         setModifiers(variableDeclarationExpression, localDeclaration);
2959                 }
2960                 return variableDeclarationExpression;
2961         }
2962
2963         protected SingleVariableDeclaration convertToSingleVariableDeclaration(LocalDeclaration localDeclaration) {
2964                 final SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
2965                 setModifiers(variableDecl, localDeclaration);
2966                 final SimpleName name = new SimpleName(this.ast);
2967                 name.internalSetIdentifier(new String(localDeclaration.name));
2968                 int start = localDeclaration.sourceStart;
2969                 int nameEnd = localDeclaration.sourceEnd;
2970                 name.setSourceRange(start, nameEnd - start + 1);
2971                 variableDecl.setName(name);
2972                 final int extraDimensions = retrieveExtraDimension(nameEnd + 1, localDeclaration.type.sourceEnd);
2973                 variableDecl.setExtraDimensions(extraDimensions);
2974                 Type type = convertType(localDeclaration.type);
2975                 int typeEnd = type.getStartPosition() + type.getLength() - 1;
2976                 int rightEnd = Math.max(typeEnd, localDeclaration.declarationSourceEnd);
2977                 /*
2978                  * There is extra work to do to set the proper type positions
2979                  * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
2980                  */
2981                 setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
2982                 variableDecl.setSourceRange(localDeclaration.declarationSourceStart, rightEnd - localDeclaration.declarationSourceStart + 1);
2983                 if (this.resolveBindings) {
2984                         recordNodes(name, localDeclaration);
2985                         recordNodes(variableDecl, localDeclaration);
2986                         variableDecl.resolveBinding();
2987                 }
2988                 return variableDecl;
2989         }
2990         
2991         protected VariableDeclarationFragment convertToVariableDeclarationFragment(net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
2992                 final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
2993                 final SimpleName name = new SimpleName(this.ast);
2994                 name.internalSetIdentifier(new String(fieldDeclaration.name));
2995                 name.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.sourceEnd - fieldDeclaration.sourceStart + 1);
2996                 variableDeclarationFragment.setName(name);
2997                 int start = fieldDeclaration.sourceEnd;
2998                 int end = start;
2999                 int extraDimensions = retrieveExtraDimension(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd );
3000                 variableDeclarationFragment.setExtraDimensions(extraDimensions);
3001                 if (fieldDeclaration.initialization != null) {
3002                         final Expression expression = convert(fieldDeclaration.initialization);
3003                         variableDeclarationFragment.setInitializer(expression);
3004                         start = expression.getStartPosition() + expression.getLength();
3005                         end = start - 1;
3006                 } else {
3007                         // we need to do it even if extendedDimension is null in case of syntax error in an array initializer
3008                         // need the exclusive range for retrieveEndOfPotentialExtendedDimensions
3009                         int possibleEnd = retrieveEndOfPotentialExtendedDimensions(start + 1, fieldDeclaration.sourceEnd, fieldDeclaration.declarationSourceEnd);
3010                         if (possibleEnd == Integer.MIN_VALUE) {
3011                                 end = fieldDeclaration.declarationSourceEnd;
3012                                 variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
3013                         } if (possibleEnd < 0) {
3014                                 end = -possibleEnd;
3015                                 variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
3016                         } else {
3017                                 end = possibleEnd;
3018                         }
3019                 }
3020                 variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, end - fieldDeclaration.sourceStart + 1);
3021                 if (this.resolveBindings) {
3022                         recordNodes(name, fieldDeclaration);
3023                         recordNodes(variableDeclarationFragment, fieldDeclaration);
3024                         variableDeclarationFragment.resolveBinding();
3025                 }
3026                 return variableDeclarationFragment;
3027         }
3028
3029         protected VariableDeclarationFragment convertToVariableDeclarationFragment(net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
3030                 final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
3031                 final SimpleName name = new SimpleName(this.ast);
3032                 name.internalSetIdentifier(new String(localDeclaration.name));
3033                 name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
3034                 variableDeclarationFragment.setName(name);
3035                 int start = localDeclaration.sourceEnd; 
3036                 net.sourceforge.phpdt.internal.compiler.ast.Expression initialization = localDeclaration.initialization;
3037                 int extraDimension = retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSourceLength);
3038                 variableDeclarationFragment.setExtraDimensions(extraDimension);
3039                 boolean hasInitialization = initialization != null;
3040                 int end;
3041                 if (hasInitialization) {
3042                         final Expression expression = convert(initialization);
3043                         variableDeclarationFragment.setInitializer(expression);
3044                         start = expression.getStartPosition() + expression.getLength();
3045                         end = start - 1;
3046                 } else {
3047                         // we need to do it even if extendedDimension is null in case of syntax error in an array initializer
3048                         // start + 1 because we need the exclusive range for retrieveEndOfPotentialExtendedDimensions
3049                         int possibleEnd = retrieveEndOfPotentialExtendedDimensions(start + 1, localDeclaration.sourceEnd, localDeclaration.declarationSourceEnd);
3050                         if (possibleEnd == Integer.MIN_VALUE) {
3051                                 end = start;
3052                                 variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
3053                         } else if (possibleEnd < 0) {
3054                                 end = -possibleEnd;
3055                                 variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
3056                         } else {
3057                                 end = possibleEnd;
3058                         }
3059                 }
3060                 variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, end - localDeclaration.sourceStart + 1);
3061                 if (this.resolveBindings) {
3062                         recordNodes(variableDeclarationFragment, localDeclaration);
3063                         recordNodes(name, localDeclaration);
3064                         variableDeclarationFragment.resolveBinding();
3065                 }
3066                 return variableDeclarationFragment;
3067         }
3068
3069         protected VariableDeclarationStatement convertToVariableDeclarationStatement(net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
3070                 final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
3071                 final VariableDeclarationStatement variableDeclarationStatement = new VariableDeclarationStatement(this.ast);
3072                 variableDeclarationStatement.fragments().add(variableDeclarationFragment);
3073                 if (this.resolveBindings) {
3074                         recordNodes(variableDeclarationFragment, localDeclaration);
3075                 }
3076                 variableDeclarationStatement.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
3077                 Type type = convertType(localDeclaration.type);
3078                 setTypeForVariableDeclarationStatement(variableDeclarationStatement, type, variableDeclarationFragment.getExtraDimensions());
3079                 if (localDeclaration.modifiersSourceStart != -1) {
3080                         setModifiers(variableDeclarationStatement, localDeclaration);
3081                 }
3082                 return variableDeclarationStatement;
3083         }
3084
3085         public Type convertType(TypeReference typeReference) {
3086                 if (typeReference instanceof Wildcard) {
3087                         final Wildcard wildcard = (Wildcard) typeReference;
3088                         final WildcardType wildcardType = new WildcardType(this.ast);
3089                         if (wildcard.bound != null) {
3090                                 final Type bound = convertType(wildcard.bound);
3091                                 wildcardType.setBound(bound, wildcard.kind == Wildcard.EXTENDS);
3092                                 int start = wildcard.sourceStart;
3093                                 wildcardType.setSourceRange(start, bound.getStartPosition() + bound.getLength() - start);
3094                         } else {
3095                                 final int start = wildcard.sourceStart;
3096                                 final int end = wildcard.sourceEnd;
3097                                 wildcardType.setSourceRange(start, end - start + 1);
3098                         }
3099                         if (this.resolveBindings) {
3100                                 recordNodes(wildcardType, typeReference);
3101                         }
3102                         return wildcardType;
3103                 }
3104                 Type type = null;
3105                 int sourceStart = -1;
3106                 int length = 0;
3107                 int dimensions = typeReference.dimensions();
3108                 if (typeReference instanceof net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference) {
3109                         // this is either an ArrayTypeReference or a SingleTypeReference
3110                         char[] name = ((net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference) typeReference).getTypeName()[0];
3111                         sourceStart = typeReference.sourceStart;
3112                         length = typeReference.sourceEnd - typeReference.sourceStart + 1;
3113                         // need to find out if this is an array type of primitive types or not
3114                         if (isPrimitiveType(name)) {
3115                                 int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
3116                                 if (end == -1) {
3117                                         end = sourceStart + length - 1;
3118                                 }                                       
3119                                 final PrimitiveType primitiveType = new PrimitiveType(this.ast);
3120                                 primitiveType.setPrimitiveTypeCode(getPrimitiveTypeCode(name));
3121                                 primitiveType.setSourceRange(sourceStart, end - sourceStart + 1);
3122                                 type = primitiveType;
3123                         } else if (typeReference instanceof ParameterizedSingleTypeReference) {
3124                                 ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) typeReference;
3125                                 final SimpleName simpleName = new SimpleName(this.ast);
3126                                 simpleName.internalSetIdentifier(new String(name));
3127                                 int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
3128                                 if (end == -1) {
3129                                         end = sourceStart + length - 1;
3130                                 }
3131                                 simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
3132                                 switch(this.ast.apiLevel) {
3133                                         case AST.JLS2_INTERNAL :
3134                                                 SimpleType simpleType = new SimpleType(this.ast);
3135                                                 simpleType.setName(simpleName);
3136                                                 simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
3137                                                 simpleType.setSourceRange(sourceStart, end - sourceStart + 1);
3138                                                 type = simpleType;
3139                                                 if (this.resolveBindings) {
3140                                                         this.recordNodes(simpleName, typeReference);
3141                                                 }
3142                                                 break;
3143                                         case AST.JLS3 :
3144                                                 simpleType = new SimpleType(this.ast);
3145                                                 simpleType.setName(simpleName);
3146                                                 simpleType.setSourceRange(simpleName.getStartPosition(), simpleName.getLength());
3147                                                 final ParameterizedType parameterizedType = new ParameterizedType(this.ast);
3148                                                 parameterizedType.setType(simpleType);
3149                                                 type = parameterizedType;
3150                                                 TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
3151                                                 if (typeArguments != null) {
3152                                                         Type type2 = null;
3153                                                         for (int i = 0, max = typeArguments.length; i < max; i++) {
3154                                                                 type2 = convertType(typeArguments[i]);
3155                                                                 ((ParameterizedType) type).typeArguments().add(type2);
3156                                                                 end = type2.getStartPosition() + type2.getLength() - 1;
3157                                                         }
3158                                                         end = retrieveClosingAngleBracketPosition(end + 1);
3159                                                         type.setSourceRange(sourceStart, end - sourceStart + 1);
3160                                                 } else {
3161                                                         type.setSourceRange(sourceStart, end - sourceStart + 1);
3162                                                 }
3163                                                 if (this.resolveBindings) {
3164                                                         this.recordNodes(simpleName, typeReference);
3165                                                         this.recordNodes(simpleType, typeReference);
3166                                                 }
3167                                 }
3168                         } else {
3169                                 final SimpleName simpleName = new SimpleName(this.ast);
3170                                 simpleName.internalSetIdentifier(new String(name));
3171                                 // we need to search for the starting position of the first brace in order to set the proper length
3172                                 // PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759
3173                                 int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
3174                                 if (end == -1) {
3175                                         end = sourceStart + length - 1;
3176                                 }
3177                                 simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
3178                                 final SimpleType simpleType = new SimpleType(this.ast);
3179                                 simpleType.setName(simpleName);
3180                                 type = simpleType;
3181                                 type.setSourceRange(sourceStart, end - sourceStart + 1);
3182                                 type = simpleType;
3183                                 if (this.resolveBindings) {
3184                                         this.recordNodes(simpleName, typeReference);
3185                                 }
3186                         }
3187                         if (dimensions != 0) {
3188                                 type = this.ast.newArrayType(type, dimensions);
3189                                 type.setSourceRange(sourceStart, length);
3190                                 ArrayType subarrayType = (ArrayType) type;
3191                                 int index = dimensions - 1;
3192                                 while (index > 0) {
3193                                         subarrayType = (ArrayType) subarrayType.getComponentType();
3194                                         int end = retrieveProperRightBracketPosition(index, sourceStart);
3195                                         subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
3196                                         index--;
3197                                 }
3198                                 if (this.resolveBindings) {
3199                                         // store keys for inner types
3200                                         completeRecord((ArrayType) type, typeReference);
3201                                 }
3202                         }
3203                 } else {
3204                         if (typeReference instanceof ParameterizedQualifiedTypeReference) {
3205                                 ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) typeReference;
3206                                 char[][] tokens = parameterizedQualifiedTypeReference.tokens;
3207                                 TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
3208                                 long[] positions = parameterizedQualifiedTypeReference.sourcePositions;
3209                                 sourceStart = (int)(positions[0]>>>32);
3210                                 switch(this.ast.apiLevel) {
3211                                         case AST.JLS2_INTERNAL : {
3212                                                         char[][] name = ((net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
3213                                                         int nameLength = name.length;
3214                                                         sourceStart = (int)(positions[0]>>>32);
3215                                                         length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
3216                                                         Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
3217                                                         final SimpleType simpleType = new SimpleType(this.ast);
3218                                                         simpleType.setName(qualifiedName);
3219                                                         simpleType.setSourceRange(sourceStart, length);
3220                                                         type = simpleType;
3221                                                 }
3222                                                 break;
3223                                         case AST.JLS3 :
3224                                                 if (typeArguments != null) {
3225                                                         int numberOfEnclosingType = 0;
3226                             int startingIndex = 0;
3227                             int endingIndex = 0;
3228                                                         for (int i = 0, max = typeArguments.length; i < max; i++) {
3229                                                                 if (typeArguments[i] != null) {
3230                                                                         numberOfEnclosingType++;
3231                                                                 } else if (numberOfEnclosingType == 0) {
3232                                     endingIndex++;
3233                                 }
3234                                                         }
3235                                                         Name name = null;
3236                                                         if (endingIndex - startingIndex == 0) {
3237                                                                 final SimpleName simpleName = new SimpleName(this.ast);
3238                                                                 simpleName.internalSetIdentifier(new String(tokens[startingIndex]));
3239                                                                 recordPendingNameScopeResolution(simpleName);
3240                                                                 int start = (int)(positions[startingIndex]>>>32);
3241                                                                 int end = (int) positions[startingIndex];
3242                                                                 simpleName.setSourceRange(start, end - start + 1);
3243                                                                 simpleName.index = 1;
3244                                                                 name = simpleName;
3245                                                                 if (this.resolveBindings) {
3246                                                                         recordNodes(simpleName, typeReference);
3247                                                                 }
3248                                                         } else {
3249                                                                 name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, endingIndex, typeReference);
3250                                                         }
3251                                                         SimpleType simpleType = new SimpleType(this.ast);
3252                                                         simpleType.setName(name);
3253                                                         int start = (int)(positions[startingIndex]>>>32);
3254                                                         int end = (int) positions[endingIndex];
3255                                                         simpleType.setSourceRange(start, end - start + 1);
3256                                                         ParameterizedType parameterizedType = new ParameterizedType(this.ast);
3257                                                         parameterizedType.setType(simpleType);
3258                             if (this.resolveBindings) {
3259                                 recordNodes(simpleType, typeReference);
3260                                 recordNodes(parameterizedType, typeReference);
3261                             }
3262                                                         start = simpleType.getStartPosition();
3263                                                         end = start + simpleType.getLength() - 1;
3264                                                         for (int i = 0, max = typeArguments[endingIndex].length; i < max; i++) {
3265                                                                 final Type type2 = convertType(typeArguments[endingIndex][i]);
3266                                                                 parameterizedType.typeArguments().add(type2);
3267                                                                 end = type2.getStartPosition() + type2.getLength() - 1;
3268                                                         }
3269                                                         int indexOfEnclosingType = 1;
3270                                                         parameterizedType.index = indexOfEnclosingType;
3271                                                         end = retrieveClosingAngleBracketPosition(end + 1);
3272                                                         length = end + 1;
3273                                                         parameterizedType.setSourceRange(start, end - start + 1);
3274                                                         startingIndex = endingIndex + 1;
3275                                                         Type currentType = parameterizedType;
3276                                                         while(startingIndex < typeArguments.length) {
3277                                                                 SimpleName simpleName = new SimpleName(this.ast);
3278                                                                 simpleName.internalSetIdentifier(new String(tokens[startingIndex]));
3279                                                                 simpleName.index = startingIndex + 1;
3280                                                                 start = (int)(positions[startingIndex]>>>32);
3281                                                                 end = (int) positions[startingIndex];
3282                                                                 simpleName.setSourceRange(start, end - start + 1);
3283                                                                 recordPendingNameScopeResolution(simpleName);
3284                                                                 QualifiedType qualifiedType = new QualifiedType(this.ast);
3285                                                                 qualifiedType.setQualifier(currentType);
3286                                                                 qualifiedType.setName(simpleName);      
3287                                 if (this.resolveBindings) {
3288                                     recordNodes(simpleName, typeReference);
3289                                     recordNodes(qualifiedType, typeReference);
3290                                 }
3291                                                                 start = currentType.getStartPosition();
3292                                                                 end = simpleName.getStartPosition() + simpleName.getLength() - 1;
3293                                                                 qualifiedType.setSourceRange(start, end - start + 1);
3294                                                                 indexOfEnclosingType++;
3295                                                                 if (typeArguments[startingIndex] != null) {
3296                                         qualifiedType.index = indexOfEnclosingType;
3297                                                                         ParameterizedType parameterizedType2 = new ParameterizedType(this.ast);
3298                                                                         parameterizedType2.setType(qualifiedType);
3299                                                                         parameterizedType2.index = indexOfEnclosingType;
3300                                    if (this.resolveBindings) {
3301                                         recordNodes(parameterizedType2, typeReference);
3302                                     }
3303                                                                         for (int i = 0, max = typeArguments[startingIndex].length; i < max; i++) {
3304                                                                                 final Type type2 = convertType(typeArguments[startingIndex][i]);
3305                                                                                 parameterizedType2.typeArguments().add(type2);
3306                                                                                 end = type2.getStartPosition() + type2.getLength() - 1;
3307                                                                         }
3308                                                                         end = retrieveClosingAngleBracketPosition(end + 1);
3309                                                                         length = end + 1;
3310                                                                         parameterizedType2.setSourceRange(start, end - start + 1);                                                      
3311                                                                         currentType = parameterizedType2;
3312                                                                 } else {
3313                                                                         currentType = qualifiedType;
3314                                         qualifiedType.index = indexOfEnclosingType;
3315                                                                 }
3316                                                                 startingIndex++;
3317                                                         }
3318                                                         if (this.resolveBindings) {
3319                                                                 this.recordNodes(currentType, typeReference);
3320                                                         }
3321                                                         type = currentType;
3322                                                         length -= sourceStart;
3323                                                 }
3324                                 }
3325                         } else {
3326                                 char[][] name = ((net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
3327                                 int nameLength = name.length;
3328                                 long[] positions = ((net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
3329                                 sourceStart = (int)(positions[0]>>>32);
3330                                 length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
3331                                 final Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
3332                                 final SimpleType simpleType = new SimpleType(this.ast);
3333                                 simpleType.setName(qualifiedName);
3334                                 type = simpleType;
3335                                 type.setSourceRange(sourceStart, length);
3336                         }
3337
3338                         length = typeReference.sourceEnd - sourceStart + 1;
3339                         if (dimensions != 0) {
3340                                 type = this.ast.newArrayType(type, dimensions);
3341                                 if (this.resolveBindings) {
3342                                         completeRecord((ArrayType) type, typeReference);
3343                                 }
3344                                 int end = retrieveEndOfDimensionsPosition(sourceStart+length, this.compilationUnitSourceLength);
3345                                 if (end != -1) {
3346                                         type.setSourceRange(sourceStart, end - sourceStart + 1);
3347                                 } else {
3348                                         type.setSourceRange(sourceStart, length);
3349                                 }
3350                                 ArrayType subarrayType = (ArrayType) type;
3351                                 int index = dimensions - 1;
3352                                 while (index > 0) {
3353                                         subarrayType = (ArrayType) subarrayType.getComponentType();
3354                                         end = retrieveProperRightBracketPosition(index, sourceStart);
3355                                         subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
3356                                         index--;
3357                                 }
3358                         }
3359                 }
3360                 if (this.resolveBindings) {
3361                         this.recordNodes(type, typeReference);
3362                 }
3363                 return type;
3364         }
3365
3366         protected Comment createComment(int[] positions) {
3367                 // Create comment node
3368                 Comment comment = null;
3369                 int start = positions[0];
3370                 int end = positions[1];
3371                 if (positions[1]>0) { // Javadoc comments have positive end position
3372                         Javadoc docComment = this.docParser.parse(positions);
3373                         if (docComment == null) return null;
3374                         comment = docComment;
3375                 } else {
3376                         end = -end;
3377                         if (positions[0] == 0) { // we cannot know without testing chars again
3378                                 if (this.docParser.scanner.source[1] == '/') {
3379                                         comment = new LineComment(this.ast);
3380                                 } else {
3381                                         comment = new BlockComment(this.ast);
3382                                 }
3383                         }
3384                         else if (positions[0]>0) { // Block comment have positive start position
3385                                 comment = new BlockComment(this.ast);
3386                         } else { // Line comment have negative start and end position
3387                                 start = -start;
3388                                 comment = new LineComment(this.ast);
3389                         }
3390                         comment.setSourceRange(start, end - start);
3391                 }
3392                 return comment;
3393         }
3394         
3395         protected Statement createFakeEmptyStatement(net.sourceforge.phpdt.internal.compiler.ast.Statement statement) {
3396                 if (statement == null) return null;
3397                 EmptyStatement emptyStatement = new EmptyStatement(this.ast);
3398                 emptyStatement.setFlags(emptyStatement.getFlags() | ASTNode.MALFORMED);
3399                 int start = statement.sourceStart;
3400                 int end = statement.sourceEnd;
3401                 emptyStatement.setSourceRange(start, end - start + 1);
3402                 return emptyStatement;
3403         }
3404         /**
3405          * @return a new modifier
3406          */
3407         private Modifier createModifier(ModifierKeyword keyword) {
3408                 final Modifier modifier = new Modifier(this.ast);
3409                 modifier.setKeyword(keyword);
3410                 int start = this.scanner.getCurrentTokenStartPosition();
3411                 int end = this.scanner.getCurrentTokenEndPosition();
3412                 modifier.setSourceRange(start, end - start + 1);
3413                 return modifier;
3414         }
3415         
3416         protected InfixExpression.Operator getOperatorFor(int operatorID) {
3417                 switch (operatorID) {
3418                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
3419                                 return InfixExpression.Operator.EQUALS;
3420                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
3421                                 return InfixExpression.Operator.LESS_EQUALS;
3422                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
3423                                 return InfixExpression.Operator.GREATER_EQUALS;
3424                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
3425                                 return InfixExpression.Operator.NOT_EQUALS;
3426                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
3427                                 return InfixExpression.Operator.LEFT_SHIFT;
3428                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
3429                                 return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
3430                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
3431                                 return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
3432                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.OR_OR :
3433                                 return InfixExpression.Operator.CONDITIONAL_OR;
3434                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.AND_AND :
3435                                 return InfixExpression.Operator.CONDITIONAL_AND;
3436                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.PLUS :
3437                                 return InfixExpression.Operator.PLUS;
3438                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MINUS :
3439                                 return InfixExpression.Operator.MINUS;
3440                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.REMAINDER :
3441                                 return InfixExpression.Operator.REMAINDER;
3442                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.XOR :
3443                                 return InfixExpression.Operator.XOR;
3444                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.AND :
3445                                 return InfixExpression.Operator.AND;
3446                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.MULTIPLY :
3447                                 return InfixExpression.Operator.TIMES;
3448                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.OR :
3449                                 return InfixExpression.Operator.OR;
3450                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.DIVIDE :
3451                                 return InfixExpression.Operator.DIVIDE;
3452                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.GREATER :
3453                                 return InfixExpression.Operator.GREATER;
3454                         case net.sourceforge.phpdt.internal.compiler.ast.OperatorIds.LESS :
3455                                 return InfixExpression.Operator.LESS;
3456                 }
3457                 return null;
3458         }
3459         
3460         protected PrimitiveType.Code getPrimitiveTypeCode(char[] name) {
3461                 switch(name[0]) {
3462                         case 'i' :
3463                                 if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
3464                                         return PrimitiveType.INT;
3465                                 }
3466                                 break;
3467                         case 'l' :
3468                                 if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
3469                                         return PrimitiveType.LONG;
3470                                 }
3471                                 break;
3472                         case 'd' :
3473                                 if (name.length == 6
3474                                          && name[1] == 'o'
3475                                          && name[2] == 'u'
3476                                          && name[3] == 'b'
3477                                          && name[4] == 'l'
3478                                          && name[5] == 'e') {
3479                                         return PrimitiveType.DOUBLE;
3480                                 }
3481                                 break;
3482                         case 'f' :
3483                                 if (name.length == 5
3484                                          && name[1] == 'l'
3485                                          && name[2] == 'o'
3486                                          && name[3] == 'a'
3487                                          && name[4] == 't') {
3488                                         return PrimitiveType.FLOAT;
3489                                 }
3490                                 break;
3491                         case 'b' :
3492                                 if (name.length == 4
3493                                          && name[1] == 'y'
3494                                          && name[2] == 't'
3495                                          && name[3] == 'e') {
3496                                         return PrimitiveType.BYTE;
3497                                 } else
3498                                         if (name.length == 7
3499                                                  && name[1] == 'o'
3500                                                  && name[2] == 'o'
3501                                                  && name[3] == 'l'
3502                                                  && name[4] == 'e'
3503                                                  && name[5] == 'a'
3504                                                  && name[6] == 'n') {
3505                                         return PrimitiveType.BOOLEAN;
3506                                 }
3507                                 break;
3508                         case 'c' :
3509                                 if (name.length == 4
3510                                          && name[1] == 'h'
3511                                          && name[2] == 'a'
3512                                          && name[3] == 'r') {
3513                                         return PrimitiveType.CHAR;
3514                                 }
3515                                 break;
3516                         case 's' :
3517                                 if (name.length == 5
3518                                          && name[1] == 'h'
3519                                          && name[2] == 'o'
3520                                          && name[3] == 'r'
3521                                          && name[4] == 't') {
3522                                         return PrimitiveType.SHORT;
3523                                 }
3524                                 break;
3525                         case 'v' :
3526                                 if (name.length == 4
3527                                          && name[1] == 'o'
3528                                          && name[2] == 'i'
3529                                          && name[3] == 'd') {
3530                                         return PrimitiveType.VOID;
3531                                 }
3532                 }
3533                 return null; // cannot be reached
3534         }
3535         
3536         protected boolean isPrimitiveType(char[] name) {
3537                 switch(name[0]) {
3538                         case 'i' :
3539                                 if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
3540                                         return true;
3541                                 }
3542                                 return false;
3543                         case 'l' :
3544                                 if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
3545                                         return true;
3546                                 }
3547                                 return false;
3548                         case 'd' :
3549                                 if (name.length == 6
3550                                          && name[1] == 'o'
3551                                          && name[2] == 'u'
3552                                          && name[3] == 'b'
3553                                          && name[4] == 'l'
3554                                          && name[5] == 'e') {
3555                                         return true;
3556                                 }
3557                                 return false;
3558                         case 'f' :
3559                                 if (name.length == 5
3560                                          && name[1] == 'l'
3561                                          && name[2] == 'o'
3562                                          && name[3] == 'a'
3563                                          && name[4] == 't') {
3564                                         return true;
3565                                 }
3566                                 return false;
3567                         case 'b' :
3568                                 if (name.length == 4
3569                                          && name[1] == 'y'
3570                                          && name[2] == 't'
3571                                          && name[3] == 'e') {
3572                                         return true;
3573                                 } else
3574                                         if (name.length == 7
3575                                                  && name[1] == 'o'
3576                                                  && name[2] == 'o'
3577                                                  && name[3] == 'l'
3578                                                  && name[4] == 'e'
3579                                                  && name[5] == 'a'
3580                                                  && name[6] == 'n') {
3581                                         return true;
3582                                 }
3583                                 return false;
3584                         case 'c' :
3585                                 if (name.length == 4
3586                                          && name[1] == 'h'
3587                                          && name[2] == 'a'
3588                                          && name[3] == 'r') {
3589                                         return true;
3590                                 }
3591                                 return false;
3592                         case 's' :
3593                                 if (name.length == 5
3594                                          && name[1] == 'h'
3595                                          && name[2] == 'o'
3596                                          && name[3] == 'r'
3597                                          && name[4] == 't') {
3598                                         return true;
3599                                 }
3600                                 return false;
3601                         case 'v' :
3602                                 if (name.length == 4
3603                                          && name[1] == 'o'
3604                                          && name[2] == 'i'
3605                                          && name[3] == 'd') {
3606                                         return true;
3607                                 }
3608                                 return false;
3609                 }
3610                 return false;
3611         }
3612         
3613         private void lookupForScopes() {
3614                 if (this.pendingNameScopeResolution != null) {
3615                         for (Iterator iterator = this.pendingNameScopeResolution.iterator(); iterator.hasNext(); ) {
3616                                 Name name = (Name) iterator.next();
3617                                 this.ast.getBindingResolver().recordScope(name, lookupScope(name));
3618                         }
3619                 }
3620                 if (this.pendingThisExpressionScopeResolution != null) {
3621                         for (Iterator iterator = this.pendingThisExpressionScopeResolution.iterator(); iterator.hasNext(); ) {
3622                                 ThisExpression thisExpression = (ThisExpression) iterator.next();
3623                                 this.ast.getBindingResolver().recordScope(thisExpression, lookupScope(thisExpression));
3624                         }
3625                 }
3626                 
3627         }
3628         
3629         private BlockScope lookupScope(ASTNode node) {
3630                 ASTNode currentNode = node;
3631                 while(currentNode != null
3632                         &&!(currentNode instanceof MethodDeclaration)
3633                         && !(currentNode instanceof Initializer)
3634                         && !(currentNode instanceof FieldDeclaration)
3635                         && !(currentNode instanceof AbstractTypeDeclaration)) {
3636                         currentNode = currentNode.getParent();
3637                 }
3638                 if (currentNode == null) {
3639                         return null;
3640                 }
3641                 if (currentNode instanceof Initializer) {
3642                         Initializer initializer = (Initializer) currentNode;
3643                         while(!(currentNode instanceof AbstractTypeDeclaration)) {
3644                                 currentNode = currentNode.getParent();
3645                         }
3646                         if (currentNode instanceof TypeDeclaration
3647                                 || currentNode instanceof EnumDeclaration
3648                                 || currentNode instanceof AnnotationTypeDeclaration) {
3649                                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDecl = (net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3650                                 if ((initializer.getModifiers() & Modifier.STATIC) != 0) {
3651                                         return typeDecl.staticInitializerScope;
3652                                 } else {
3653                                         return typeDecl.initializerScope;
3654                                 }
3655                         }
3656                 } else if (currentNode instanceof FieldDeclaration) {
3657                         FieldDeclaration fieldDeclaration = (FieldDeclaration) currentNode;
3658                         while(!(currentNode instanceof AbstractTypeDeclaration)) {
3659                                 currentNode = currentNode.getParent();
3660                         }
3661                         if (currentNode instanceof AbstractTypeDeclaration) {
3662                                 net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDecl = (net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3663                                 if ((fieldDeclaration.getModifiers() & Modifier.STATIC) != 0) {
3664                                         return typeDecl.staticInitializerScope;
3665                                 } else {
3666                                         return typeDecl.initializerScope;
3667                                 }
3668                         }
3669                 } else if (currentNode instanceof AbstractTypeDeclaration) {
3670                         net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDecl = (net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3671                         return typeDecl.initializerScope;
3672                 }
3673                 AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3674                 return abstractMethodDeclaration.scope;
3675         }
3676
3677         protected void recordName(Name name, net.sourceforge.phpdt.internal.compiler.ast.ASTNode compilerNode) {
3678                 if (compilerNode != null) {
3679                         recordNodes(name, compilerNode);
3680                         if (compilerNode instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeReference) {
3681                                 net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeRef = (net.sourceforge.phpdt.internal.compiler.ast.TypeReference) compilerNode;
3682                                 if (name.isQualifiedName()) {
3683                                         SimpleName simpleName = null;
3684                                         while (name.isQualifiedName()) {
3685                                                 simpleName = ((QualifiedName) name).getName();
3686                                                 recordNodes(simpleName, typeRef);
3687                                                 name = ((QualifiedName) name).getQualifier();
3688                                                 recordNodes(name, typeRef);
3689                                         }
3690                                 }
3691                         }
3692                 }
3693         }
3694         
3695         protected void recordNodes(ASTNode node, net.sourceforge.phpdt.internal.compiler.ast.ASTNode oldASTNode) {
3696                 this.ast.getBindingResolver().store(node, oldASTNode);
3697         }
3698         
3699         protected void recordNodes(net.sourceforge.phpdt.internal.compiler.ast.Javadoc javadoc, TagElement tagElement) {
3700                 Iterator fragments = tagElement.fragments().listIterator();
3701                 while (fragments.hasNext()) {
3702                         ASTNode node = (ASTNode) fragments.next();
3703                         if (node.getNodeType() == ASTNode.MEMBER_REF) {
3704                                 MemberRef memberRef = (MemberRef) node;
3705                                 Name name = memberRef.getName();
3706                                 // get compiler node and record nodes
3707                                 int start = name.getStartPosition();
3708                                 net.sourceforge.phpdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
3709                                 if (compilerNode!= null) {
3710                                         recordNodes(name, compilerNode);
3711                                         recordNodes(node, compilerNode);
3712                                 }
3713                                 // Replace qualifier to have all nodes recorded
3714                                 if (memberRef.getQualifier() != null) {
3715                                         net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeRef = null;
3716                                         if (compilerNode instanceof JavadocFieldReference) {
3717                                                 net.sourceforge.phpdt.internal.compiler.ast.Expression expression = ((JavadocFieldReference)compilerNode).receiver;
3718                                                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeReference) {
3719                                                         typeRef = (net.sourceforge.phpdt.internal.compiler.ast.TypeReference) expression;
3720                                                 }
3721                                         } 
3722                                         else if (compilerNode instanceof JavadocMessageSend) {
3723                                                 net.sourceforge.phpdt.internal.compiler.ast.Expression expression = ((JavadocMessageSend)compilerNode).receiver;
3724                                                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeReference) {
3725                                                         typeRef = (net.sourceforge.phpdt.internal.compiler.ast.TypeReference) expression;
3726                                                 }
3727                                         }
3728                                         if (typeRef != null) {
3729                                                 recordName(memberRef.getQualifier(), typeRef);
3730                                         }
3731                                 }
3732                         } else if (node.getNodeType() == ASTNode.METHOD_REF) {
3733                                 MethodRef methodRef = (MethodRef) node;
3734                                 Name name = methodRef.getName();
3735                                 // get method name start position
3736                                 int start = methodRef.getStartPosition();
3737                                 this.scanner.resetTo(start, start + name.getStartPosition()+name.getLength());
3738                                 int token;
3739                                 try {
3740                                         nextToken: while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF && token != TerminalTokens.TokenNameLPAREN)  {
3741                                                 if (token == TerminalTokens.TokenNameERROR && this.scanner.currentCharacter == '#') {
3742                                                         start = this.scanner.getCurrentTokenEndPosition()+1;
3743                                                         break nextToken;
3744                                                 }
3745                                         }
3746                                 }
3747                                 catch(InvalidInputException e) {
3748                                         // ignore
3749                                 }
3750                                 // get compiler node and record nodes
3751                                 net.sourceforge.phpdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
3752                                 // record nodes
3753                                 if (compilerNode != null) {
3754                                         recordNodes(methodRef, compilerNode);
3755                                         // get type ref
3756                                         net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeRef = null;
3757                                         if (compilerNode instanceof net.sourceforge.phpdt.internal.compiler.ast.JavadocAllocationExpression) {
3758                                                 typeRef = ((net.sourceforge.phpdt.internal.compiler.ast.JavadocAllocationExpression)compilerNode).type;
3759                                                 if (typeRef != null) recordNodes(name, compilerNode);
3760                                         } 
3761                                         else if (compilerNode instanceof net.sourceforge.phpdt.internal.compiler.ast.JavadocMessageSend) {
3762                                                 net.sourceforge.phpdt.internal.compiler.ast.Expression expression = ((net.sourceforge.phpdt.internal.compiler.ast.JavadocMessageSend)compilerNode).receiver;
3763                                                 if (expression instanceof net.sourceforge.phpdt.internal.compiler.ast.TypeReference) {
3764                                                         typeRef = (net.sourceforge.phpdt.internal.compiler.ast.TypeReference) expression;
3765                                                 }
3766                                                 // TODO (frederic) remove following line to fix bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=62650
3767                                                 recordNodes(name, compilerNode);
3768                                         }
3769                                         // record name and qualifier
3770                                         if (typeRef != null && methodRef.getQualifier() != null) {
3771                                                 recordName(methodRef.getQualifier(), typeRef);
3772                                         }
3773                                 }
3774                                 // Resolve parameters
3775                                 Iterator parameters = methodRef.parameters().listIterator();
3776                                 while (parameters.hasNext()) {
3777                                         MethodRefParameter param = (MethodRefParameter) parameters.next();
3778                                         net.sourceforge.phpdt.internal.compiler.ast.Expression expression = (net.sourceforge.phpdt.internal.compiler.ast.Expression) javadoc.getNodeStartingAt(param.getStartPosition());
3779                                         if (expression != null) {
3780                                                 recordNodes(param, expression);
3781                                                 if (expression instanceof JavadocArgumentExpression) {
3782                                                         JavadocArgumentExpression argExpr = (JavadocArgumentExpression) expression;
3783                                                         net.sourceforge.phpdt.internal.compiler.ast.TypeReference typeRef = argExpr.argument.type;
3784                                                         if (this.ast.apiLevel >= AST.JLS3) param.setVarargs(argExpr.argument.isVarArgs());
3785                                                         recordNodes(param.getType(), typeRef);
3786                                                         if (param.getType().isSimpleType()) {
3787                                                                 recordName(((SimpleType)param.getType()).getName(), typeRef);
3788                                                         } else if (param.getType().isArrayType()) {
3789                                                                 Type type = ((ArrayType) param.getType()).getElementType();
3790                                                                 recordNodes(type, typeRef);
3791                                                                 if (type.isSimpleType()) {
3792                                                                         recordName(((SimpleType)type).getName(), typeRef);
3793                                                                 }
3794                                                         }
3795                                                 }
3796                                         }
3797                                 }
3798                         } else if (node.getNodeType() == ASTNode.SIMPLE_NAME ||
3799                                         node.getNodeType() == ASTNode.QUALIFIED_NAME) {
3800                                 net.sourceforge.phpdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(node.getStartPosition());
3801                                 recordName((Name) node, compilerNode);
3802                         } else if (node.getNodeType() == ASTNode.TAG_ELEMENT) {
3803                                 // resolve member and method references binding
3804                                 recordNodes(javadoc, (TagElement) node);
3805                         }
3806                 }
3807         }
3808         
3809         protected void recordPendingNameScopeResolution(Name name) {
3810                 if (this.pendingNameScopeResolution == null) {
3811                         this.pendingNameScopeResolution = new HashSet();
3812                 }
3813                 this.pendingNameScopeResolution.add(name);
3814         }
3815         
3816         protected void recordPendingThisExpressionScopeResolution(ThisExpression thisExpression) {
3817                 if (this.pendingThisExpressionScopeResolution == null) {
3818                         this.pendingThisExpressionScopeResolution = new HashSet();
3819                 }
3820                 this.pendingThisExpressionScopeResolution.add(thisExpression);
3821         }
3822         
3823         /**
3824          * Remove whitespaces and comments before and after the expression.
3825          */     
3826         private void trimWhiteSpacesAndComments(net.sourceforge.phpdt.internal.compiler.ast.Expression expression) {
3827                 int start = expression.sourceStart;
3828                 int end = expression.sourceEnd;
3829                 int token;
3830                 int trimLeftPosition = expression.sourceStart;
3831                 int trimRightPosition = expression.sourceEnd;
3832                 boolean first = true;
3833                 Scanner removeBlankScanner = this.ast.scanner;
3834                 try {
3835                         removeBlankScanner.setSource(this.compilationUnitSource);
3836                         removeBlankScanner.resetTo(start, end);
3837                         while (true) {
3838                                 token = removeBlankScanner.getNextToken();
3839                                 switch (token) {
3840                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC :
3841                                         case TerminalTokens.TokenNameCOMMENT_LINE :
3842                                         case TerminalTokens.TokenNameCOMMENT_BLOCK :
3843                                                 if (first) {
3844                                                         trimLeftPosition = removeBlankScanner.currentPosition;
3845                                                 }
3846                                                 break;
3847                                         case TerminalTokens.TokenNameWHITESPACE :
3848                                                 if (first) {
3849                                                         trimLeftPosition = removeBlankScanner.currentPosition;
3850                                                 }
3851                                                 break;
3852                                         case TerminalTokens.TokenNameEOF :
3853                                                 expression.sourceStart = trimLeftPosition;
3854                                                 expression.sourceEnd = trimRightPosition;
3855                                                 return;
3856                                         default :
3857                                                 /*
3858                                                  * if we find something else than a whitespace or a comment,
3859                                                  * then we reset the trimRigthPosition to the expression
3860                                                  * source end.
3861                                                  */
3862                                                 trimRightPosition = removeBlankScanner.currentPosition - 1;
3863                                                 first = false;                          
3864                                 }
3865                         }
3866                 } catch (InvalidInputException e){
3867                         // ignore
3868                 }
3869         }
3870
3871         /**
3872          * Remove potential trailing comment by settings the source end on the closing parenthesis
3873          */
3874         protected void removeLeadingAndTrailingCommentsFromLiteral(ASTNode node) {
3875                 int start = node.getStartPosition();
3876                 this.scanner.resetTo(start, start + node.getLength());
3877                 int token;
3878                 int startPosition = -1;
3879                 try {
3880                         while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
3881                                 switch(token) {
3882                                         case TerminalTokens.TokenNameIntegerLiteral :
3883                                         case TerminalTokens.TokenNameFloatingPointLiteral :
3884                                         case TerminalTokens.TokenNameLongLiteral :
3885                                         case TerminalTokens.TokenNameDoubleLiteral :
3886                                         case TerminalTokens.TokenNameCharacterLiteral :
3887                                                 if (startPosition == -1) {
3888                                                         startPosition = this.scanner.startPosition;
3889                                                 }
3890                                                 int end = this.scanner.currentPosition;
3891                                                 node.setSourceRange(startPosition, end - startPosition);
3892                                                 return;
3893                                         case TerminalTokens.TokenNameMINUS :
3894                                                 startPosition = this.scanner.startPosition;
3895                                                 break;
3896                                 }
3897                         }
3898                 } catch(InvalidInputException e) {
3899                         // ignore
3900                 }
3901         }
3902         
3903         /**
3904          * Remove potential trailing comment by settings the source end on the closing parenthesis
3905          */
3906         protected void removeTrailingCommentFromExpressionEndingWithAParen(ASTNode node) {
3907                 int start = node.getStartPosition();
3908                 this.scanner.resetTo(start, start + node.getLength());
3909                 int token;
3910                 int parenCounter = 0;
3911                 try {
3912                         while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
3913                                 switch(token) {
3914                                         case TerminalTokens.TokenNameLPAREN :
3915                                                 parenCounter++;
3916                                                 break;
3917                                         case TerminalTokens.TokenNameRPAREN :
3918                                                 parenCounter--;
3919                                                 if (parenCounter == 0) {
3920                                                         int end = this.scanner.currentPosition - 1;
3921                                                         node.setSourceRange(start, end - start + 1);
3922                                                 }
3923                                 }
3924                         }
3925                 } catch(InvalidInputException e) {
3926                         // ignore
3927                 }
3928         }
3929
3930         /**
3931          * This method is used to retrieve the end position of the block.
3932          * @return int the dimension found, -1 if none
3933          */
3934         protected int retrieveClosingAngleBracketPosition(int start) {
3935                 this.scanner.resetTo(start, this.compilationUnitSourceLength);
3936                 this.scanner.returnOnlyGreater = true;
3937                 try {
3938                         int token;
3939                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3940                                 switch(token) {
3941                                         case TerminalTokens.TokenNameGREATER:
3942                                                 return this.scanner.currentPosition - 1;
3943                                         default:
3944                                                 return start;
3945                                 }
3946                         }
3947                 } catch(InvalidInputException e) {
3948                         // ignore
3949                 }
3950                 this.scanner.returnOnlyGreater = false;
3951                 return start;
3952         }
3953
3954         /**
3955          * This method is used to set the right end position for expression
3956          * statement. The actual AST nodes don't include the trailing semicolon.
3957          * This method fixes the length of the corresponding node.
3958          */
3959         protected void retrieveColonPosition(ASTNode node) {
3960                 int start = node.getStartPosition();
3961                 int length = node.getLength();
3962                 int end = start + length;
3963                 this.scanner.resetTo(end, this.compilationUnitSourceLength);
3964                 try {
3965                         int token;
3966                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3967                                 switch(token) {
3968                                         case TerminalTokens.TokenNameCOLON:
3969                                                 node.setSourceRange(start, this.scanner.currentPosition - start);
3970                                                 return;
3971                                 }
3972                         }
3973                 } catch(InvalidInputException e) {
3974                         // ignore
3975                 }
3976         }
3977         /**
3978          * This method is used to retrieve the start position of the Ellipsis
3979          */
3980         protected int retrieveEllipsisStartPosition(int start, int end) {
3981                 this.scanner.resetTo(start, end);
3982                 try {
3983                         int token;
3984                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
3985                                 switch(token) {
3986                                         case TerminalTokens.TokenNameELLIPSIS:
3987                                                 return this.scanner.startPosition - 1;
3988                                 }
3989                         }
3990                 } catch(InvalidInputException e) {
3991                         // ignore
3992                 }
3993                 return -1;
3994         
3995         }
3996         /**
3997          * This method is used to retrieve the end position of the block.
3998          * @return int the dimension found, -1 if none
3999          */
4000         protected int retrieveEndBlockPosition(int start, int end) {
4001                 this.scanner.resetTo(start, end);
4002                 int count = 0;
4003                 try {
4004                         int token;
4005                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4006                                 switch(token) {
4007                                         case TerminalTokens.TokenNameLBRACE://110
4008                                                 count++;
4009                                                 break;
4010                                         case TerminalTokens.TokenNameRBRACE://95
4011                                                 count--;
4012                                                 if (count == 0) {
4013                                                         return this.scanner.currentPosition - 1;
4014                                                 }
4015                                 }
4016                         }
4017                 } catch(InvalidInputException e) {
4018                         // ignore
4019                 }
4020                 return -1;
4021         }
4022
4023         protected int retrieveSemiColonPosition(Expression node) {
4024                 int start = node.getStartPosition();
4025                 int length = node.getLength();
4026                 int end = start + length;
4027                 this.scanner.resetTo(end, this.compilationUnitSourceLength);
4028                 try {
4029                         int token;
4030                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4031                                 switch(token) {
4032                                         case TerminalTokens.TokenNameSEMICOLON:
4033                                                 return this.scanner.currentPosition - 1;
4034                                 }
4035                         }
4036                 } catch(InvalidInputException e) {
4037                         // ignore
4038                 }
4039                 return -1;
4040         }
4041
4042         /**
4043          * This method is used to retrieve the ending position for a type declaration when the dimension is right after the type
4044          * name.
4045          * For example:
4046          *    int[] i; => return 5, but int i[] => return -1;
4047          * @return int the dimension found
4048          */
4049         protected int retrieveEndOfDimensionsPosition(int start, int end) {
4050                 this.scanner.resetTo(start, end);
4051                 int foundPosition = -1;
4052                 try {
4053                         int token;
4054                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4055                                 switch(token) {
4056                                         case TerminalTokens.TokenNameLBRACKET:
4057                                         case TerminalTokens.TokenNameCOMMENT_BLOCK:
4058                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC:
4059                                         case TerminalTokens.TokenNameCOMMENT_LINE:
4060                                                 break;
4061                                         case TerminalTokens.TokenNameRBRACKET://166
4062                                                 foundPosition = this.scanner.currentPosition - 1;
4063                                                 break;
4064                                         default:
4065                                                 return foundPosition;
4066                                 }
4067                         }
4068                 } catch(InvalidInputException e) {
4069                         // ignore
4070                 }
4071                 return foundPosition;
4072         }
4073
4074         /**
4075          * This method is used to retrieve the position just before the left bracket.
4076          * @return int the dimension found, -1 if none
4077          */
4078         protected int retrieveEndOfElementTypeNamePosition(int start, int end) {
4079                 this.scanner.resetTo(start, end);
4080                 try {
4081                         int token;
4082                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4083                                 switch(token) {
4084                                         case TerminalTokens.TokenNameIdentifier:
4085                                         case TerminalTokens.TokenNamebyte:
4086                                         case TerminalTokens.TokenNamechar:
4087                                         case TerminalTokens.TokenNamedouble:
4088                                         case TerminalTokens.TokenNamefloat:
4089                                         case TerminalTokens.TokenNameint:
4090                                         case TerminalTokens.TokenNamelong:
4091                                         case TerminalTokens.TokenNameshort:
4092                                         case TerminalTokens.TokenNameboolean:
4093                                                 return this.scanner.currentPosition - 1;
4094                                 }
4095                         }
4096                 } catch(InvalidInputException e) {
4097                         // ignore
4098                 }
4099                 return -1;
4100         }
4101
4102         /**
4103          * This method is used to retrieve the position after the right parenthesis.
4104          * @return int the position found
4105          */
4106         protected int retrieveEndOfRightParenthesisPosition(int start, int end) {
4107                 this.scanner.resetTo(start, end);
4108                 try {
4109                         int token;
4110                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4111                                 switch(token) {
4112                                         case TerminalTokens.TokenNameRPAREN:
4113                                                 return this.scanner.currentPosition;
4114                                 }
4115                         }
4116                 } catch(InvalidInputException e) {
4117                         // ignore
4118                 }
4119                 return -1;
4120         }
4121
4122         /**
4123          * This method is used to retrieve the array dimension declared after the
4124          * name of a local or a field declaration.
4125          * For example:
4126          *    int i, j[] = null, k[][] = {{}};
4127          *    It should return 0 for i, 1 for j and 2 for k.
4128          * @return int the dimension found
4129          */
4130         protected int retrieveExtraDimension(int start, int end) {
4131                 this.scanner.resetTo(start, end);
4132                 int dimensions = 0;
4133                 try {
4134                         int token;
4135                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4136                                 switch(token) {
4137                                         case TerminalTokens.TokenNameLBRACKET:
4138                                         case TerminalTokens.TokenNameCOMMENT_BLOCK:
4139                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC:
4140                                         case TerminalTokens.TokenNameCOMMENT_LINE:
4141                                                 break;
4142                                         case TerminalTokens.TokenNameRBRACKET://166
4143                                                 dimensions++;
4144                                                 break;
4145                                         default:
4146                                                 return dimensions;
4147                                 }
4148                         }
4149                 } catch(InvalidInputException e) {
4150                         // ignore
4151                 }
4152                 return dimensions;
4153         }
4154
4155         protected void retrieveIdentifierAndSetPositions(int start, int end, Name name) {
4156                 this.scanner.resetTo(start, end);
4157                 int token;
4158                 try {
4159                         while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
4160                                 if (token == TerminalTokens.TokenNameIdentifier) {
4161                                         int startName = this.scanner.startPosition;
4162                                         int endName = this.scanner.currentPosition - 1;
4163                                         name.setSourceRange(startName, endName - startName + 1);
4164                                         return;
4165                                 }
4166                         }
4167                 } catch(InvalidInputException e) {
4168                         // ignore
4169                 }
4170         }
4171         
4172         /**
4173          * This method is used to retrieve the start position of the block.
4174          * @return int the dimension found, -1 if none
4175          */
4176         protected int retrieveIdentifierEndPosition(int start, int end) {
4177                 this.scanner.resetTo(start, end);
4178                 try {
4179                         int token;
4180                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4181                                 switch(token) {
4182                                         case TerminalTokens.TokenNameIdentifier://110
4183                                                 return this.scanner.getCurrentTokenEndPosition();
4184                                 }
4185                         }
4186                 } catch(InvalidInputException e) {
4187                         // ignore
4188                 }
4189                 return -1;
4190         }       
4191
4192         /**
4193          * This method is used to retrieve position before the next comma or semi-colon.
4194          * @param initializerEnd the given initializer end exclusive
4195          * @return int the position found.
4196          */
4197         protected int retrieveEndOfPotentialExtendedDimensions(int initializerEnd, int nameEnd, int end) {
4198                 this.scanner.resetTo(initializerEnd, end);
4199                 boolean hasTokens = false;
4200                 int balance = 0;
4201                 int pos = initializerEnd > nameEnd ? initializerEnd - 1 : nameEnd;
4202                 try {
4203                         int token;
4204                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4205                                 hasTokens = true;
4206                                 switch(token) {
4207                                         case TerminalTokens.TokenNameLBRACE :
4208                                         case TerminalTokens.TokenNameLBRACKET :
4209                                                 balance++;
4210                                                 break;
4211                                         case TerminalTokens.TokenNameRBRACKET :
4212                                         case TerminalTokens.TokenNameRBRACE :
4213                                                 balance --;
4214                                                 pos = this.scanner.currentPosition - 1;
4215                                                 break;
4216                                         case TerminalTokens.TokenNameCOMMA :
4217                                                 if (balance == 0) return pos;
4218                                                 // case where a missing closing brace doesn't close an array initializer
4219                                                 pos = this.scanner.currentPosition - 1;
4220                                                 break;
4221                                         case TerminalTokens.TokenNameSEMICOLON :
4222                                                 if (balance == 0) return pos;
4223                                                 return -pos;
4224                                 }
4225                         }
4226                 } catch(InvalidInputException e) {
4227                         // ignore
4228                 }
4229                 // no token, we simply return pos as the right position
4230                 return hasTokens ? Integer.MIN_VALUE : pos;
4231         }
4232
4233         protected int retrieveProperRightBracketPosition(int bracketNumber, int start) {
4234                 this.scanner.resetTo(start, this.compilationUnitSourceLength);
4235                 try {
4236                         int token, count = 0;
4237                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4238                                 switch(token) {
4239                                         case TerminalTokens.TokenNameRBRACKET:
4240                                                 count++;
4241                                                 if (count == bracketNumber) {
4242                                                         return this.scanner.currentPosition - 1;
4243                                                 }
4244                                 }
4245                         }
4246                 } catch(InvalidInputException e) {
4247                         // ignore
4248                 }
4249                 return -1;
4250         }
4251
4252         /**
4253          * This method is used to retrieve position before the next right brace or semi-colon.
4254          * @return int the position found.
4255          */
4256         protected int retrieveRightBraceOrSemiColonPosition(int start, int end) {
4257                 this.scanner.resetTo(start, end);
4258                 try {
4259                         int token;
4260                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4261                                 switch(token) {
4262                                         case TerminalTokens.TokenNameRBRACE :
4263                                                 return this.scanner.currentPosition - 1;
4264                                         case TerminalTokens.TokenNameSEMICOLON :
4265                                                 return this.scanner.currentPosition - 1;
4266                                 }
4267                         }
4268                 } catch(InvalidInputException e) {
4269                         // ignore
4270                 }
4271                 return -1;
4272         }
4273
4274         /**
4275          * This method is used to retrieve position before the next right brace or semi-colon.
4276          * @return int the position found.
4277          */
4278         protected int retrieveRightBrace(int start, int end) {
4279                 this.scanner.resetTo(start, end);
4280                 try {
4281                         int token;
4282                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4283                                 switch(token) {
4284                                         case TerminalTokens.TokenNameRBRACE :
4285                                                 return this.scanner.currentPosition - 1;
4286                                 }
4287                         }
4288                 } catch(InvalidInputException e) {
4289                         // ignore
4290                 }
4291                 return -1;
4292         }
4293         
4294         /**
4295          * This method is used to retrieve the position of the right bracket.
4296          * @return int the dimension found, -1 if none
4297          */
4298         protected int retrieveRightBracketPosition(int start, int end) {
4299                 this.scanner.resetTo(start, end);
4300                 try {
4301                         int token;
4302                         int balance = 0;
4303                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4304                                 switch(token) {
4305                                         case TerminalTokens.TokenNameLBRACKET :
4306                                                 balance++;
4307                                                 break;
4308                                         case TerminalTokens.TokenNameRBRACKET :
4309                                                 balance--;
4310                                                 if (balance == 0) return this.scanner.currentPosition - 1;
4311                                                 break;
4312                                 }
4313                         }
4314                 } catch(InvalidInputException e) {
4315                         // ignore
4316                 }
4317                 return -1;
4318         }
4319
4320         /**
4321          * This method is used to retrieve the start position of the block.
4322          * @return int the dimension found, -1 if none
4323          */
4324         protected int retrieveStartBlockPosition(int start, int end) {
4325                 this.scanner.resetTo(start, end);
4326                 try {
4327                         int token;
4328                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4329                                 switch(token) {
4330                                         case TerminalTokens.TokenNameLBRACE://110
4331                                                 return this.scanner.startPosition;
4332                                 }
4333                         }
4334                 } catch(InvalidInputException e) {
4335                         // ignore
4336                 }
4337                 return -1;
4338         }
4339
4340         /**
4341          * This method is used to retrieve the starting position of the catch keyword.
4342          * @return int the dimension found, -1 if none
4343          */
4344         protected int retrieveStartingCatchPosition(int start, int end) {
4345                 this.scanner.resetTo(start, end);
4346                 try {
4347                         int token;
4348                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4349                                 switch(token) {
4350                                         case TerminalTokens.TokenNamecatch://225
4351                                                 return this.scanner.startPosition;
4352                                 }
4353                         }
4354                 } catch(InvalidInputException e) {
4355                         // ignore
4356                 }
4357                 return -1;
4358         }
4359         
4360         public void setAST(AST ast) {
4361                 this.ast = ast;
4362                 this.docParser = new DocCommentParser(this.ast, this.scanner, this.insideComments);
4363         }
4364
4365         protected void setModifiers(AnnotationTypeDeclaration typeDecl, net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
4366                 this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
4367                 this.setModifiers(typeDecl, typeDeclaration.annotations, typeDeclaration.sourceStart);
4368         }
4369         
4370         protected void setModifiers(AnnotationTypeMemberDeclaration annotationTypeMemberDecl, net.sourceforge.phpdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
4371                 this.scanner.resetTo(annotationTypeMemberDeclaration.declarationSourceStart, annotationTypeMemberDeclaration.sourceStart);
4372                 this.setModifiers(annotationTypeMemberDecl, annotationTypeMemberDeclaration.annotations, annotationTypeMemberDeclaration.sourceStart);
4373         }
4374
4375         /**
4376          * @param bodyDeclaration
4377          */
4378         protected void setModifiers(BodyDeclaration bodyDeclaration, net.sourceforge.phpdt.internal.compiler.ast.Annotation[] annotations, int modifiersEnd) {
4379                 this.scanner.tokenizeWhiteSpace = false;
4380                 try {
4381                         int token;
4382                         int indexInAnnotations = 0;
4383                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4384                                 IExtendedModifier modifier = null;
4385                                 switch(token) {
4386                                         case TerminalTokens.TokenNameabstract:
4387                                                 modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4388                                                 break;
4389                                         case TerminalTokens.TokenNamepublic:
4390                                                 modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4391                                                 break;
4392                                         case TerminalTokens.TokenNamestatic:
4393                                                 modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4394                                                 break;
4395                                         case TerminalTokens.TokenNameprotected:
4396                                                 modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4397                                                 break;
4398                                         case TerminalTokens.TokenNameprivate:
4399                                                 modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4400                                                 break;
4401                                         case TerminalTokens.TokenNamefinal:
4402                                                 modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4403                                                 break;
4404                                         case TerminalTokens.TokenNamenative:
4405                                                 modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4406                                                 break;
4407                                         case TerminalTokens.TokenNamesynchronized:
4408                                                 modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4409                                                 break;
4410                                         case TerminalTokens.TokenNametransient:
4411                                                 modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4412                                                 break;
4413                                         case TerminalTokens.TokenNamevolatile:
4414                                                 modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4415                                                 break;
4416                                         case TerminalTokens.TokenNamestrictfp:
4417                                                 modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4418                                                 break;
4419                                         case TerminalTokens.TokenNameAT :
4420                                                 // we have an annotation
4421                                                 if (annotations != null && indexInAnnotations < annotations.length) {
4422                                                         net.sourceforge.phpdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4423                                                         modifier = convert(annotation);
4424                                                         this.scanner.resetTo(annotation.declarationSourceEnd + 1, modifiersEnd);
4425                                                 }
4426                                                 break;
4427                                         case TerminalTokens.TokenNameCOMMENT_BLOCK :
4428                                         case TerminalTokens.TokenNameCOMMENT_LINE :
4429                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4430                                                 break;
4431                                         default :
4432                                                 // there is some syntax errors in source code
4433                                                 break;
4434                                 }
4435                                 if (modifier != null) {
4436                                         bodyDeclaration.modifiers().add(modifier);
4437                                 }
4438                         }
4439                 } catch(InvalidInputException e) {
4440                         // ignore
4441                 }
4442         }
4443
4444         protected void setModifiers(EnumDeclaration enumDeclaration, net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration enumDeclaration2) {
4445                 this.scanner.resetTo(enumDeclaration2.declarationSourceStart, enumDeclaration2.sourceStart);
4446                 this.setModifiers(enumDeclaration, enumDeclaration2.annotations, enumDeclaration2.sourceStart);
4447         }
4448         
4449         protected void setModifiers(EnumConstantDeclaration enumConstantDeclaration, net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
4450                 switch(this.ast.apiLevel) {
4451                         case AST.JLS2_INTERNAL :
4452                                 enumConstantDeclaration.internalSetModifiers(fieldDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
4453                                 if (fieldDeclaration.annotations != null) {
4454                                         enumConstantDeclaration.setFlags(enumConstantDeclaration.getFlags() | ASTNode.MALFORMED);
4455                                 }
4456                                 break;
4457                         case AST.JLS3 :
4458                                 this.scanner.resetTo(fieldDeclaration.declarationSourceStart, fieldDeclaration.sourceStart);
4459                                 this.setModifiers(enumConstantDeclaration, fieldDeclaration.annotations, fieldDeclaration.sourceStart);
4460                 }
4461         }
4462         
4463         /**
4464          * @param fieldDeclaration
4465          * @param fieldDecl
4466          */
4467         protected void setModifiers(FieldDeclaration fieldDeclaration, net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
4468                 switch(this.ast.apiLevel) {
4469                         case AST.JLS2_INTERNAL :
4470                                 fieldDeclaration.internalSetModifiers(fieldDecl.modifiers & ExtraCompilerModifiers.AccJustFlag);
4471                                 if (fieldDecl.annotations != null) {
4472                                         fieldDeclaration.setFlags(fieldDeclaration.getFlags() | ASTNode.MALFORMED);
4473                                 }
4474                                 break;
4475                         case AST.JLS3 :
4476                                 this.scanner.resetTo(fieldDecl.declarationSourceStart, fieldDecl.sourceStart);
4477                                 this.setModifiers(fieldDeclaration, fieldDecl.annotations, fieldDecl.sourceStart);
4478                 }
4479         }
4480         
4481         /**
4482          * @param initializer
4483          * @param oldInitializer
4484          */
4485         protected void setModifiers(Initializer initializer, net.sourceforge.phpdt.internal.compiler.ast.Initializer oldInitializer) {
4486                 switch(this.ast.apiLevel) {
4487                         case AST.JLS2_INTERNAL: 
4488                                 initializer.internalSetModifiers(oldInitializer.modifiers & ExtraCompilerModifiers.AccJustFlag);
4489                                 if (oldInitializer.annotations != null) {
4490                                         initializer.setFlags(initializer.getFlags() | ASTNode.MALFORMED);
4491                                 }
4492                                 break;
4493                         case AST.JLS3 :
4494                                 this.scanner.resetTo(oldInitializer.declarationSourceStart, oldInitializer.bodyStart);
4495                                 this.setModifiers(initializer, oldInitializer.annotations, oldInitializer.bodyStart);
4496                 }
4497         }
4498         /**
4499          * @param methodDecl
4500          * @param methodDeclaration
4501          */
4502         protected void setModifiers(MethodDeclaration methodDecl, AbstractMethodDeclaration methodDeclaration) {
4503                 switch(this.ast.apiLevel) {
4504                         case AST.JLS2_INTERNAL :
4505                                 methodDecl.internalSetModifiers(methodDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
4506                                 if (methodDeclaration.annotations != null) {
4507                                         methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
4508                                 }
4509                                 break;
4510                         case AST.JLS3 :
4511                                 this.scanner.resetTo(methodDeclaration.declarationSourceStart, methodDeclaration.sourceStart);
4512                                 this.setModifiers(methodDecl, methodDeclaration.annotations, methodDeclaration.sourceStart);
4513                 }
4514         }
4515
4516         /**
4517          * @param variableDecl
4518          * @param argument
4519          */
4520         protected void setModifiers(SingleVariableDeclaration variableDecl, Argument argument) {
4521                 switch(this.ast.apiLevel) {
4522                         case AST.JLS2_INTERNAL :
4523                                 variableDecl.internalSetModifiers(argument.modifiers & ExtraCompilerModifiers.AccJustFlag);
4524                                 if (argument.annotations != null) {
4525                                         variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
4526                                 }
4527                                 break;
4528                         case AST.JLS3 :
4529                                 this.scanner.resetTo(argument.declarationSourceStart, argument.sourceStart);
4530                                 net.sourceforge.phpdt.internal.compiler.ast.Annotation[] annotations = argument.annotations;
4531                                 int indexInAnnotations = 0;
4532                                 try {
4533                                         int token;
4534                                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4535                                                 IExtendedModifier modifier = null;
4536                                                 switch(token) {
4537                                                         case TerminalTokens.TokenNameabstract:
4538                                                                 modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4539                                                                 break;
4540                                                         case TerminalTokens.TokenNamepublic:
4541                                                                 modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4542                                                                 break;
4543                                                         case TerminalTokens.TokenNamestatic:
4544                                                                 modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4545                                                                 break;
4546                                                         case TerminalTokens.TokenNameprotected:
4547                                                                 modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4548                                                                 break;
4549                                                         case TerminalTokens.TokenNameprivate:
4550                                                                 modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4551                                                                 break;
4552                                                         case TerminalTokens.TokenNamefinal:
4553                                                                 modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4554                                                                 break;
4555                                                         case TerminalTokens.TokenNamenative:
4556                                                                 modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4557                                                                 break;
4558                                                         case TerminalTokens.TokenNamesynchronized:
4559                                                                 modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4560                                                                 break;
4561                                                         case TerminalTokens.TokenNametransient:
4562                                                                 modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4563                                                                 break;
4564                                                         case TerminalTokens.TokenNamevolatile:
4565                                                                 modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4566                                                                 break;
4567                                                         case TerminalTokens.TokenNamestrictfp:
4568                                                                 modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4569                                                                 break;
4570                                                         case TerminalTokens.TokenNameAT :
4571                                                                 // we have an annotation
4572                                                                 if (annotations != null && indexInAnnotations < annotations.length) {
4573                                                                         net.sourceforge.phpdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4574                                                                         modifier = convert(annotation);
4575                                                                         this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4576                                                                 }
4577                                                                 break;
4578                                                         case TerminalTokens.TokenNameCOMMENT_BLOCK :
4579                                                         case TerminalTokens.TokenNameCOMMENT_LINE :
4580                                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4581                                                                 break;
4582                                                         default :
4583                                                                 return;
4584                                                 }
4585                                                 if (modifier != null) {
4586                                                         variableDecl.modifiers().add(modifier);
4587                                                 }
4588                                         }
4589                                 } catch(InvalidInputException e) {
4590                                         // ignore
4591                                 }
4592                 }
4593         }
4594         
4595         protected void setModifiers(SingleVariableDeclaration variableDecl, LocalDeclaration localDeclaration) {
4596                 switch(this.ast.apiLevel) {
4597                 case AST.JLS2_INTERNAL :
4598                         variableDecl.internalSetModifiers(localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
4599                         if (localDeclaration.annotations != null) {
4600                                 variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
4601                         }
4602                         break;
4603                 case AST.JLS3 :
4604                         this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
4605                         net.sourceforge.phpdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
4606                         int indexInAnnotations = 0;
4607                         try {
4608                                 int token;
4609                                 while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4610                                         IExtendedModifier modifier = null;
4611                                         switch(token) {
4612                                                 case TerminalTokens.TokenNameabstract:
4613                                                         modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4614                                                         break;
4615                                                 case TerminalTokens.TokenNamepublic:
4616                                                         modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4617                                                         break;
4618                                                 case TerminalTokens.TokenNamestatic:
4619                                                         modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4620                                                         break;
4621                                                 case TerminalTokens.TokenNameprotected:
4622                                                         modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4623                                                         break;
4624                                                 case TerminalTokens.TokenNameprivate:
4625                                                         modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4626                                                         break;
4627                                                 case TerminalTokens.TokenNamefinal:
4628                                                         modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4629                                                         break;
4630                                                 case TerminalTokens.TokenNamenative:
4631                                                         modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4632                                                         break;
4633                                                 case TerminalTokens.TokenNamesynchronized:
4634                                                         modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4635                                                         break;
4636                                                 case TerminalTokens.TokenNametransient:
4637                                                         modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4638                                                         break;
4639                                                 case TerminalTokens.TokenNamevolatile:
4640                                                         modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4641                                                         break;
4642                                                 case TerminalTokens.TokenNamestrictfp:
4643                                                         modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4644                                                         break;
4645                                                 case TerminalTokens.TokenNameAT :
4646                                                         // we have an annotation
4647                                                         if (annotations != null && indexInAnnotations < annotations.length) {
4648                                                                 net.sourceforge.phpdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4649                                                                 modifier = convert(annotation);
4650                                                                 this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4651                                                         }
4652                                                         break;
4653                                                 case TerminalTokens.TokenNameCOMMENT_BLOCK :
4654                                                 case TerminalTokens.TokenNameCOMMENT_LINE :
4655                                                 case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4656                                                         break;
4657                                                 default :
4658                                                         return;
4659                                         }
4660                                         if (modifier != null) {
4661                                                 variableDecl.modifiers().add(modifier);
4662                                         }
4663                                 }
4664                         } catch(InvalidInputException e) {
4665                                 // ignore
4666                         }
4667                 }
4668         }
4669
4670         /**
4671          * @param typeDecl
4672          * @param typeDeclaration
4673          */
4674         protected void setModifiers(TypeDeclaration typeDecl, net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
4675                 switch(this.ast.apiLevel) { 
4676                         case AST.JLS2_INTERNAL :
4677                                 int modifiers = typeDeclaration.modifiers;
4678                                 modifiers &= ~ClassFileConstants.AccInterface; // remove AccInterface flags
4679                                 modifiers &= ExtraCompilerModifiers.AccJustFlag;
4680                                 typeDecl.internalSetModifiers(modifiers);
4681                                 if (typeDeclaration.annotations != null) {
4682                                         typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
4683                                 }
4684                                 break;
4685                         case AST.JLS3 :
4686                                 this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
4687                                 this.setModifiers(typeDecl, typeDeclaration.annotations, typeDeclaration.sourceStart);
4688                 }
4689         }
4690         
4691         /**
4692          * @param variableDeclarationExpression
4693          * @param localDeclaration
4694          */
4695         protected void setModifiers(VariableDeclarationExpression variableDeclarationExpression, LocalDeclaration localDeclaration) {
4696                 switch(this.ast.apiLevel) {
4697                         case AST.JLS2_INTERNAL :
4698                                 int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
4699                                 modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
4700                                 variableDeclarationExpression.internalSetModifiers(modifiers);
4701                                 if (localDeclaration.annotations != null) {
4702                                         variableDeclarationExpression.setFlags(variableDeclarationExpression.getFlags() | ASTNode.MALFORMED);
4703                                 }
4704                                 break;
4705                         case AST.JLS3 :
4706                                 this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
4707                                 net.sourceforge.phpdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
4708                                 int indexInAnnotations = 0;
4709                                 try {
4710                                         int token;
4711                                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4712                                                 IExtendedModifier modifier = null;
4713                                                 switch(token) {
4714                                                         case TerminalTokens.TokenNameabstract:
4715                                                                 modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4716                                                                 break;
4717                                                         case TerminalTokens.TokenNamepublic:
4718                                                                 modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4719                                                                 break;
4720                                                         case TerminalTokens.TokenNamestatic:
4721                                                                 modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4722                                                                 break;
4723                                                         case TerminalTokens.TokenNameprotected:
4724                                                                 modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4725                                                                 break;
4726                                                         case TerminalTokens.TokenNameprivate:
4727                                                                 modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4728                                                                 break;
4729                                                         case TerminalTokens.TokenNamefinal:
4730                                                                 modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4731                                                                 break;
4732                                                         case TerminalTokens.TokenNamenative:
4733                                                                 modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4734                                                                 break;
4735                                                         case TerminalTokens.TokenNamesynchronized:
4736                                                                 modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4737                                                                 break;
4738                                                         case TerminalTokens.TokenNametransient:
4739                                                                 modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4740                                                                 break;
4741                                                         case TerminalTokens.TokenNamevolatile:
4742                                                                 modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4743                                                                 break;
4744                                                         case TerminalTokens.TokenNamestrictfp:
4745                                                                 modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4746                                                                 break;
4747                                                         case TerminalTokens.TokenNameAT :
4748                                                                 // we have an annotation
4749                                                                 if (annotations != null && indexInAnnotations < annotations.length) {
4750                                                                         net.sourceforge.phpdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4751                                                                         modifier = convert(annotation);
4752                                                                         this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4753                                                                 }
4754                                                                 break;
4755                                                         case TerminalTokens.TokenNameCOMMENT_BLOCK :
4756                                                         case TerminalTokens.TokenNameCOMMENT_LINE :
4757                                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4758                                                                 break;
4759                                                         default :
4760                                                                 return;
4761                                                 }
4762                                                 if (modifier != null) {
4763                                                         variableDeclarationExpression.modifiers().add(modifier);
4764                                                 }
4765                                         }
4766                                 } catch(InvalidInputException e) {
4767                                         // ignore
4768                                 }
4769                 }               
4770         }
4771
4772         /**
4773          * @param variableDeclarationStatement
4774          * @param localDeclaration
4775          */
4776         protected void setModifiers(VariableDeclarationStatement variableDeclarationStatement, LocalDeclaration localDeclaration) {
4777                 switch(this.ast.apiLevel) {
4778                         case AST.JLS2_INTERNAL :
4779                                 int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
4780                                 modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
4781                                 variableDeclarationStatement.internalSetModifiers(modifiers);
4782                                 if (localDeclaration.annotations != null) {
4783                                         variableDeclarationStatement.setFlags(variableDeclarationStatement.getFlags() | ASTNode.MALFORMED);
4784                                 }
4785                                 break;
4786                         case AST.JLS3 :
4787                                 this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
4788                                 net.sourceforge.phpdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
4789                                 int indexInAnnotations = 0;
4790                                 try {
4791                                         int token;
4792                                         while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4793                                                 IExtendedModifier modifier = null;
4794                                                 switch(token) {
4795                                                         case TerminalTokens.TokenNameabstract:
4796                                                                 modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4797                                                                 break;
4798                                                         case TerminalTokens.TokenNamepublic:
4799                                                                 modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
4800                                                                 break;
4801                                                         case TerminalTokens.TokenNamestatic:
4802                                                                 modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
4803                                                                 break;
4804                                                         case TerminalTokens.TokenNameprotected:
4805                                                                 modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
4806                                                                 break;
4807                                                         case TerminalTokens.TokenNameprivate:
4808                                                                 modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
4809                                                                 break;
4810                                                         case TerminalTokens.TokenNamefinal:
4811                                                                 modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
4812                                                                 break;
4813                                                         case TerminalTokens.TokenNamenative:
4814                                                                 modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
4815                                                                 break;
4816                                                         case TerminalTokens.TokenNamesynchronized:
4817                                                                 modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
4818                                                                 break;
4819                                                         case TerminalTokens.TokenNametransient:
4820                                                                 modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
4821                                                                 break;
4822                                                         case TerminalTokens.TokenNamevolatile:
4823                                                                 modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
4824                                                                 break;
4825                                                         case TerminalTokens.TokenNamestrictfp:
4826                                                                 modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
4827                                                                 break;
4828                                                         case TerminalTokens.TokenNameAT :
4829                                                                 // we have an annotation
4830                                                                 if (annotations != null && indexInAnnotations < annotations.length) {
4831                                                                         net.sourceforge.phpdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4832                                                                         modifier = convert(annotation);
4833                                                                         this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4834                                                                 }
4835                                                                 break;
4836                                                         case TerminalTokens.TokenNameCOMMENT_BLOCK :
4837                                                         case TerminalTokens.TokenNameCOMMENT_LINE :
4838                                                         case TerminalTokens.TokenNameCOMMENT_JAVADOC :
4839                                                                 break;
4840                                                         default :
4841                                                                 return;
4842                                                 }
4843                                                 if (modifier != null) {
4844                                                         variableDeclarationStatement.modifiers().add(modifier);
4845                                                 }
4846                                         }
4847                                 } catch(InvalidInputException e) {
4848                                         // ignore
4849                                 }
4850                 }                               
4851         }
4852
4853         protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, net.sourceforge.phpdt.internal.compiler.ast.ASTNode node) {
4854                 int length = typeName.length;
4855                 final SimpleName firstToken = new SimpleName(this.ast);
4856                 firstToken.internalSetIdentifier(new String(typeName[0]));
4857                 firstToken.index = 1;
4858                 int start0 = (int)(positions[0]>>>32);
4859                 int start = start0;
4860                 int end = (int)(positions[0] & 0xFFFFFFFF);
4861                 firstToken.setSourceRange(start, end - start + 1);
4862                 final SimpleName secondToken = new SimpleName(this.ast);
4863                 secondToken.internalSetIdentifier(new String(typeName[1]));
4864                 secondToken.index = 2;
4865                 start = (int)(positions[1]>>>32);
4866                 end = (int)(positions[1] & 0xFFFFFFFF);
4867                 secondToken.setSourceRange(start, end - start + 1);
4868                 QualifiedName qualifiedName = new QualifiedName(this.ast);
4869                 qualifiedName.setQualifier(firstToken);
4870                 qualifiedName.setName(secondToken);
4871                 if (this.resolveBindings) {
4872                         recordNodes(qualifiedName, node);
4873                         recordPendingNameScopeResolution(qualifiedName);
4874                         recordNodes(firstToken, node);
4875                         recordNodes(secondToken, node);
4876                         recordPendingNameScopeResolution(firstToken);
4877                         recordPendingNameScopeResolution(secondToken);
4878                 }
4879                 qualifiedName.index = 2;
4880                 qualifiedName.setSourceRange(start0, end - start0 + 1);
4881                 SimpleName newPart = null;
4882                 for (int i = 2; i < length; i++) {
4883                         newPart = new SimpleName(this.ast);
4884                         newPart.internalSetIdentifier(new String(typeName[i]));
4885                         newPart.index = i + 1;
4886                         start = (int)(positions[i]>>>32);
4887                         end = (int)(positions[i] & 0xFFFFFFFF);
4888                         newPart.setSourceRange(start,  end - start + 1);
4889                         QualifiedName qualifiedName2 = new QualifiedName(this.ast);
4890                         qualifiedName2.setQualifier(qualifiedName);
4891                         qualifiedName2.setName(newPart);
4892                         qualifiedName = qualifiedName2;
4893                         qualifiedName.index = newPart.index;
4894                         qualifiedName.setSourceRange(start0, end - start0 + 1);
4895                         if (this.resolveBindings) {
4896                                 recordNodes(qualifiedName, node);
4897                                 recordNodes(newPart, node);                             
4898                                 recordPendingNameScopeResolution(qualifiedName);
4899                                 recordPendingNameScopeResolution(newPart);
4900                         }
4901                 }
4902                 QualifiedName name = qualifiedName;
4903                 if (this.resolveBindings) {
4904                         recordNodes(name, node);
4905                         recordPendingNameScopeResolution(name);
4906                 }
4907                 return name;
4908         }
4909         
4910         protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int endingIndex, net.sourceforge.phpdt.internal.compiler.ast.ASTNode node) {
4911                 int length = endingIndex + 1;
4912                 final SimpleName firstToken = new SimpleName(this.ast);
4913                 firstToken.internalSetIdentifier(new String(typeName[0]));
4914                 firstToken.index = 1;
4915                 int start0 = (int)(positions[0]>>>32);
4916                 int start = start0;
4917                 int end = (int) positions[0];
4918                 firstToken.setSourceRange(start, end - start + 1);
4919                 final SimpleName secondToken = new SimpleName(this.ast);
4920                 secondToken.internalSetIdentifier(new String(typeName[1]));
4921                 secondToken.index = 2;
4922                 start = (int)(positions[1]>>>32);
4923                 end = (int) positions[1];
4924                 secondToken.setSourceRange(start, end - start + 1);
4925                 QualifiedName qualifiedName = new QualifiedName(this.ast);
4926                 qualifiedName.setQualifier(firstToken);
4927                 qualifiedName.setName(secondToken);
4928                 if (this.resolveBindings) {
4929                         recordNodes(qualifiedName, node);
4930                         recordPendingNameScopeResolution(qualifiedName);
4931                         recordNodes(firstToken, node);
4932                         recordNodes(secondToken, node);
4933                         recordPendingNameScopeResolution(firstToken);
4934                         recordPendingNameScopeResolution(secondToken);
4935                 }
4936                 qualifiedName.index = 2;
4937                 qualifiedName.setSourceRange(start0, end - start0 + 1);
4938                 SimpleName newPart = null;
4939                 for (int i = 2; i < length; i++) {
4940                         newPart = new SimpleName(this.ast);
4941                         newPart.internalSetIdentifier(new String(typeName[i]));
4942                         newPart.index = i + 1;
4943                         start = (int)(positions[i]>>>32);
4944                         end = (int) positions[i];
4945                         newPart.setSourceRange(start,  end - start + 1);
4946                         QualifiedName qualifiedName2 = new QualifiedName(this.ast);
4947                         qualifiedName2.setQualifier(qualifiedName);
4948                         qualifiedName2.setName(newPart);
4949                         qualifiedName = qualifiedName2;
4950                         qualifiedName.index = newPart.index;
4951                         qualifiedName.setSourceRange(start0, end - start0 + 1);
4952                         if (this.resolveBindings) {
4953                                 recordNodes(qualifiedName, node);
4954                                 recordNodes(newPart, node);                             
4955                                 recordPendingNameScopeResolution(qualifiedName);
4956                                 recordPendingNameScopeResolution(newPart);
4957                         }
4958                 }
4959         if (newPart == null && this.resolveBindings) {
4960             recordNodes(qualifiedName, node);
4961             recordPendingNameScopeResolution(qualifiedName);
4962         }
4963                 return qualifiedName;
4964         }
4965         
4966         protected void setTypeNameForAnnotation(net.sourceforge.phpdt.internal.compiler.ast.Annotation compilerAnnotation, Annotation annotation) {
4967                 TypeReference typeReference = compilerAnnotation.type;
4968                 if (typeReference instanceof QualifiedTypeReference) {
4969                         QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
4970                         char[][] tokens = qualifiedTypeReference.tokens;
4971                         long[] positions = qualifiedTypeReference.sourcePositions;
4972                         // QualifiedName
4973                         annotation.setTypeName(setQualifiedNameNameAndSourceRanges(tokens, positions, typeReference));
4974                 } else {
4975                         SingleTypeReference singleTypeReference = (SingleTypeReference) typeReference;
4976                         final SimpleName name = new SimpleName(this.ast);
4977                         name.internalSetIdentifier(new String(singleTypeReference.token));
4978                         int start = singleTypeReference.sourceStart;
4979                         int end = singleTypeReference.sourceEnd;
4980                         name.setSourceRange(start, end - start + 1);
4981                         name.index = 1;
4982                         annotation.setTypeName(name);
4983                         if (this.resolveBindings) {
4984                                 recordNodes(name, typeReference);
4985                         }
4986                 }
4987         }
4988         
4989         protected void setTypeForField(FieldDeclaration fieldDeclaration, Type type, int extraDimension) {
4990                 if (extraDimension != 0) {
4991                         if (type.isArrayType()) {
4992                                 ArrayType arrayType = (ArrayType) type;
4993                                 int remainingDimensions = arrayType.getDimensions() - extraDimension;
4994                                 if (remainingDimensions == 0)  {
4995                                         // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
4996                                         Type elementType = arrayType.getElementType();
4997                                         // cut the child loose from its parent (without creating garbage)
4998                                         elementType.setParent(null, null);
4999                                         this.ast.getBindingResolver().updateKey(type, elementType);
5000                                         fieldDeclaration.setType(elementType);
5001                                 } else {
5002                                         int start = type.getStartPosition();
5003                                         ArrayType subarrayType = arrayType;
5004                                         int index = extraDimension;
5005                                         while (index > 0) {
5006                                                 subarrayType = (ArrayType) subarrayType.getComponentType();
5007                                                 index--;
5008                                         }
5009                                         int end = retrieveProperRightBracketPosition(remainingDimensions, start);
5010                                         subarrayType.setSourceRange(start, end - start + 1);
5011                                         // cut the child loose from its parent (without creating garbage)
5012                                         subarrayType.setParent(null, null);
5013                                         fieldDeclaration.setType(subarrayType);
5014                                         updateInnerPositions(subarrayType, remainingDimensions);
5015                                         this.ast.getBindingResolver().updateKey(type, subarrayType);
5016                                 }
5017                         } else {
5018                                 fieldDeclaration.setType(type);
5019                         }
5020                 } else {
5021                         if (type.isArrayType()) {
5022                                 // update positions of the component types of the array type
5023                                 int dimensions = ((ArrayType) type).getDimensions();
5024                                 updateInnerPositions(type, dimensions);
5025                         }
5026                         fieldDeclaration.setType(type);
5027                 }
5028         }
5029         
5030         protected void setTypeForMethodDeclaration(MethodDeclaration methodDeclaration, Type type, int extraDimension) {
5031                 if (extraDimension != 0) {
5032                         if (type.isArrayType()) {
5033                                 ArrayType arrayType = (ArrayType) type;
5034                                 int remainingDimensions = arrayType.getDimensions() - extraDimension;
5035                                 if (remainingDimensions == 0)  {
5036                                         // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
5037                                         Type elementType = arrayType.getElementType();
5038                                         // cut the child loose from its parent (without creating garbage)
5039                                         elementType.setParent(null, null);
5040                                         this.ast.getBindingResolver().updateKey(type, elementType);
5041                                         switch(this.ast.apiLevel) {
5042                                                 case AST.JLS2_INTERNAL :
5043                                                         methodDeclaration.internalSetReturnType(elementType);
5044                                                         break;
5045                                                 case AST.JLS3 :
5046                                                         methodDeclaration.setReturnType2(elementType);
5047                                                 break;
5048                                         }
5049                                 } else {
5050                                         int start = type.getStartPosition();
5051                                         ArrayType subarrayType = arrayType;
5052                                         int index = extraDimension;
5053                                         while (index > 0) {
5054                                                 subarrayType = (ArrayType) subarrayType.getComponentType();
5055                                                 index--;
5056                                         }
5057                                         int end = retrieveProperRightBracketPosition(remainingDimensions, start);
5058                                         subarrayType.setSourceRange(start, end - start + 1);
5059                                         // cut the child loose from its parent (without creating garbage)
5060                                         subarrayType.setParent(null, null);
5061                                         updateInnerPositions(subarrayType, remainingDimensions);
5062                                         switch(this.ast.apiLevel) {
5063                                                 case AST.JLS2_INTERNAL :
5064                                                         methodDeclaration.internalSetReturnType(subarrayType);
5065                                                         break;
5066                                                 case AST.JLS3 :
5067                                                         methodDeclaration.setReturnType2(subarrayType);
5068                                                 break;
5069                                         }
5070                                         this.ast.getBindingResolver().updateKey(type, subarrayType);
5071                                 }
5072                         } else {
5073                                 switch(this.ast.apiLevel) {
5074                                         case AST.JLS2_INTERNAL :
5075                                                 methodDeclaration.internalSetReturnType(type);
5076                                                 break;
5077                                         case AST.JLS3 :
5078                                                 methodDeclaration.setReturnType2(type);
5079                                         break;
5080                                 }
5081                         }
5082                 } else {
5083                         switch(this.ast.apiLevel) {
5084                                 case AST.JLS2_INTERNAL :
5085                                         methodDeclaration.internalSetReturnType(type);
5086                                         break;
5087                                 case AST.JLS3 :
5088                                         methodDeclaration.setReturnType2(type);
5089                                 break;
5090                         }
5091                 }
5092         }
5093         
5094         protected void setTypeForMethodDeclaration(AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration, Type type, int extraDimension) {
5095                 annotationTypeMemberDeclaration.setType(type);
5096         }
5097
5098         protected void setTypeForSingleVariableDeclaration(SingleVariableDeclaration singleVariableDeclaration, Type type, int extraDimension) {
5099                 if (extraDimension != 0) {
5100                         if (type.isArrayType()) {
5101                                 ArrayType arrayType = (ArrayType) type;
5102                                 int remainingDimensions = arrayType.getDimensions() - extraDimension;
5103                                 if (remainingDimensions == 0)  {
5104                                         // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
5105                                         Type elementType = arrayType.getElementType();
5106                                         // cut the child loose from its parent (without creating garbage)
5107                                         elementType.setParent(null, null);
5108                                         this.ast.getBindingResolver().updateKey(type, elementType);
5109                                         singleVariableDeclaration.setType(elementType);
5110                                 } else {
5111                                         int start = type.getStartPosition();
5112                                         ArrayType subarrayType = arrayType;
5113                                         int index = extraDimension;
5114                                         while (index > 0) {
5115                                                 subarrayType = (ArrayType) subarrayType.getComponentType();
5116                                                 index--;
5117                                         }
5118                                         int end = retrieveProperRightBracketPosition(remainingDimensions, start);
5119                                         subarrayType.setSourceRange(start, end - start + 1);
5120                                         // cut the child loose from its parent (without creating garbage)
5121                                         subarrayType.setParent(null, null);
5122                                         updateInnerPositions(subarrayType, remainingDimensions);
5123                                         singleVariableDeclaration.setType(subarrayType);
5124                                         this.ast.getBindingResolver().updateKey(type, subarrayType);
5125                                 }
5126                         } else {
5127                                 singleVariableDeclaration.setType(type);
5128                         }
5129                 } else {
5130                         singleVariableDeclaration.setType(type);
5131                 }
5132         }
5133
5134         protected void setTypeForVariableDeclarationExpression(VariableDeclarationExpression variableDeclarationExpression, Type type, int extraDimension) {
5135                 if (extraDimension != 0) {
5136                         if (type.isArrayType()) {
5137                                 ArrayType arrayType = (ArrayType) type;
5138                                 int remainingDimensions = arrayType.getDimensions() - extraDimension;
5139                                 if (remainingDimensions == 0)  {
5140                                         // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
5141                                         Type elementType = arrayType.getElementType();
5142                                         // cut the child loose from its parent (without creating garbage)
5143                                         elementType.setParent(null, null);
5144                                         this.ast.getBindingResolver().updateKey(type, elementType);
5145                                         variableDeclarationExpression.setType(elementType);
5146                                 } else {
5147                                         int start = type.getStartPosition();
5148                                         ArrayType subarrayType = arrayType;
5149                                         int index = extraDimension;
5150                                         while (index > 0) {
5151                                                 subarrayType = (ArrayType) subarrayType.getComponentType();
5152                                                 index--;
5153                                         }
5154                                         int end = retrieveProperRightBracketPosition(remainingDimensions, start);
5155                                         subarrayType.setSourceRange(start, end - start + 1);
5156                                         // cut the child loose from its parent (without creating garbage)
5157                                         subarrayType.setParent(null, null);
5158                                         updateInnerPositions(subarrayType, remainingDimensions);
5159                                         variableDeclarationExpression.setType(subarrayType);
5160                                         this.ast.getBindingResolver().updateKey(type, subarrayType);
5161                                 }
5162                         } else {
5163                                 variableDeclarationExpression.setType(type);
5164                         }
5165                 } else {
5166                         variableDeclarationExpression.setType(type);
5167                 }
5168         }
5169
5170         protected void setTypeForVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, Type type, int extraDimension) {
5171                 if (extraDimension != 0) {
5172                         if (type.isArrayType()) {
5173                                 ArrayType arrayType = (ArrayType) type;
5174                                 int remainingDimensions = arrayType.getDimensions() - extraDimension;
5175                                 if (remainingDimensions == 0)  {
5176                                         // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
5177                                         Type elementType = arrayType.getElementType();
5178                                         // cut the child loose from its parent (without creating garbage)
5179                                         elementType.setParent(null, null);
5180                                         this.ast.getBindingResolver().updateKey(type, elementType);
5181                                         variableDeclarationStatement.setType(elementType);
5182                                 } else {
5183                                         int start = type.getStartPosition();
5184                                         ArrayType subarrayType = arrayType;
5185                                         int index = extraDimension;
5186                                         while (index > 0) {
5187                                                 subarrayType = (ArrayType) subarrayType.getComponentType();
5188                                                 index--;
5189                                         }
5190                                         int end = retrieveProperRightBracketPosition(remainingDimensions, start);
5191                                         subarrayType.setSourceRange(start, end - start + 1);
5192                                         // cut the child loose from its parent (without creating garbage)
5193                                         subarrayType.setParent(null, null);
5194                                         updateInnerPositions(subarrayType, remainingDimensions);
5195                                         variableDeclarationStatement.setType(subarrayType);
5196                                         this.ast.getBindingResolver().updateKey(type, subarrayType);
5197                                 }
5198                         } else {
5199                                 variableDeclarationStatement.setType(type);
5200                         }
5201                 } else {
5202                         variableDeclarationStatement.setType(type);
5203                 }
5204         }
5205
5206         protected void updateInnerPositions(Type type, int dimensions) {
5207                 if (dimensions > 1) {
5208                         // need to set positions for intermediate array type see 42839
5209                         int start = type.getStartPosition();
5210                         Type currentComponentType = ((ArrayType) type).getComponentType();
5211                         int searchedDimension = dimensions - 1;
5212                         int rightBracketEndPosition = start;
5213                         while (currentComponentType.isArrayType()) {
5214                                 rightBracketEndPosition = retrieveProperRightBracketPosition(searchedDimension, start);
5215                                 currentComponentType.setSourceRange(start, rightBracketEndPosition - start + 1);
5216                                 currentComponentType = ((ArrayType) currentComponentType).getComponentType();
5217                                 searchedDimension--;
5218                         }               
5219                 }
5220         }
5221 }