Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/eclipse/jdt/core/dom/ASTConverter.java


1   /*******************************************************************************
2    * Copyright (c) 2000, 2004 IBM Corporation and others.
3    * All rights reserved. This program and the accompanying materials 
4    * are made available under the terms of the Common Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/cpl-v10.html
7    * 
8    * Contributors:
9    *     IBM Corporation - initial API and implementation
10   *******************************************************************************/
11  
12  package org.eclipse.jdt.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 org.eclipse.jdt.core.JavaCore;
23  import org.eclipse.jdt.core.compiler.IProblem;
24  import org.eclipse.jdt.core.compiler.InvalidInputException;
25  import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
26  import org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression;
27  import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
28  import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
29  import org.eclipse.jdt.internal.compiler.ast.MessageSend;
30  import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
31  import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
32  import org.eclipse.jdt.internal.compiler.env.IConstants;
33  import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
34  import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
35  import org.eclipse.jdt.internal.compiler.parser.Scanner;
36  import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
37  
38  /**
39   * Internal class for converting internal compiler ASTs into public ASTs.
40   */
41  class ASTConverter {
42  
43    private AST ast;
44    char[] compilationUnitSource;
45    Scanner scanner;
46    private boolean resolveBindings;
47    private Set pendingThisExpressionScopeResolution;
48    private Set pendingNameScopeResolution;  
49    private IProgressMonitor monitor;
50    // comments
51    private boolean insideComments;
52    private DocCommentParser docParser;
53    private Comment[] commentsTable;
54    private DefaultCommentMapper commentMapper;
55  
56    public ASTConverter(Map options, boolean resolveBindings, IProgressMonitor monitor) {
57      this.resolveBindings = resolveBindings;
58      this.scanner = new Scanner(
59            true /*comment*/,
60            false /*whitespace*/,
61            false /*nls*/,
62            JavaCore.VERSION_1_4.equals(options.get(JavaCore.COMPILER_SOURCE)) ? ClassFileConstants.JDK1_4 : ClassFileConstants.JDK1_3 /*sourceLevel*/, 
63            null /*taskTags*/,
64            null/*taskPriorities*/,
65            true/*taskCaseSensitive*/);
66      this.monitor = monitor;
67      this.insideComments = JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_DOC_COMMENT_SUPPORT));
68    }
69    
70    public void setAST(AST ast) {
71      this.ast = ast;
72      this.docParser = new DocCommentParser(this.ast, this.scanner, this.insideComments);
73    }
74  
75    /*
76     * Internal use only
77     * Used to convert class body declarations
78     */
79    public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes) {
80      TypeDeclaration typeDecl = this.ast.newTypeDeclaration();
81      int nodesLength = nodes.length;
82      for (int i = 0; i < nodesLength; i++) {
83        org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodes[i];
84        if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
85          org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) node;
86          Initializer initializer = this.ast.newInitializer();
87          initializer.setBody(convert(oldInitializer.block));
88          initializer.setModifiers(oldInitializer.modifiers);
89          initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
90  //        setJavaDocComment(initializer);
91  //        initializer.setJavadoc(convert(oldInitializer.javadoc));
92          convert(oldInitializer.javadoc, initializer);
93          typeDecl.bodyDeclarations().add(initializer);
94        } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
95          org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
96          if (i > 0
97            && (nodes[i - 1] instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)
98            && ((org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)nodes[i - 1]).declarationSourceStart == fieldDeclaration.declarationSourceStart) {
99            // we have a multiple field declaration
100           // We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
101           FieldDeclaration currentFieldDeclaration = (FieldDeclaration) typeDecl.bodyDeclarations().get(typeDecl.bodyDeclarations().size() - 1);
102           currentFieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fieldDeclaration));
103         } else {
104           // we can create a new FieldDeclaration
105           typeDecl.bodyDeclarations().add(convertToFieldDeclaration(fieldDeclaration));
106         }
107       } else if(node instanceof org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) {
108         AbstractMethodDeclaration nextMethodDeclaration = (AbstractMethodDeclaration) node;
109         if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
110           typeDecl.bodyDeclarations().add(convert(nextMethodDeclaration));
111         }
112       } else if(node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
113         org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
114         typeDecl.bodyDeclarations().add(convert(nextMemberDeclaration));
115       }
116     }
117     return typeDecl;
118   }
119   
120   public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
121     this.compilationUnitSource = source;
122     this.scanner.setSource(source);
123     this.scanner.lineEnds = unit.compilationResult().lineSeparatorPositions;
124     CompilationUnit compilationUnit = this.ast.newCompilationUnit();
125     // handle the package declaration immediately
126     // There is no node corresponding to the package declaration
127     if (this.resolveBindings) {
128       recordNodes(compilationUnit, unit);
129     }
130     if (unit.currentPackage != null) {
131       PackageDeclaration packageDeclaration = convertPackage(unit);
132       compilationUnit.setPackage(packageDeclaration);
133     }
134     org.eclipse.jdt.internal.compiler.ast.ImportReference[] imports = unit.imports;
135     if (imports != null) {
136       int importLength = imports.length;
137       for (int i = 0; i < importLength; i++) {
138         compilationUnit.imports().add(convertImport(imports[i]));
139       }
140     }
141 
142     // Parse comments
143     int[][] comments = unit.comments;
144     if (comments != null) {
145       buildCommentsTable(compilationUnit, comments);
146     }
147 
148     org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit.types;
149     if (types != null) {
150       int typesLength = types.length;
151       for (int i = 0; i < typesLength; i++) {
152         compilationUnit.types().add(convert(types[i]));
153       }
154     }
155     compilationUnit.setSourceRange(unit.sourceStart, unit.sourceEnd - unit.sourceStart  + 1);
156     
157     int problemLength = unit.compilationResult.problemCount;
158     if (problemLength != 0) {
159       IProblem[] resizedProblems = null;
160       final IProblem[] problems = unit.compilationResult.problems;
161       if (problems.length == problemLength) {
162         resizedProblems = problems;
163       } else {
164         System.arraycopy(problems, 0, (resizedProblems = new IProblem[problemLength]), 0, problemLength);
165       }
166       propagateErrors(compilationUnit, resizedProblems);
167       compilationUnit.setProblems(resizedProblems);
168     }
169     if (this.resolveBindings) {
170       lookupForScopes();
171     }
172     compilationUnit.initCommentMapper(this.scanner);
173     return compilationUnit;
174   }
175   
176   /**
177    * @param compilationUnit
178    * @param comments
179    */
180   void buildCommentsTable(CompilationUnit compilationUnit, int[][] comments) {
181     // Build comment table
182     this.commentsTable = new Comment[comments.length];
183     int nbr = 0;
184     for (int i = 0; i < comments.length; i++) {
185       Comment comment = createComment(comments[i]);
186       if (comment != null) {
187         comment.setAlternateRoot(compilationUnit);
188         this.commentsTable[nbr++] = comment;
189       }
190     }
191     // Resize table if  necessary
192     if (nbr<comments.length) {
193       Comment[] newCommentsTable = new Comment[nbr];
194       System.arraycopy(this.commentsTable, 0, newCommentsTable, 0, nbr);
195       this.commentsTable = newCommentsTable;
196     }
197     compilationUnit.setCommentTable(this.commentsTable);
198   }
199 
200   public PackageDeclaration convertPackage(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration) {
201     org.eclipse.jdt.internal.compiler.ast.ImportReference importReference = compilationUnitDeclaration.currentPackage;
202     PackageDeclaration packageDeclaration = this.ast.newPackageDeclaration();
203     char[][] tokens = importReference.tokens;
204     int length = importReference.tokens.length;
205     long[] positions = importReference.sourcePositions;
206     int start = (int)(positions[0]>>>32);
207     int end = (int)(positions[length - 1] & 0xFFFFFFFF);
208     Name name = null;
209     if (length > 1) {
210       name = setQualifiedNameNameAndSourceRanges(tokens, positions, importReference);
211     } else {
212       name = this.ast.newSimpleName(new String(tokens[0]));
213       name.setSourceRange(start, end - start + 1);
214     }
215     packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
216     packageDeclaration.setName(name);
217     if (this.resolveBindings) {
218       recordNodes(packageDeclaration, importReference);
219       recordNodes(name, compilationUnitDeclaration);
220     }
221     return packageDeclaration;
222   }
223   
224   public ImportDeclaration convertImport(org.eclipse.jdt.internal.compiler.ast.ImportReference importReference) {
225     ImportDeclaration importDeclaration = this.ast.newImportDeclaration();
226     boolean onDemand = importReference.onDemand;
227     char[][] tokens = importReference.tokens;
228     int length = importReference.tokens.length;
229     long[] positions = importReference.sourcePositions;
230     Name name = null;
231     if (length > 1) {
232       name = setQualifiedNameNameAndSourceRanges(tokens, positions, importReference);
233     } else {
234       name = this.ast.newSimpleName(new String(tokens[0]));
235       int start = (int)(positions[0]>>>32);
236       int end = (int)(positions[0] & 0xFFFFFFFF);
237       name.setSourceRange(start, end - start + 1);
238     }
239     importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
240     importDeclaration.setName(name);
241     importDeclaration.setOnDemand(onDemand);
242     if (this.resolveBindings) {
243       recordNodes(importDeclaration, importReference);
244     }
245     return importDeclaration;
246   }
247 
248   public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
249     checkCanceled();
250     TypeDeclaration typeDecl = this.ast.newTypeDeclaration();
251     int modifiers = typeDeclaration.modifiers;
252     modifiers &= ~IConstants.AccInterface; // remove AccInterface flags
253     modifiers &= CompilerModifiers.AccJustFlag;
254     typeDecl.setModifiers(modifiers);
255     typeDecl.setInterface(typeDeclaration.isInterface());
256     SimpleName typeName = this.ast.newSimpleName(new String(typeDeclaration.name));
257     typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
258     typeDecl.setName(typeName);
259     typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
260     
261     // need to set the superclass and super interfaces here since we cannot distinguish them at
262     // the type references level.
263     if (typeDeclaration.superclass != null) {
264       typeDecl.setSuperclass(convert(typeDeclaration.superclass));
265     }
266     
267     org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
268     if (superInterfaces != null) {
269       for (int index = 0, length = superInterfaces.length; index < length; index++) {
270         typeDecl.superInterfaces().add(convert(superInterfaces[index]));
271       }
272     }
273     
274     buildBodyDeclarations(typeDeclaration, typeDecl);
275     // The javadoc comment is now got from list store in compilation unit declaration
276 //    setJavaDocComment(typeDecl);
277     if (this.resolveBindings) {
278       recordNodes(typeDecl, typeDeclaration);
279       recordNodes(typeName, typeDeclaration);
280       typeDecl.resolveBinding();
281     }
282     return typeDecl;
283   }
284   
285   private void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration, TypeDeclaration typeDecl) {
286     // add body declaration in the lexical order
287     org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = typeDeclaration.memberTypes;
288     org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = typeDeclaration.fields;
289     org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = typeDeclaration.methods;
290     
291     int fieldsLength = fields == null? 0 : fields.length;
292     int methodsLength = methods == null? 0 : methods.length;
293     int membersLength = members == null ? 0 : members.length;
294     int fieldsIndex = 0;
295     int methodsIndex = 0;
296     int membersIndex = 0;
297     
298     while ((fieldsIndex < fieldsLength)
299       || (membersIndex < membersLength)
300       || (methodsIndex < methodsLength)) {
301       org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
302       org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
303       org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
304     
305       int position = Integer.MAX_VALUE;
306       int nextDeclarationType = -1;
307       if (fieldsIndex < fieldsLength) {
308         nextFieldDeclaration = fields[fieldsIndex];
309         if (nextFieldDeclaration.declarationSourceStart < position) {
310           position = nextFieldDeclaration.declarationSourceStart;
311           nextDeclarationType = 0; // FIELD
312         }
313       }
314       if (methodsIndex < methodsLength) {
315         nextMethodDeclaration = methods[methodsIndex];
316         if (nextMethodDeclaration.declarationSourceStart < position) {
317           position = nextMethodDeclaration.declarationSourceStart;
318           nextDeclarationType = 1; // METHOD
319         }
320       }
321       if (membersIndex < membersLength) {
322         nextMemberDeclaration = members[membersIndex];
323         if (nextMemberDeclaration.declarationSourceStart < position) {
324           position = nextMemberDeclaration.declarationSourceStart;
325           nextDeclarationType = 2; // MEMBER
326         }
327       }
328       switch (nextDeclarationType) {
329         case 0 :
330           checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, typeDecl.bodyDeclarations());
331           fieldsIndex++;
332           break;
333         case 1 :
334           methodsIndex++;
335           if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
336             typeDecl.bodyDeclarations().add(convert(nextMethodDeclaration));
337           }
338           break;
339         case 2 :
340           membersIndex++;
341           typeDecl.bodyDeclarations().add(convert(nextMemberDeclaration));
342       }
343     }
344     // Convert javadoc
345 //    typeDecl.setJavadoc(convert(typeDeclaration.javadoc));
346     convert(typeDeclaration.javadoc, typeDecl);
347   }
348   
349   private void checkAndAddMultipleFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields, int index, List bodyDeclarations) {
350     if (fields[index] instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
351       org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) fields[index];
352       Initializer initializer = this.ast.newInitializer();
353       initializer.setBody(convert(oldInitializer.block));
354       initializer.setModifiers(oldInitializer.modifiers);
355       initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
356       // The javadoc comment is now got from list store in compilation unit declaration
357 //      setJavaDocComment(initializer);
358 //      initializer.setJavadoc(convert(oldInitializer.javadoc));
359       convert(oldInitializer.javadoc, initializer);
360       bodyDeclarations.add(initializer);
361       return;
362     }
363     if (index > 0 && fields[index - 1].declarationSourceStart == fields[index].declarationSourceStart) {
364       // we have a multiple field declaration
365       // We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
366       FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclarations.get(bodyDeclarations.size() - 1);
367       fieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fields[index]));
368     } else {
369       // we can create a new FieldDeclaration
370       bodyDeclarations.add(convertToFieldDeclaration(fields[index]));
371     }
372   }
373   
374   private void checkAndAddMultipleLocalDeclaration(org.eclipse.jdt.internal.compiler.ast.Statement[] stmts, int index, List blockStatements) {
375     if (index > 0
376         && stmts[index - 1] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
377           org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local1 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index - 1];
378           org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local2 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index];
379          if (local1.declarationSourceStart == local2.declarationSourceStart) {
380           // we have a multiple local declarations
381           // We retrieve the existing VariableDeclarationStatement to add the new VariableDeclarationFragment
382           VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) blockStatements.get(blockStatements.size() - 1);
383           variableDeclarationStatement.fragments().add(convertToVariableDeclarationFragment((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
384          } else {
385           // we can create a new FieldDeclaration
386           blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
387          }
388     } else {
389       // we can create a new FieldDeclaration
390       blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
391     }
392   }
393 
394   private void checkCanceled() {
395     if (this.monitor != null && this.monitor.isCanceled())
396       throw new OperationCanceledException();
397   }
398 
399   public Name convert(org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference) {
400     char[][] typeName = typeReference.getTypeName();
401     int length = typeName.length;
402     Name name = null;
403     if (length > 1) {
404       // QualifiedName
405       org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference;
406       long[] positions = qualifiedTypeReference.sourcePositions;      
407       name = setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
408     } else {
409       name = this.ast.newSimpleName(new String(typeName[0]));
410       name.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);
411     }
412     if (this.resolveBindings) {
413       recordNodes(name, typeReference);
414     }
415     return name;
416   }
417   
418   public SimpleName convert(org.eclipse.jdt.internal.compiler.ast.SingleNameReference nameReference) {
419     SimpleName name = this.ast.newSimpleName(new String(nameReference.token));    
420     if (this.resolveBindings) {
421       recordNodes(name, nameReference);
422     }
423     name.setSourceRange(nameReference.sourceStart, nameReference.sourceEnd - nameReference.sourceStart + 1);
424     return name;
425   }
426 
427   public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference nameReference) {
428     return setQualifiedNameNameAndSourceRanges(nameReference.tokens, nameReference.sourcePositions, nameReference);
429   }
430 
431   private QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
432     int length = typeName.length;
433     SimpleName firstToken = this.ast.newSimpleName(new String(typeName[0]));
434     firstToken.index = length - 1;
435     int start0 = (int)(positions[0]>>>32);
436     int start = start0;
437     int end = (int)(positions[0] & 0xFFFFFFFF);
438     firstToken.setSourceRange(start, end - start + 1);
439     SimpleName secondToken = this.ast.newSimpleName(new String(typeName[1]));
440     secondToken.index = length - 2;
441     start = (int)(positions[1]>>>32);
442     end = (int)(positions[1] & 0xFFFFFFFF);
443     secondToken.setSourceRange(start, end - start + 1);
444     QualifiedName qualifiedName = this.ast.newQualifiedName(firstToken, secondToken);
445     if (this.resolveBindings) {
446       recordNodes(qualifiedName, node);
447       recordPendingNameScopeResolution(qualifiedName);
448       recordNodes(firstToken, node);
449       recordNodes(secondToken, node);
450       recordPendingNameScopeResolution(firstToken);
451       recordPendingNameScopeResolution(secondToken);
452     }
453     qualifiedName.index = length - 2;
454     qualifiedName.setSourceRange(start0, end - start0 + 1);
455     SimpleName newPart = null;
456     for (int i = 2; i < length; i++) {
457       newPart = this.ast.newSimpleName(new String(typeName[i]));
458       newPart.index = length - i - 1;
459       start = (int)(positions[i]>>>32);
460       end = (int)(positions[i] & 0xFFFFFFFF);
461       newPart.setSourceRange(start,  end - start + 1);
462       qualifiedName = this.ast.newQualifiedName(qualifiedName, newPart);
463       qualifiedName.index = newPart.index;
464       qualifiedName.setSourceRange(start0, end - start0 + 1);
465       if (this.resolveBindings) {
466         recordNodes(qualifiedName, node);
467         recordNodes(newPart, node);        
468         recordPendingNameScopeResolution(qualifiedName);
469         recordPendingNameScopeResolution(newPart);
470       }
471     }
472     QualifiedName name = qualifiedName;
473     if (this.resolveBindings) {
474       recordNodes(name, node);
475       recordPendingNameScopeResolution(name);
476     }
477     return name;
478   }
479   
480   public Expression convert(org.eclipse.jdt.internal.compiler.ast.ThisReference reference) {
481     if (reference.isImplicitThis()) {
482       // There is no source associated with an implicit this
483       return null;
484     } else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
485       return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference);
486     } else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) {
487       return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) reference);
488     }  else {
489       ThisExpression thisExpression = this.ast.newThisExpression();
490       thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
491       if (this.resolveBindings) {
492         recordNodes(thisExpression, reference);
493         recordPendingThisExpressionScopeResolution(thisExpression);
494       }
495       return thisExpression;
496     }
497   }
498 
499   public ThisExpression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference reference) {
500     ThisExpression thisExpression = this.ast.newThisExpression();
501     thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
502     thisExpression.setQualifier(convert(reference.qualification));
503     if (this.resolveBindings) {
504       recordNodes(thisExpression, reference);
505       recordPendingThisExpressionScopeResolution(thisExpression);
506     }
507     return thisExpression;
508   }
509 
510   public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference reference) {
511     return convert(reference.qualification);
512   }
513 
514   public ArrayAccess convert(org.eclipse.jdt.internal.compiler.ast.ArrayReference reference) {
515     ArrayAccess arrayAccess = this.ast.newArrayAccess();
516     if (this.resolveBindings) {
517       recordNodes(arrayAccess, reference);
518     }
519     arrayAccess.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
520     arrayAccess.setArray(convert(reference.receiver));
521     arrayAccess.setIndex(convert(reference.position));
522     return arrayAccess;
523   }
524   
525   public Expression convert(org.eclipse.jdt.internal.compiler.ast.FieldReference reference) {
526     if (reference.receiver.isSuper()) {
527       SuperFieldAccess superFieldAccess = this.ast.newSuperFieldAccess();
528       if (this.resolveBindings) {
529         recordNodes(superFieldAccess, reference);
530       }
531       if (reference.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
532         Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference.receiver);
533         superFieldAccess.setQualifier(qualifier);
534         if (this.resolveBindings) {
535           recordNodes(qualifier, reference.receiver);
536         }
537       }
538       SimpleName simpleName = this.ast.newSimpleName(new String(reference.token)); 
539       int sourceStart = (int)(reference.nameSourcePosition>>>32);
540       int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
541       simpleName.setSourceRange(sourceStart, length);
542       superFieldAccess.setName(simpleName);
543       if (this.resolveBindings) {
544         recordNodes(simpleName, reference);
545       }
546       superFieldAccess.setSourceRange(reference.receiver.sourceStart, reference.sourceEnd - reference.receiver.sourceStart + 1);
547       return superFieldAccess;
548     } else {
549       FieldAccess fieldAccess = this.ast.newFieldAccess();
550       if (this.resolveBindings) {
551         recordNodes(fieldAccess, reference);
552       }
553       Expression receiver = convert(reference.receiver);
554       fieldAccess.setExpression(receiver);
555       SimpleName simpleName = this.ast.newSimpleName(new String(reference.token)); 
556       int sourceStart = (int)(reference.nameSourcePosition>>>32);
557       int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
558       simpleName.setSourceRange(sourceStart, length);
559       fieldAccess.setName(simpleName);
560       if (this.resolveBindings) {
561         recordNodes(simpleName, reference);
562       }
563       fieldAccess.setSourceRange(receiver.getStartPosition(), reference.sourceEnd - receiver.getStartPosition() + 1);
564       return fieldAccess;
565     }
566   }
567   
568   public Expression convert(org.eclipse.jdt.internal.compiler.ast.Reference reference) {
569     if (reference instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
570       return convert((org.eclipse.jdt.internal.compiler.ast.NameReference) reference);
571     }
572     if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ThisReference) {
573       return convert((org.eclipse.jdt.internal.compiler.ast.ThisReference) reference);
574     }
575     if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ArrayReference) {
576       return convert((org.eclipse.jdt.internal.compiler.ast.ArrayReference) reference);
577     }
578     if (reference instanceof org.eclipse.jdt.internal.compiler.ast.FieldReference) {
579       return convert((org.eclipse.jdt.internal.compiler.ast.FieldReference) reference);
580     }
581     throw new IllegalArgumentException("Not yet implemented: convert(" + reference.getClass() + ")");//$NON-NLS-1$//$NON-NLS-2$
582   }
583             
584   public Name convert(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
585     if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) {
586       return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) reference);
587     }
588     if (reference instanceof org.eclipse.jdt.internal.compiler.ast.SingleNameReference) {
589       return convert((org.eclipse.jdt.internal.compiler.ast.SingleNameReference) reference);
590     }
591     throw new IllegalArgumentException("Not yet implemented: convert(" + reference.getClass() + ")");//$NON-NLS-1$//$NON-NLS-2$
592   }  
593 
594   private void completeRecord(ArrayType arrayType, org.eclipse.jdt.internal.compiler.ast.ASTNode astNode) {
595     ArrayType array = arrayType;
596     int dimensions = array.getDimensions();
597     for (int i = 0; i < dimensions; i++) {
598       Type componentType = array.getComponentType();
599       this.recordNodes(componentType, astNode);
600       if (componentType.isArrayType()) {
601         array = (ArrayType) componentType;
602       }
603     }
604   }
605   
606   public Type convertType(org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference) {
607     Type type = null;        
608     int sourceStart = -1;
609     int length = 0;
610     int dimensions = typeReference.dimensions();
611     if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) {
612       // this is either an ArrayTypeReference or a SingleTypeReference
613       char[] name = ((org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) typeReference).getTypeName()[0];
614       sourceStart = typeReference.sourceStart;
615       length = typeReference.sourceEnd - typeReference.sourceStart + 1;
616       if (dimensions != 0) {
617         // need to find out if this is an array type of primitive types or not
618         if (isPrimitiveType(name)) {
619           int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
620           if (end == -1) {
621             end = sourceStart + length - 1;
622           }          
623           PrimitiveType primitiveType = this.ast.newPrimitiveType(getPrimitiveTypeCode(name));
624           primitiveType.setSourceRange(sourceStart, end - sourceStart + 1);
625           type = this.ast.newArrayType(primitiveType, dimensions);
626           if (this.resolveBindings) {
627             // store keys for inner types
628             completeRecord((ArrayType) type, typeReference);
629           }
630           type.setSourceRange(sourceStart, length);
631         } else {
632           SimpleName simpleName = this.ast.newSimpleName(new String(name));
633           // we need to search for the starting position of the first brace in order to set the proper length
634           // PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759
635           int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
636           if (end == -1) {
637             end = sourceStart + length - 1;
638           }
639           simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
640           SimpleType simpleType = this.ast.newSimpleType(simpleName);
641           simpleType.setSourceRange(sourceStart, end - sourceStart + 1);
642           type = this.ast.newArrayType(simpleType, dimensions);
643           type.setSourceRange(sourceStart, length);
644           if (this.resolveBindings) {
645             completeRecord((ArrayType) type, typeReference);
646             this.recordNodes(simpleName, typeReference);
647           }
648         }
649       } else {
650         if (isPrimitiveType(name)) {
651           type = this.ast.newPrimitiveType(getPrimitiveTypeCode(name));
652           type.setSourceRange(sourceStart, length);
653         } else {
654           SimpleName simpleName = this.ast.newSimpleName(new String(name));
655           simpleName.setSourceRange(sourceStart, length);
656           type = this.ast.newSimpleType(simpleName);
657           type.setSourceRange(sourceStart, length);
658           if (this.resolveBindings) {
659             this.recordNodes(simpleName, typeReference);
660           }
661         }
662       }
663     } else {
664       char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
665       int nameLength = name.length;
666       long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
667       sourceStart = (int)(positions[0]>>>32);
668       length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
669       Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
670       if (dimensions != 0) {
671         // need to find out if this is an array type of primitive types or not
672         SimpleType simpleType = this.ast.newSimpleType(qualifiedName);
673         simpleType.setSourceRange(sourceStart, length);
674         type = this.ast.newArrayType(simpleType, dimensions);
675         if (this.resolveBindings) {
676           completeRecord((ArrayType) type, typeReference);
677         }        
678         int end = retrieveEndOfDimensionsPosition(sourceStart+length, this.compilationUnitSource.length);
679         if (end != -1) {
680           type.setSourceRange(sourceStart, end - sourceStart + 1);
681         } else {
682           type.setSourceRange(sourceStart, length);
683         }
684       } else {
685         type = this.ast.newSimpleType(qualifiedName);
686         type.setSourceRange(sourceStart, length);
687       }
688     }
689     if (this.resolveBindings) {
690       this.recordNodes(type, typeReference);
691     }
692     return type;
693   }
694     
695   public MethodDeclaration convert(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) {
696     checkCanceled();
697     MethodDeclaration methodDecl = this.ast.newMethodDeclaration();
698     methodDecl.setModifiers(methodDeclaration.modifiers & org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers.AccJustFlag);
699     boolean isConstructor = methodDeclaration.isConstructor();
700     methodDecl.setConstructor(isConstructor);
701     SimpleName methodName = this.ast.newSimpleName(new String(methodDeclaration.selector));
702     int start = methodDeclaration.sourceStart;
703     int end = retrieveIdentifierEndPosition(start, methodDeclaration.sourceEnd);
704     methodName.setSourceRange(start, end - start + 1);
705     methodDecl.setName(methodName);
706     org.eclipse.jdt.internal.compiler.ast.TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
707     if (thrownExceptions != null) {
708       int thrownExceptionsLength = thrownExceptions.length;
709       for (int i = 0; i < thrownExceptionsLength; i++) {
710         methodDecl.thrownExceptions().add(convert(thrownExceptions[i]));
711       }
712     }
713     org.eclipse.jdt.internal.compiler.ast.Argument[] parameters = methodDeclaration.arguments;
714     if (parameters != null) {
715       int parametersLength = parameters.length;
716       for (int i = 0; i < parametersLength; i++) {
717         methodDecl.parameters().add(convert(parameters[i]));
718       }
719     }
720     org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall explicitConstructorCall = null;
721     if (isConstructor) {
722       // set the return type to VOID
723       PrimitiveType returnType = this.ast.newPrimitiveType(PrimitiveType.VOID);
724       returnType.setSourceRange(methodDeclaration.sourceStart, 0);
725       methodDecl.setReturnType(returnType);
726       org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration constructorDeclaration = (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) methodDeclaration;
727       explicitConstructorCall = constructorDeclaration.constructorCall;
728     } else {
729       org.eclipse.jdt.internal.compiler.ast.MethodDeclaration method = (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) methodDeclaration;
730       org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = method.returnType;
731       if (typeReference != null) {
732         Type returnType = convertType(typeReference);
733         // get the positions of the right parenthesis
734         int rightParenthesisPosition = retrieveEndOfRightParenthesisPosition(end, method.bodyEnd);
735         int extraDimensions = retrieveExtraDimension(rightParenthesisPosition, method.bodyEnd);
736         methodDecl.setExtraDimensions(extraDimensions);
737         setTypeForMethodDeclaration(methodDecl, returnType, extraDimensions);
738       }
739     }
740     int declarationSourceStart = methodDeclaration.declarationSourceStart;
741     int declarationSourceEnd = methodDeclaration.bodyEnd;
742     methodDecl.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
743     int closingPosition = retrieveRightBraceOrSemiColonPosition(methodDecl, methodDeclaration);
744     if (closingPosition != -1) {
745       int startPosition = methodDecl.getStartPosition();
746       methodDecl.setSourceRange(startPosition, closingPosition - startPosition);
747 
748       org.eclipse.jdt.internal.compiler.ast.Statement[] statements = methodDeclaration.statements;
749       
750       start = retrieveStartBlockPosition(methodDeclaration.sourceStart, declarationSourceEnd);
751       end = retrieveEndBlockPosition(methodDeclaration.sourceStart, methodDeclaration.declarationSourceEnd);
752       Block block = null;
753       if (start != -1 && end != -1) {
754         /*
755          * start or end can be equal to -1 if we have an interface's method.
756          */
757         block = this.ast.newBlock();
758         block.setSourceRange(start, end - start + 1);
759         methodDecl.setBody(block);
760       }
761       if (block != null && (statements != null || explicitConstructorCall != null)) {
762         if (explicitConstructorCall != null && explicitConstructorCall.accessMode != org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall.ImplicitSuper) {
763           block.statements().add(convert(explicitConstructorCall));
764         }
765         int statementsLength = statements == null ? 0 : statements.length;
766         for (int i = 0; i < statementsLength; i++) {
767           if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
768             checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
769           } else {
770             block.statements().add(convert(statements[i]));
771           }
772         }
773       }
774       if (block != null && (Modifier.isAbstract(methodDecl.getModifiers()) || Modifier.isNative(methodDecl.getModifiers()))) {
775         methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
776       }
777     } else {
778       // syntax error in this method declaration
779       if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract()) {
780         start = retrieveStartBlockPosition(methodDeclaration.sourceStart, declarationSourceEnd);
781         end = methodDeclaration.bodyEnd;
782         // try to get the best end position
783         IProblem[] problems = methodDeclaration.compilationResult().problems;
784         if (problems != null) {
785           for (int i = 0, max = methodDeclaration.compilationResult().problemCount; i < max; i++) {
786             IProblem currentProblem = problems[i];
787             if (currentProblem.getSourceStart() == start && currentProblem.getID() == IProblem.ParsingErrorInsertToComplete) {
788               end = currentProblem.getSourceEnd();
789               break;
790             }
791           }
792         }
793         int startPosition = methodDecl.getStartPosition();
794         methodDecl.setSourceRange(startPosition, end - startPosition + 1);
795         if (start != -1 && end != -1) {
796           /*
797            * start or end can be equal to -1 if we have an interface's method.
798            */
799           Block block = this.ast.newBlock();
800           block.setSourceRange(start, end - start + 1);
801           methodDecl.setBody(block);
802         }
803       }      
804     }
805     
806     // The javadoc comment is now got from list store in compilation unit declaration
807 //    setJavaDocComment(methodDecl);
808 //    methodDecl.setJavadoc(convert(methodDeclaration.javadoc));
809     convert(methodDeclaration.javadoc, methodDecl);
810     if (this.resolveBindings) {
811       recordNodes(methodDecl, methodDeclaration);
812       recordNodes(methodName, methodDeclaration);
813       methodDecl.resolveBinding();
814     }
815     return methodDecl;
816   }  
817 
818   public Expression convert(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
819     if ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
820       return convertToParenthesizedExpression(expression);
821     }
822     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CastExpression) {
823       return convert((org.eclipse.jdt.internal.compiler.ast.CastExpression) expression);
824     }
825     // switch between all types of expression
826     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) {
827       return convert((org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) expression);
828     }
829     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) {
830       return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) expression);
831     }
832     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AllocationExpression) {
833       return convert((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) expression);
834     }
835     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) {
836       return convert((org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) expression);
837     }
838     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PrefixExpression) {
839       return convert((org.eclipse.jdt.internal.compiler.ast.PrefixExpression) expression);
840     }
841     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PostfixExpression) {
842       return convert((org.eclipse.jdt.internal.compiler.ast.PostfixExpression) expression);
843     }
844     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) {
845       return convert((org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) expression);
846     }
847     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Assignment) {
848       return convert((org.eclipse.jdt.internal.compiler.ast.Assignment) expression);
849     }
850     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) {
851       return convert((org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) expression);
852     }
853     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FalseLiteral) {
854       return convert((org.eclipse.jdt.internal.compiler.ast.FalseLiteral) expression);
855     }
856     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TrueLiteral) {
857       return convert((org.eclipse.jdt.internal.compiler.ast.TrueLiteral) expression);
858     }
859     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.NullLiteral) {
860       return convert((org.eclipse.jdt.internal.compiler.ast.NullLiteral) expression);
861     }
862     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CharLiteral) {
863       return convert((org.eclipse.jdt.internal.compiler.ast.CharLiteral) expression);
864     }
865     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) {
866       return convert((org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) expression);
867     }
868     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FloatLiteral) {
869       return convert((org.eclipse.jdt.internal.compiler.ast.FloatLiteral) expression);
870     }
871     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) {
872       return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) expression);
873     }
874     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteral) {
875       return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteral) expression);
876     }
877     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) {
878       return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) expression);
879     }        
880     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteral) {
881       return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteral) expression);
882     }
883     if (expression instanceof StringLiteralConcatenation) {
884       return convert((StringLiteralConcatenation) expression);
885     }
886     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) {
887       return convert((org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) expression);
888     }  
889     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.StringLiteral) {
890       return convert((org.eclipse.jdt.internal.compiler.ast.StringLiteral) expression);
891     }        
892     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) {
893       return convert((org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) expression);
894     }        
895     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) {
896       return convert((org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) expression);
897     }        
898     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.EqualExpression) {
899       return convert((org.eclipse.jdt.internal.compiler.ast.EqualExpression) expression);
900     }        
901     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression) {
902       return convert((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) expression);
903     }        
904     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) {
905       return convert((org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) expression);
906     }        
907     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.UnaryExpression) {
908       return convert((org.eclipse.jdt.internal.compiler.ast.UnaryExpression) expression);
909     }        
910     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) {
911       return convert((org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) expression);
912     }        
913     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.MessageSend) {
914       return convert((org.eclipse.jdt.internal.compiler.ast.MessageSend) expression);
915     }        
916     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Reference) {
917       return convert((org.eclipse.jdt.internal.compiler.ast.Reference) expression);
918     }
919     if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
920       return convert((org.eclipse.jdt.internal.compiler.ast.TypeReference) expression);
921     }        
922     throw new IllegalArgumentException("Not yet implemented: convert(" + expression.getClass() + ")");//$NON-NLS-1$//$NON-NLS-2$
923   }
924 
925   public ParenthesizedExpression convertToParenthesizedExpression(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
926     ParenthesizedExpression parenthesizedExpression = this.ast.newParenthesizedExpression();
927     if (this.resolveBindings) {
928       recordNodes(parenthesizedExpression, expression);
929     }
930     parenthesizedExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
931     adjustSourcePositionsForParent(expression);
932     trimWhiteSpacesAndComments(expression);
933     // decrement the number of parenthesis
934     int numberOfParenthesis = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
935     expression.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK;
936     expression.bits |= (numberOfParenthesis - 1) << org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
937     parenthesizedExpression.setExpression(convert(expression));
938     return parenthesizedExpression;
939   }
940   
941   public ClassInstanceCreation convert(org.eclipse.jdt.internal.compiler.ast.AllocationExpression expression) {
942     ClassInstanceCreation classInstanceCreation = this.ast.newClassInstanceCreation();
943     if (this.resolveBindings) {
944       recordNodes(classInstanceCreation, expression);
945     }
946     classInstanceCreation.setName(convert(expression.type));
947     classInstanceCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
948     org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
949     if (arguments != null) {
950       int length = arguments.length;
951       for (int i = 0; i < length; i++) {
952         classInstanceCreation.arguments().add(convert(arguments[i]));
953       }
954     }
955     removeTrailingCommentFromExpressionEndingWithAParen(classInstanceCreation);
956     return classInstanceCreation;
957   }
958   
959   private void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration expression, AnonymousClassDeclaration anonymousClassDeclaration) {
960     // add body declaration in the lexical order
961     org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = expression.memberTypes;
962     org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = expression.fields;
963     org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = expression.methods;
964     
965     int fieldsLength = fields == null? 0 : fields.length;
966     int methodsLength = methods == null? 0 : methods.length;
967     int membersLength = members == null ? 0 : members.length;
968     int fieldsIndex = 0;
969     int methodsIndex = 0;
970     int membersIndex = 0;
971     
972     while ((fieldsIndex < fieldsLength)
973       || (membersIndex < membersLength)
974       || (methodsIndex < methodsLength)) {
975       org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
976       org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
977       org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
978     
979       int position = Integer.MAX_VALUE;
980       int nextDeclarationType = -1;
981       if (fieldsIndex < fieldsLength) {
982         nextFieldDeclaration = fields[fieldsIndex];
983         if (nextFieldDeclaration.declarationSourceStart < position) {
984           position = nextFieldDeclaration.declarationSourceStart;
985           nextDeclarationType = 0; // FIELD
986         }
987       }
988       if (methodsIndex < methodsLength) {
989         nextMethodDeclaration = methods[methodsIndex];
990         if (nextMethodDeclaration.declarationSourceStart < position) {
991           position = nextMethodDeclaration.declarationSourceStart;
992           nextDeclarationType = 1; // METHOD
993         }
994       }
995       if (membersIndex < membersLength) {
996         nextMemberDeclaration = members[membersIndex];
997         if (nextMemberDeclaration.declarationSourceStart < position) {
998           position = nextMemberDeclaration.declarationSourceStart;
999           nextDeclarationType = 2; // MEMBER
1000        }
1001      }
1002      switch (nextDeclarationType) {
1003        case 0 :
1004          checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, anonymousClassDeclaration.bodyDeclarations());
1005          fieldsIndex++;
1006          break;
1007        case 1 :
1008          methodsIndex++;
1009          if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
1010            anonymousClassDeclaration.bodyDeclarations().add(convert(nextMethodDeclaration));
1011          }
1012          break;
1013        case 2 :
1014          membersIndex++;
1015          anonymousClassDeclaration.bodyDeclarations().add(convert(nextMemberDeclaration));
1016      }
1017    }
1018  }
1019
1020  public ArrayCreation convert(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression expression) {
1021    ArrayCreation arrayCreation = this.ast.newArrayCreation();
1022    if (this.resolveBindings) {
1023      recordNodes(arrayCreation, expression);
1024    }
1025    arrayCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1026    org.eclipse.jdt.internal.compiler.ast.Expression[] dimensions = expression.dimensions;
1027    
1028    int dimensionsLength = dimensions.length;
1029    for (int i = 0; i < dimensionsLength; i++) {
1030      if (dimensions[i] != null) {
1031        Expression dimension = convert(dimensions[i]);
1032        if (this.resolveBindings) {
1033          recordNodes(dimension, dimensions[i]);
1034        }
1035        arrayCreation.dimensions().add(dimension);
1036      }
1037    }
1038    Type type = convertType(expression.type);
1039    if (this.resolveBindings) {
1040      recordNodes(type, expression.type);
1041    }    
1042    ArrayType arrayType = null;
1043    if (type.isArrayType()) {
1044      arrayType = (ArrayType) type;
1045    } else {
1046      arrayType = this.ast.newArrayType(type, dimensionsLength);
1047      if (this.resolveBindings) {
1048        completeRecord(arrayType, expression);
1049      }      
1050      int start = type.getStartPosition();
1051      int end = type.getStartPosition() + type.getLength();
1052      int previousSearchStart = end;
1053      ArrayType componentType = (ArrayType) type.getParent();
1054      for (int i = 0; i < dimensionsLength; i++) {
1055        previousSearchStart = retrieveRightBracketPosition(previousSearchStart + 1, this.compilationUnitSource.length);
1056        componentType.setSourceRange(start, previousSearchStart - start + 1);
1057        componentType = (ArrayType) componentType.getParent();
1058      }
1059    }
1060    arrayCreation.setType(arrayType);
1061    if (this.resolveBindings) {
1062      recordNodes(arrayType, expression);
1063    }  
1064    if (expression.initializer != null) {
1065      arrayCreation.setInitializer(convert(expression.initializer));
1066    }
1067    return arrayCreation;
1068  }
1069
1070  public SingleVariableDeclaration convert(org.eclipse.jdt.internal.compiler.ast.Argument argument) {
1071    SingleVariableDeclaration variableDecl = this.ast.newSingleVariableDeclaration();
1072    variableDecl.setModifiers(argument.modifiers);
1073    SimpleName name = this.ast.newSimpleName(new String(argument.name));
1074    int start = argument.sourceStart;
1075    int nameEnd = argument.sourceEnd;
1076    name.setSourceRange(start, nameEnd - start + 1);
1077    variableDecl.setName(name);
1078    final int extraDimensions = retrieveExtraDimension(nameEnd + 1, argument.type.sourceEnd);
1079    variableDecl.setExtraDimensions(extraDimensions);
1080    Type type = convertType(argument.type);
1081    int typeEnd = type.getStartPosition() + type.getLength() - 1;
1082    int rightEnd = Math.max(typeEnd, argument.declarationSourceEnd);
1083    /*
1084     * There is extra work to do to set the proper type positions
1085     * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
1086     */
1087    setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
1088    variableDecl.setSourceRange(argument.declarationSourceStart, rightEnd - argument.declarationSourceStart + 1);
1089    if (this.resolveBindings) {
1090      recordNodes(name, argument);
1091      recordNodes(variableDecl, argument);
1092      variableDecl.resolveBinding();
1093    }
1094    return variableDecl;
1095  }
1096
1097  public ArrayInitializer convert(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer expression) {
1098    ArrayInitializer arrayInitializer = this.ast.newArrayInitializer();
1099    if (this.resolveBindings) {
1100      recordNodes(arrayInitializer, expression);
1101    }
1102    arrayInitializer.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1103    org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = expression.expressions;
1104    if (expressions != null) {
1105      int length = expressions.length;
1106      for (int i = 0; i < length; i++) {
1107        Expression expr = convert(expressions[i]);
1108        if (this.resolveBindings) {
1109          recordNodes(expr, expressions[i]);
1110        }
1111        arrayInitializer.expressions().add(expr);
1112      }
1113    }
1114    return arrayInitializer;
1115  }
1116
1117  public Expression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression allocation) {
1118    if (allocation.anonymousType != null) {
1119      ClassInstanceCreation classInstanceCreation = this.ast.newClassInstanceCreation();
1120      classInstanceCreation.setName(convert(allocation.type));
1121      if (allocation.enclosingInstance != null) {
1122        classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
1123      }
1124      int declarationSourceStart = allocation.sourceStart;
1125      classInstanceCreation.setSourceRange(declarationSourceStart, allocation.anonymousType.bodyEnd - declarationSourceStart + 1);
1126      org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = allocation.arguments;
1127      if (arguments != null) {
1128        int length = arguments.length;
1129        for (int i = 0; i < length; i++) {
1130          classInstanceCreation.arguments().add(convert(arguments[i]));
1131        }
1132      }
1133      AnonymousClassDeclaration anonymousClassDeclaration = this.ast.newAnonymousClassDeclaration();
1134      int start = retrieveStartBlockPosition(allocation.anonymousType.sourceEnd, allocation.anonymousType.bodyEnd);
1135      anonymousClassDeclaration.setSourceRange(start, allocation.anonymousType.bodyEnd - start + 1);
1136      classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
1137      buildBodyDeclarations(allocation.anonymousType, anonymousClassDeclaration);
1138      if (this.resolveBindings) {
1139        recordNodes(classInstanceCreation, allocation.anonymousType);
1140        recordNodes(anonymousClassDeclaration, allocation.anonymousType);
1141        anonymousClassDeclaration.resolveBinding();
1142      }
1143      return classInstanceCreation;      
1144    } else {
1145      ClassInstanceCreation classInstanceCreation = this.ast.newClassInstanceCreation();
1146      classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
1147      classInstanceCreation.setName(convert(allocation.type));
1148      classInstanceCreation.setSourceRange(allocation.sourceStart, allocation.sourceEnd - allocation.sourceStart + 1);
1149      org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = allocation.arguments;
1150      if (arguments != null) {
1151        int length = arguments.length;
1152        for (int i = 0; i < length; i++) {
1153          Expression argument = convert(arguments[i]);
1154          if (this.resolveBindings) {
1155            recordNodes(argument, arguments[i]);
1156          }
1157          classInstanceCreation.arguments().add(argument);
1158        }
1159      }
1160      if (this.resolveBindings) {
1161        recordNodes(classInstanceCreation, allocation);
1162      }
1163      removeTrailingCommentFromExpressionEndingWithAParen(classInstanceCreation);
1164      return classInstanceCreation;
1165    }
1166  }
1167  
1168  public Assignment convert(org.eclipse.jdt.internal.compiler.ast.Assignment expression) {
1169    Assignment assignment = this.ast.newAssignment();
1170    if (this.resolveBindings) {
1171      recordNodes(assignment, expression);
1172    }
1173    Expression lhs = convert(expression.lhs);
1174    assignment.setLeftHandSide(lhs);
1175    assignment.setOperator(Assignment.Operator.ASSIGN);
1176    assignment.setRightHandSide(convert(expression.expression));
1177    int start = lhs.getStartPosition();
1178    assignment.setSourceRange(start, expression.sourceEnd - start + 1);
1179    return assignment;
1180  }
1181
1182  public Assignment convert(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment expression) {
1183    Assignment assignment = this.ast.newAssignment();
1184    Expression lhs = convert(expression.lhs);
1185    assignment.setLeftHandSide(lhs);
1186    int start = lhs.getStartPosition();
1187    assignment.setSourceRange(start, expression.sourceEnd - start + 1);
1188    switch (expression.operator) {
1189      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1190        assignment.setOperator(Assignment.Operator.PLUS_ASSIGN);
1191        break;
1192      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1193        assignment.setOperator(Assignment.Operator.MINUS_ASSIGN);
1194        break;
1195      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
1196        assignment.setOperator(Assignment.Operator.TIMES_ASSIGN);
1197        break;
1198      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
1199        assignment.setOperator(Assignment.Operator.DIVIDE_ASSIGN);
1200        break;
1201      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
1202        assignment.setOperator(Assignment.Operator.BIT_AND_ASSIGN);
1203        break;
1204      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
1205        assignment.setOperator(Assignment.Operator.BIT_OR_ASSIGN);
1206        break;
1207      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
1208        assignment.setOperator(Assignment.Operator.BIT_XOR_ASSIGN);
1209        break;
1210      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
1211        assignment.setOperator(Assignment.Operator.REMAINDER_ASSIGN);
1212        break;
1213      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
1214        assignment.setOperator(Assignment.Operator.LEFT_SHIFT_ASSIGN);
1215        break;
1216      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
1217        assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN);
1218        break;
1219      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
1220        assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN);
1221        break;
1222    }
1223    assignment.setRightHandSide(convert(expression.expression));
1224    return assignment;
1225  }
1226
1227  public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.PrefixExpression expression) {
1228    PrefixExpression prefixExpression = this.ast.newPrefixExpression();
1229    if (this.resolveBindings) {
1230      recordNodes(prefixExpression, expression);
1231    }
1232    prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1233    prefixExpression.setOperand(convert(expression.lhs));
1234    switch (expression.operator) {
1235      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1236        prefixExpression.setOperator(PrefixExpression.Operator.INCREMENT);
1237        break;
1238      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1239        prefixExpression.setOperator(PrefixExpression.Operator.DECREMENT);
1240        break;
1241    }
1242    return prefixExpression;
1243  }
1244
1245  public PostfixExpression convert(org.eclipse.jdt.internal.compiler.ast.PostfixExpression expression) {
1246    PostfixExpression postfixExpression = this.ast.newPostfixExpression();
1247    if (this.resolveBindings) {
1248      recordNodes(postfixExpression, expression);
1249    }
1250    postfixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1251    postfixExpression.setOperand(convert(expression.lhs));
1252    switch (expression.operator) {
1253      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1254        postfixExpression.setOperator(PostfixExpression.Operator.INCREMENT);
1255        break;
1256      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1257        postfixExpression.setOperator(PostfixExpression.Operator.DECREMENT);
1258        break;
1259    }
1260    return postfixExpression;
1261  }
1262
1263  public CastExpression convert(org.eclipse.jdt.internal.compiler.ast.CastExpression expression) {
1264    CastExpression castExpression = this.ast.newCastExpression();
1265    castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1266    org.eclipse.jdt.internal.compiler.ast.Expression type = expression.type;
1267    trimWhiteSpacesAndComments(type);
1268    if (type instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference ) {
1269      castExpression.setType(convertType((org.eclipse.jdt.internal.compiler.ast.TypeReference)type));
1270    } else if (type instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
1271      castExpression.setType(convertToType((org.eclipse.jdt.internal.compiler.ast.NameReference)type));
1272    }
1273    castExpression.setExpression(convert(expression.expression));
1274    if (this.resolveBindings) {
1275      recordNodes(castExpression, expression);
1276    }
1277    return castExpression;
1278  }
1279    
1280  public Type convertToType(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
1281    Name name = convert(reference);
1282    SimpleType type = this.ast.newSimpleType(name);
1283    type.setSourceRange(name.getStartPosition(), name.getLength());
1284    if (this.resolveBindings) {
1285      this.recordNodes(type, reference);
1286    }
1287    return type;
1288  }
1289  public Expression convert(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess expression) {
1290    TypeLiteral typeLiteral = this.ast.newTypeLiteral();
1291    if (this.resolveBindings) {
1292      this.recordNodes(typeLiteral, expression);
1293    }
1294    typeLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1295    typeLiteral.setType(convertType(expression.type));
1296    return typeLiteral;
1297  }
1298
1299  public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.FalseLiteral expression) {
1300    BooleanLiteral literal = this.ast.newBooleanLiteral(false);
1301    if (this.resolveBindings) {
1302      this.recordNodes(literal, expression);
1303    }
1304    literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1305    return literal;  
1306  }
1307    
1308  public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.TrueLiteral expression) {
1309    BooleanLiteral literal = this.ast.newBooleanLiteral(true);
1310    if (this.resolveBindings) {
1311      this.recordNodes(literal, expression);
1312    }
1313    literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1314    return literal;    
1315  }
1316
1317  public InfixExpression convert(StringLiteralConcatenation expression) {
1318    expression.computeConstant();
1319    InfixExpression infixExpression = this.ast.newInfixExpression();
1320    infixExpression.setOperator(InfixExpression.Operator.PLUS);
1321    org.eclipse.jdt.internal.compiler.ast.StringLiteral[] stringLiterals = expression.literals;
1322    infixExpression.setLeftOperand(convert(stringLiterals[0]));
1323    infixExpression.setRightOperand(convert(stringLiterals[1]));
1324    for (int i = 2; i < expression.counter; i++) {
1325      infixExpression.extendedOperands().add(convert(stringLiterals[i]));
1326    }
1327    if (this.resolveBindings) {
1328      this.recordNodes(infixExpression, expression);
1329    }
1330    infixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1331    return infixExpression;
1332  }
1333
1334  public org.eclipse.jdt.core.dom.NullLiteral convert(org.eclipse.jdt.internal.compiler.ast.NullLiteral expression) {
1335    org.eclipse.jdt.core.dom.NullLiteral literal = this.ast.newNullLiteral();
1336    if (this.resolveBindings) {
1337      this.recordNodes(literal, expression);
1338    }
1339    literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1340    return literal;    
1341  }
1342
1343  public CharacterLiteral convert(org.eclipse.jdt.internal.compiler.ast.CharLiteral expression) {
1344    int length = expression.sourceEnd - expression.sourceStart + 1;  
1345    int sourceStart = expression.sourceStart;
1346    char[] tokens = new char[length];
1347    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1348    CharacterLiteral literal = this.ast.newCharacterLiteral();
1349    if (this.resolveBindings) {
1350      this.recordNodes(literal, expression);
1351    }
1352    literal.setEscapedValue(new String(tokens));
1353    literal.setSourceRange(sourceStart, length);
1354    removeLeadingAndTrailingCommentsFromLiteral(literal);
1355    return literal;
1356  }
1357
1358  public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral expression) {
1359    int length = expression.sourceEnd - expression.sourceStart + 1;  
1360    int sourceStart = expression.sourceStart;
1361    char[] tokens = new char[length];
1362    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1363    NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
1364    if (this.resolveBindings) {
1365      this.recordNodes(literal, expression);
1366    }
1367    literal.setSourceRange(sourceStart, length);
1368    removeLeadingAndTrailingCommentsFromLiteral(literal);
1369    return literal;
1370  }
1371
1372  public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.FloatLiteral expression) {
1373    int length = expression.sourceEnd - expression.sourceStart + 1;  
1374    int sourceStart = expression.sourceStart;
1375    char[] tokens = new char[length];
1376    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1377    NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
1378    if (this.resolveBindings) {
1379      this.recordNodes(literal, expression);
1380    }
1381    literal.setSourceRange(sourceStart, length);
1382    removeLeadingAndTrailingCommentsFromLiteral(literal);
1383    return literal;
1384  }
1385
1386  public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteral expression) {
1387    int length = expression.sourceEnd - expression.sourceStart + 1;  
1388    int sourceStart = expression.sourceStart;
1389    char[] tokens = new char[length];
1390    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1391    NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
1392    if (this.resolveBindings) {
1393      this.recordNodes(literal, expression);
1394    }
1395    literal.setSourceRange(sourceStart, length);
1396    removeLeadingAndTrailingCommentsFromLiteral(literal);
1397    return literal;
1398  }
1399
1400  public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue expression) {
1401    int length = expression.sourceEnd - expression.sourceStart + 1;  
1402    int sourceStart = expression.sourceStart;
1403    char[] tokens = new char[length];
1404    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1405    NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
1406    if (this.resolveBindings) {
1407      this.recordNodes(literal, expression);
1408    }
1409    literal.setSourceRange(sourceStart, length);
1410    removeLeadingAndTrailingCommentsFromLiteral(literal);
1411    return literal;
1412  }
1413
1414  public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteral expression) {
1415    int length = expression.sourceEnd - expression.sourceStart + 1;  
1416    int sourceStart = expression.sourceStart;
1417    char[] tokens = new char[length];
1418    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1419    NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
1420    if (this.resolveBindings) {
1421      this.recordNodes(literal, expression);
1422    }
1423    literal.setSourceRange(sourceStart, length);
1424    removeLeadingAndTrailingCommentsFromLiteral(literal);
1425    return literal;
1426  }
1427
1428  public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue expression) {
1429    int length = expression.sourceEnd - expression.sourceStart + 1;  
1430    int sourceStart = expression.sourceStart;
1431    char[] tokens = new char[length];
1432    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1433    NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
1434    if (this.resolveBindings) {
1435      this.recordNodes(literal, expression);
1436    }
1437    literal.setSourceRange(sourceStart, length);
1438    removeLeadingAndTrailingCommentsFromLiteral(literal);
1439    return literal;
1440  }
1441
1442  public StringLiteral convert(org.eclipse.jdt.internal.compiler.ast.StringLiteral expression) {
1443    int length = expression.sourceEnd - expression.sourceStart + 1;  
1444    int sourceStart = expression.sourceStart;
1445    char[] tokens = new char[length];
1446    System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
1447    StringLiteral literal = this.ast.newStringLiteral();
1448    if (this.resolveBindings) {
1449      this.recordNodes(literal, expression);
1450    }
1451    literal.setEscapedValue(new String(tokens));
1452    literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1453    return literal;
1454  }
1455
1456  public StringLiteral convert(org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral expression) {
1457    expression.computeConstant();
1458    StringLiteral literal = this.ast.newStringLiteral();
1459    if (this.resolveBindings) {
1460      this.recordNodes(literal, expression);
1461    }
1462    literal.setLiteralValue(expression.constant.stringValue());
1463    literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1464    return literal;
1465  }
1466  
1467  public Expression convert(org.eclipse.jdt.internal.compiler.ast.BinaryExpression expression) {
1468    InfixExpression infixExpression = this.ast.newInfixExpression();
1469    if (this.resolveBindings) {
1470      this.recordNodes(infixExpression, expression);
1471    }
1472
1473    int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
1474    switch (expressionOperatorID) {
1475      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
1476        infixExpression.setOperator(InfixExpression.Operator.EQUALS);
1477        break;
1478      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
1479        infixExpression.setOperator(InfixExpression.Operator.LESS_EQUALS);
1480        break;
1481      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
1482        infixExpression.setOperator(InfixExpression.Operator.GREATER_EQUALS);
1483        break;
1484      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
1485        infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
1486        break;
1487      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
1488        infixExpression.setOperator(InfixExpression.Operator.LEFT_SHIFT);
1489        break;
1490      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
1491        infixExpression.setOperator(InfixExpression.Operator.RIGHT_SHIFT_SIGNED);
1492        break;
1493      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
1494        infixExpression.setOperator(InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED);
1495        break;
1496      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR_OR :
1497        infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
1498        break;
1499      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND_AND :
1500        infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
1501        break;
1502      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1503        infixExpression.setOperator(InfixExpression.Operator.PLUS);
1504        break;
1505      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1506        infixExpression.setOperator(InfixExpression.Operator.MINUS);
1507        break;
1508      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
1509        infixExpression.setOperator(InfixExpression.Operator.REMAINDER);
1510        break;
1511      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
1512        infixExpression.setOperator(InfixExpression.Operator.XOR);
1513        break;
1514      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
1515        infixExpression.setOperator(InfixExpression.Operator.AND);
1516        break;
1517      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
1518        infixExpression.setOperator(InfixExpression.Operator.TIMES);
1519        break;
1520      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
1521        infixExpression.setOperator(InfixExpression.Operator.OR);
1522        break;
1523      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
1524        infixExpression.setOperator(InfixExpression.Operator.DIVIDE);
1525        break;
1526      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER :
1527        infixExpression.setOperator(InfixExpression.Operator.GREATER);
1528        break;
1529      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS :
1530        infixExpression.setOperator(InfixExpression.Operator.LESS);
1531    }
1532    
1533    if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
1534        && ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
1535      // create an extended string literal equivalent => use the extended operands list
1536      infixExpression.extendedOperands().add(convert(expression.right));
1537      org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
1538      org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
1539      do {
1540        rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
1541        if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
1542              && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
1543           || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
1544               && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
1545              && ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
1546           List extendedOperands = infixExpression.extendedOperands();
1547           InfixExpression temp = this.ast.newInfixExpression();
1548          if (this.resolveBindings) {
1549            this.recordNodes(temp, expression);
1550          }
1551           temp.setOperator(getOperatorFor(expressionOperatorID));
1552           Expression leftSide = convert(leftOperand);
1553          temp.setLeftOperand(leftSide);
1554          temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
1555          int size = extendedOperands.size();
1556           for (int i = 0; i < size - 1; i++) {
1557             Expression expr = temp;
1558             temp = this.ast.newInfixExpression();
1559             
1560            if (this.resolveBindings) {
1561              this.recordNodes(temp, expression);
1562            }           
1563             temp.setLeftOperand(expr);
1564             temp.setOperator(getOperatorFor(expressionOperatorID));
1565            temp.setSourceRange(expr.getStartPosition(), expr.getLength());
1566           }
1567           infixExpression = temp;
1568           for (int i = 0; i < size; i++) {
1569             Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
1570             temp.setRightOperand(extendedOperand);
1571             int startPosition = temp.getLeftOperand().getStartPosition();
1572             temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
1573             if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
1574               temp = (InfixExpression) temp.getLeftOperand();
1575             }
1576           }
1577          int startPosition = infixExpression.getLeftOperand().getStartPosition();
1578          infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1579          if (this.resolveBindings) {
1580            this.recordNodes(infixExpression, expression);
1581          }
1582          return infixExpression;
1583        }
1584        infixExpression.extendedOperands().add(0, convert(rightOperand));
1585        leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
1586      } while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
1587      Expression leftExpression = convert(leftOperand);
1588      infixExpression.setLeftOperand(leftExpression);
1589      infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
1590      int startPosition = leftExpression.getStartPosition();
1591      infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1592      return infixExpression;
1593    } else if (expression.left instanceof StringLiteralConcatenation
1594        && ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
1595      StringLiteralConcatenation literal = (StringLiteralConcatenation) expression.left;
1596      final org.eclipse.jdt.internal.compiler.ast.StringLiteral[] stringLiterals = literal.literals;
1597      infixExpression.setLeftOperand(convert(stringLiterals[0]));
1598      infixExpression.setRightOperand(convert(stringLiterals[1]));
1599      for (int i = 2; i < literal.counter; i++) {
1600        infixExpression.extendedOperands().add(convert(stringLiterals[i]));
1601      }
1602      infixExpression.extendedOperands().add(convert(expression.right));
1603      int startPosition = literal.sourceStart;
1604      infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1605      return infixExpression;
1606    }
1607    Expression leftExpression = convert(expression.left);
1608    infixExpression.setLeftOperand(leftExpression);
1609    infixExpression.setRightOperand(convert(expression.right));
1610    int startPosition = leftExpression.getStartPosition();
1611    infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1612    return infixExpression;
1613  }
1614      
1615  public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.UnaryExpression expression) {
1616    PrefixExpression prefixExpression = this.ast.newPrefixExpression();
1617    if (this.resolveBindings) {
1618      this.recordNodes(prefixExpression, expression);
1619    }
1620    prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1621    prefixExpression.setOperand(convert(expression.expression));
1622    switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
1623      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
1624        prefixExpression.setOperator(PrefixExpression.Operator.PLUS);
1625        break;
1626      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
1627        prefixExpression.setOperator(PrefixExpression.Operator.MINUS);
1628        break;
1629      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT :
1630        prefixExpression.setOperator(PrefixExpression.Operator.NOT);
1631        break;
1632      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.TWIDDLE :
1633        prefixExpression.setOperator(PrefixExpression.Operator.COMPLEMENT);
1634    }
1635    return prefixExpression;
1636  }
1637  
1638  public InstanceofExpression convert(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression expression) {
1639    InstanceofExpression instanceOfExpression = this.ast.newInstanceofExpression();
1640    if (this.resolveBindings) {
1641      recordNodes(instanceOfExpression, expression);
1642    }
1643    Expression leftExpression = convert(expression.expression);
1644    instanceOfExpression.setLeftOperand(leftExpression);
1645    instanceOfExpression.setRightOperand(convertType(expression.type));
1646    int startPosition = leftExpression.getStartPosition();
1647    instanceOfExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1648    return instanceOfExpression;
1649  }
1650
1651  public ConditionalExpression convert(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression expression) {
1652    ConditionalExpression conditionalExpression = this.ast.newConditionalExpression();
1653    if (this.resolveBindings) {
1654      recordNodes(conditionalExpression, expression);
1655    }
1656    conditionalExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
1657    conditionalExpression.setExpression(convert(expression.condition));
1658    conditionalExpression.setThenExpression(convert(expression.valueIfTrue));
1659    conditionalExpression.setElseExpression(convert(expression.valueIfFalse));
1660    return conditionalExpression;
1661  }
1662
1663  public Expression convert(MessageSend expression) {
1664    // will return a MethodInvocation or a SuperMethodInvocation or
1665    Expression expr;
1666    int sourceStart = expression.sourceStart;
1667    if (expression.isSuperAccess()) {
1668      // returns a SuperMethodInvocation
1669      SuperMethodInvocation superMethodInvocation = this.ast.newSuperMethodInvocation();
1670      if (this.resolveBindings) {
1671        recordNodes(superMethodInvocation, expression);
1672      }
1673      SimpleName name = this.ast.newSimpleName(new String(expression.selector));
1674      int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
1675      int nameSourceLength = (int)(expression.nameSourcePosition & 0xFFFFFFFF) - nameSourceStart + 1;
1676      name.setSourceRange(nameSourceStart, nameSourceLength);
1677      if (this.resolveBindings) {
1678        recordNodes(name, expression);
1679      }
1680      superMethodInvocation.setName(name);
1681      // expression.receiver is either a QualifiedSuperReference or a SuperReference
1682      // so the casting cannot fail
1683      if (expression.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
1684        Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) expression.receiver);
1685        superMethodInvocation.setQualifier(qualifier);
1686        if (this.resolveBindings) {
1687          recordNodes(qualifier, expression.receiver);
1688        }
1689        if (qualifier != null) {
1690          sourceStart = qualifier.getStartPosition();
1691        }      
1692      }
1693      org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
1694      if (arguments != null) {
1695        int argumentsLength = arguments.length;
1696        for (int i = 0; i < argumentsLength; i++) {
1697          Expression expri = convert(arguments[i]);
1698          if (this.resolveBindings) {
1699            recordNodes(expri, arguments[i]);
1700          }
1701          superMethodInvocation.arguments().add(expri);
1702        }
1703      }
1704      expr = superMethodInvocation;
1705    } else {
1706      // returns a MethodInvocation
1707      MethodInvocation methodInvocation = this.ast.newMethodInvocation();
1708      if (this.resolveBindings) {
1709        recordNodes(methodInvocation, expression);
1710      }
1711      SimpleName name = this.ast.newSimpleName(new String(expression.selector));
1712      int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
1713      int nameSourceLength = (int)(expression.nameSourcePosition & 0xFFFFFFFF) - nameSourceStart + 1;
1714      name.setSourceRange(nameSourceStart, nameSourceLength);
1715      methodInvocation.setName(name);
1716      if (this.resolveBindings) {
1717        recordNodes(name, expression);
1718      }
1719      org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
1720      if (arguments != null) {
1721        int argumentsLength = arguments.length;
1722        for (int i = 0; i < argumentsLength; i++) {
1723          Expression expri = convert(arguments[i]);
1724          if (this.resolveBindings) {
1725            recordNodes(expri, arguments[i]);
1726          }
1727          methodInvocation.arguments().add(expri);
1728        }
1729      }
1730      Expression qualifier = null;
1731      org.eclipse.jdt.internal.compiler.ast.Expression receiver = expression.receiver;
1732      if (receiver instanceof MessageSend) {
1733        if ((receiver.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
1734          qualifier = convertToParenthesizedExpression(receiver);
1735        } else {
1736          qualifier = convert((MessageSend) receiver);
1737        }
1738      } else {
1739        qualifier = convert(receiver);
1740      }
1741      if (qualifier instanceof Name && this.resolveBindings) {
1742        recordNodes(qualifier, receiver);
1743      }
1744      methodInvocation.setExpression(qualifier);
1745      if (qualifier != null) {
1746        sourceStart = qualifier.getStartPosition();
1747      }
1748      expr = methodInvocation;
1749    }
1750    expr.setSourceRange(sourceStart, expression.sourceEnd - sourceStart + 1);  
1751    removeTrailingCommentFromExpressionEndingWithAParen(expr);
1752    return expr;
1753  }
1754
1755  public Expression convert(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression expression) {
1756    InfixExpression infixExpression = this.ast.newInfixExpression();
1757    if (this.resolveBindings) {
1758      recordNodes(infixExpression, expression);
1759    }
1760    Expression leftExpression = convert(expression.left);
1761    infixExpression.setLeftOperand(leftExpression);
1762    infixExpression.setRightOperand(convert(expression.right));
1763    infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
1764    int startPosition = leftExpression.getStartPosition();
1765    infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1766    return infixExpression;
1767  
1768  }
1769  
1770  public Expression convert(org.eclipse.jdt.internal.compiler.ast.EqualExpression expression) {
1771    InfixExpression infixExpression = this.ast.newInfixExpression();
1772    if (this.resolveBindings) {
1773      recordNodes(infixExpression, expression);
1774    }
1775    Expression leftExpression = convert(expression.left);
1776    infixExpression.setLeftOperand(leftExpression);
1777    infixExpression.setRightOperand(convert(expression.right));
1778    int startPosition = leftExpression.getStartPosition();
1779    infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
1780    switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
1781      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
1782        infixExpression.setOperator(InfixExpression.Operator.EQUALS);
1783        break;
1784      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
1785        infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
1786    }
1787    return infixExpression;
1788  
1789  }
1790
1791  public Expression convert(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression expression) {
1792    InfixExpression infixExpression = this.ast.newInfixExpression();
1793    if (this.resolveBindings) {
1794      recordNodes(infixExpression, expression);
1795    }
1796    Expression leftExpression = convert(expression.left);
1797    infixExpression.setLeftOperand(leftExpression);
1798    infixExpression.setRightOperand(convert(expression.right));
1799    infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
1800    int sourceStart = leftExpression.getStartPosition();
1801    infixExpression.setSourceRange(sourceStart, expression.sourceEnd - sourceStart + 1);
1802    return infixExpression;
1803  }
1804
1805  public Statement convert(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
1806    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
1807      return convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)statement);
1808    }
1809    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.AssertStatement) {
1810      return convert((org.eclipse.jdt.internal.compiler.ast.AssertStatement) statement);
1811    }
1812    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Block) {
1813      return convert((org.eclipse.jdt.internal.compiler.ast.Block) statement);
1814    }
1815    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.BreakStatement) {
1816      return convert((org.eclipse.jdt.internal.compiler.ast.BreakStatement) statement);
1817    }
1818    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ContinueStatement) {
1819      return convert((org.eclipse.jdt.internal.compiler.ast.ContinueStatement) statement);
1820    }
1821    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.CaseStatement) {
1822      return convert((org.eclipse.jdt.internal.compiler.ast.CaseStatement) statement);
1823    }
1824    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.DoStatement) {
1825      return convert((org.eclipse.jdt.internal.compiler.ast.DoStatement) statement);
1826    }
1827    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.EmptyStatement) {
1828      return convert((org.eclipse.jdt.internal.compiler.ast.EmptyStatement) statement);
1829    }
1830    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) {
1831      return convert((org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) statement);
1832    }
1833    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ForStatement) {
1834      return convert((org.eclipse.jdt.internal.compiler.ast.ForStatement) statement);
1835    }
1836    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.IfStatement) {
1837      return convert((org.eclipse.jdt.internal.compiler.ast.IfStatement) statement);
1838    }
1839    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LabeledStatement) {
1840      return convert((org.eclipse.jdt.internal.compiler.ast.LabeledStatement) statement);
1841    }
1842    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ReturnStatement) {
1843      return convert((org.eclipse.jdt.internal.compiler.ast.ReturnStatement) statement);
1844    }
1845    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SwitchStatement) {
1846      return convert((org.eclipse.jdt.internal.compiler.ast.SwitchStatement) statement);
1847    }
1848    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) {
1849      return convert((org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) statement);
1850    }
1851    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ThrowStatement) {
1852      return convert((org.eclipse.jdt.internal.compiler.ast.ThrowStatement) statement);
1853    }
1854    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TryStatement) {
1855      return convert((org.eclipse.jdt.internal.compiler.ast.TryStatement) statement);
1856    }
1857    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration 
1858        && (statement.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsLocalTypeMASK) != 0) {
1859      TypeDeclarationStatement typeDeclarationStatement = this.ast.newTypeDeclarationStatement(convert((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) statement));
1860      TypeDeclaration typeDecl = typeDeclarationStatement.getTypeDeclaration();
1861      typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
1862      return typeDeclarationStatement;
1863    }
1864    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
1865      TypeDeclarationStatement typeDeclarationStatement = this.ast.newTypeDeclarationStatement(convert((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) statement));
1866      TypeDeclaration typeDecl = typeDeclarationStatement.getTypeDeclaration();
1867      typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
1868      return typeDeclarationStatement;
1869    }
1870    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.WhileStatement) {
1871      return convert((org.eclipse.jdt.internal.compiler.ast.WhileStatement) statement);
1872    }
1873    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
1874      Expression expr = convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
1875      Statement stmt = this.ast.newExpressionStatement(expr);
1876      stmt.setSourceRange(expr.getStartPosition(), expr.getLength());
1877      retrieveSemiColonPosition(stmt);
1878      return stmt;
1879    }
1880    throw new IllegalArgumentException("Not yet implemented: convert(" + statement.getClass() + ")");//$NON-NLS-1$//$NON-NLS-2$
1881  }
1882
1883  public AssertStatement convert(org.eclipse.jdt.internal.compiler.ast.AssertStatement statement) {
1884    AssertStatement assertStatement = this.ast.newAssertStatement();
1885    int end = statement.assertExpression.sourceEnd + 1;
1886    assertStatement.setExpression(convert(statement.assertExpression));
1887    org.eclipse.jdt.internal.compiler.ast.Expression exceptionArgument = statement.exceptionArgument;
1888    if (exceptionArgument != null) {
1889      assertStatement.setMessage(convert(exceptionArgument));
1890      end = exceptionArgument.sourceEnd + 1;
1891    }
1892    int start = statement.sourceStart;
1893    int sourceEnd = retrieveEndingSemiColonPosition(end, this.compilationUnitSource.length);
1894    assertStatement.setSourceRange(start, sourceEnd - start + 1);
1895    return assertStatement;
1896  }
1897
1898  public Block convert(org.eclipse.jdt.internal.compiler.ast.Block statement) {
1899    Block block = this.ast.newBlock();
1900    if (statement.sourceEnd > 0) {
1901      block.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1902    }
1903    org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
1904    if (statements != null) {
1905      int statementsLength = statements.length;
1906      for (int i = 0; i < statementsLength; i++) {
1907        if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
1908          checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
1909        } else {
1910          block.statements().add(convert(statements[i]));
1911        }        
1912      }
1913    }
1914    return block;
1915  }
1916  
1917  public BreakStatement convert(org.eclipse.jdt.internal.compiler.ast.BreakStatement statement)  {
1918    BreakStatement breakStatement = this.ast.newBreakStatement();
1919    breakStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1920    if (statement.label != null) {
1921      SimpleName name = this.ast.newSimpleName(new String(statement.label));
1922      retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
1923      breakStatement.setLabel(name);
1924    }
1925    retrieveSemiColonPosition(breakStatement);
1926    return breakStatement;
1927  }
1928
1929  public ContinueStatement convert(org.eclipse.jdt.internal.compiler.ast.ContinueStatement statement)  {
1930    ContinueStatement continueStatement = this.ast.newContinueStatement();
1931    continueStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1932    if (statement.label != null) {
1933      SimpleName name = this.ast.newSimpleName(new String(statement.label));
1934      retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
1935      continueStatement.setLabel(name);
1936    }
1937    retrieveSemiColonPosition(continueStatement);
1938    return continueStatement;
1939  }
1940    
1941    
1942  public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) {
1943    SwitchCase switchCase = this.ast.newSwitchCase();
1944    org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
1945    if (constantExpression == null) {
1946      switchCase.setExpression(null);
1947    } else {
1948      switchCase.setExpression(convert(constantExpression));
1949    }
1950    switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1951    retrieveColonPosition(switchCase);
1952    return switchCase;
1953  }
1954  
1955  public DoStatement convert(org.eclipse.jdt.internal.compiler.ast.DoStatement statement) {
1956    DoStatement doStatement = this.ast.newDoStatement();
1957    doStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1958    doStatement.setExpression(convert(statement.condition));
1959    doStatement.setBody(convert(statement.action));
1960    retrieveSemiColonPosition(doStatement);
1961    return doStatement;
1962  }
1963  
1964  public EmptyStatement convert(org.eclipse.jdt.internal.compiler.ast.EmptyStatement statement) {
1965    EmptyStatement emptyStatement = this.ast.newEmptyStatement();
1966    emptyStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1967    return emptyStatement;
1968  }
1969  
1970  public Statement convert(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall statement) {
1971    Statement newStatement;
1972    if (statement.isSuperAccess() || statement.isSuper()) {
1973      SuperConstructorInvocation superConstructorInvocation = this.ast.newSuperConstructorInvocation();
1974      if (statement.qualification != null) {
1975        superConstructorInvocation.setExpression(convert(statement.qualification));
1976      }
1977      org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
1978      if (arguments != null) {
1979        int length = arguments.length;
1980        for (int i = 0; i < length; i++) {
1981          superConstructorInvocation.arguments().add(convert(arguments[i]));
1982        }
1983      }
1984      newStatement = superConstructorInvocation;
1985    } else {
1986      ConstructorInvocation constructorInvocation = this.ast.newConstructorInvocation();
1987      org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
1988      if (arguments != null) {
1989        int length = arguments.length;
1990        for (int i = 0; i < length; i++) {
1991          constructorInvocation.arguments().add(convert(arguments[i]));
1992        }
1993      }
1994      newStatement = constructorInvocation;
1995    }
1996    newStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
1997    retrieveSemiColonPosition(newStatement);
1998    if (this.resolveBindings) {
1999      recordNodes(newStatement, statement);
2000    }
2001    return newStatement;
2002  }
2003  
2004  public ForStatement convert(org.eclipse.jdt.internal.compiler.ast.ForStatement statement) {
2005    ForStatement forStatement = this.ast.newForStatement();
2006    forStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2007    org.eclipse.jdt.internal.compiler.ast.Statement[] initializations = statement.initializations;
2008    if (initializations != null) {
2009      // we know that we have at least one initialization
2010      if (initializations[0] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
2011        VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[0]);
2012        int initializationsLength = initializations.length;
2013        for (int i = 1; i < initializationsLength; i++) {
2014          variableDeclarationExpression.fragments().add(convertToVariableDeclarationFragment((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)initializations[i]));
2015        }
2016        if (initializationsLength != 1) {
2017          int start = variableDeclarationExpression.getStartPosition();
2018          int end = ((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[initializationsLength - 1]).declarationSourceEnd;
2019          variableDeclarationExpression.setSourceRange(start, end - start + 1);
2020        }
2021        forStatement.initializers().add(variableDeclarationExpression);
2022      } else {
2023        int initializationsLength = initializations.length;
2024        for (int i = 0; i < initializationsLength; i++) {
2025          forStatement.initializers().add(convertToExpression(initializations[i]));
2026        }
2027      }
2028    }
2029    if (statement.condition != null) {
2030      forStatement.setExpression(convert(statement.condition));
2031    }
2032    org.eclipse.jdt.internal.compiler.ast.Statement[] increments = statement.increments;
2033    if (increments != null) {
2034      int incrementsLength = increments.length;
2035      for (int i = 0; i < incrementsLength; i++) {
2036        forStatement.updaters().add(convertToExpression(increments[i]));        
2037      }
2038    }
2039    forStatement.setBody(convert(statement.action));
2040    return forStatement;
2041  }
2042  
2043  public Expression convertToExpression(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
2044    if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
2045      return convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
2046    }
2047    // unsupported
2048    throw new IllegalArgumentException("Not yet implemented: convert(" + statement.getClass() + ")");//$NON-NLS-1$//$NON-NLS-2$
2049  }
2050  
2051  public IfStatement convert(org.eclipse.jdt.internal.compiler.ast.IfStatement statement) {
2052    IfStatement ifStatement = this.ast.newIfStatement();
2053    ifStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2054    ifStatement.setExpression(convert(statement.condition));
2055    ifStatement.setThenStatement(convert(statement.thenStatement));
2056    if (statement.elseStatement != null) {
2057      ifStatement.setElseStatement(convert(statement.elseStatement));
2058    }
2059    return ifStatement;
2060  }
2061  
2062  public LabeledStatement convert(org.eclipse.jdt.internal.compiler.ast.LabeledStatement statement) {
2063    LabeledStatement labeledStatement = this.ast.newLabeledStatement();
2064    labeledStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2065    org.eclipse.jdt.internal.compiler.ast.Statement body = statement.statement;
2066    labeledStatement.setBody(convert(body));
2067    SimpleName name = this.ast.newSimpleName(new String(statement.label));
2068    retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
2069    labeledStatement.setLabel(name);
2070    return labeledStatement;
2071  }
2072  
2073  public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
2074    ReturnStatement returnStatement = this.ast.newReturnStatement();
2075    returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2076    if (statement.expression != null) {
2077      returnStatement.setExpression(convert(statement.expression));
2078    }
2079    retrieveSemiColonPosition(returnStatement);
2080    return returnStatement;
2081  }
2082  
2083  public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) {
2084    SwitchStatement switchStatement = this.ast.newSwitchStatement();
2085    switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2086    switchStatement.setExpression(convert(statement.expression));
2087    org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
2088    if (statements != null) {
2089      int statementsLength = statements.length;
2090      for (int i = 0; i < statementsLength; i++) {
2091        switchStatement.statements().add(convert(statements[i]));
2092      }
2093    }
2094    return switchStatement;
2095  }
2096  
2097  public SynchronizedStatement convert(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement statement) {
2098    SynchronizedStatement synchronizedStatement = this.ast.newSynchronizedStatement();
2099    synchronizedStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2100    synchronizedStatement.setBody(convert(statement.block));
2101    synchronizedStatement.setExpression(convert(statement.expression));
2102    return synchronizedStatement;
2103  }
2104  
2105  public ThrowStatement convert(org.eclipse.jdt.internal.compiler.ast.ThrowStatement statement) {
2106    ThrowStatement throwStatement = this.ast.newThrowStatement();
2107    throwStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2108    throwStatement.setExpression(convert(statement.exception));
2109    retrieveSemiColonPosition(throwStatement);
2110    return throwStatement;
2111  }
2112  
2113  public TryStatement convert(org.eclipse.jdt.internal.compiler.ast.TryStatement statement) {
2114    TryStatement tryStatement = this.ast.newTryStatement();
2115    tryStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);  
2116
2117    tryStatement.setBody(convert(statement.tryBlock));
2118    org.eclipse.jdt.internal.compiler.ast.Argument[] catchArguments = statement.catchArguments;
2119    if (catchArguments != null) {
2120      int catchArgumentsLength = catchArguments.length;
2121      org.eclipse.jdt.internal.compiler.ast.Block[] catchBlocks = statement.catchBlocks;
2122      int start = statement.tryBlock.sourceEnd;
2123      for (int i = 0; i < catchArgumentsLength; i++) {
2124        CatchClause catchClause = this.ast.newCatchClause();
2125        int catchClauseSourceStart = retrieveStartingCatchPosition(start, catchArguments[i].sourceStart);
2126        catchClause.setSourceRange(catchClauseSourceStart, catchBlocks[i].sourceEnd - catchClauseSourceStart + 1);  
2127        catchClause.setBody(convert(catchBlocks[i]));
2128        catchClause.setException(convert(catchArguments[i]));
2129        tryStatement.catchClauses().add(catchClause);
2130        start = catchBlocks[i].sourceEnd;
2131      }
2132    }
2133    if (statement.finallyBlock != null) {
2134      tryStatement.setFinally(convert(statement.finallyBlock));
2135    }
2136    return tryStatement;
2137  }
2138  
2139  public WhileStatement convert(org.eclipse.jdt.internal.compiler.ast.WhileStatement statement) {
2140    WhileStatement whileStatement = this.ast.newWhileStatement();
2141    whileStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
2142    whileStatement.setExpression(convert(statement.condition));
2143    org.eclipse.jdt.internal.compiler.ast.Statement action = statement.action;
2144    whileStatement.setBody(convert(action));
2145    return whileStatement;
2146  }
2147  
2148  private boolean isPrimitiveType(char[] name) {
2149    switch(name[0]) {
2150      case 'i' :
2151        if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
2152          return true;
2153        }
2154        return false;
2155      case 'l' :
2156        if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
2157          return true;
2158        }
2159        return false;
2160      case 'd' :
2161        if (name.length == 6
2162           && name[1] == 'o'
2163           && name[2] == 'u'
2164           && name[3] == 'b'
2165           && name[4] == 'l'
2166           && name[5] == 'e') {
2167          return true;
2168        }
2169        return false;
2170      case 'f' :
2171        if (name.length == 5
2172           && name[1] == 'l'
2173           && name[2] == 'o'
2174           && name[3] == 'a'
2175           && name[4] == 't') {
2176          return true;
2177        }
2178        return false;
2179      case 'b' :
2180        if (name.length == 4
2181           && name[1] == 'y'
2182           && name[2] == 't'
2183           && name[3] == 'e') {
2184          return true;
2185        } else
2186          if (name.length == 7
2187             && name[1] == 'o'
2188             && name[2] == 'o'
2189             && name[3] == 'l'
2190             && name[4] == 'e'
2191             && name[5] == 'a'
2192             && name[6] == 'n') {
2193          return true;
2194        }
2195        return false;
2196      case 'c' :
2197        if (name.length == 4
2198           && name[1] == 'h'
2199           && name[2] == 'a'
2200           && name[3] == 'r') {
2201          return true;
2202        }
2203        return false;
2204      case 's' :
2205        if (name.length == 5
2206           && name[1] == 'h'
2207           && name[2] == 'o'
2208           && name[3] == 'r'
2209           && name[4] == 't') {
2210          return true;
2211        }
2212        return false;
2213      case 'v' :
2214        if (name.length == 4
2215           && name[1] == 'o'
2216           && name[2] == 'i'
2217           && name[3] == 'd') {
2218          return true;
2219        }
2220        return false;
2221    }
2222    return false;
2223  }
2224  
2225  private PrimitiveType.Code getPrimitiveTypeCode(char[] name) {
2226    switch(name[0]) {
2227      case 'i' :
2228        if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
2229          return PrimitiveType.INT;
2230        }
2231        break;
2232      case 'l' :
2233        if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
2234          return PrimitiveType.LONG;
2235        }
2236        break;
2237      case 'd' :
2238        if (name.length == 6
2239           && name[1] == 'o'
2240           && name[2] == 'u'
2241           && name[3] == 'b'
2242           && name[4] == 'l'
2243           && name[5] == 'e') {
2244          return PrimitiveType.DOUBLE;
2245        }
2246        break;
2247      case 'f' :
2248        if (name.length == 5
2249           && name[1] == 'l'
2250           && name[2] == 'o'
2251           && name[3] == 'a'
2252           && name[4] == 't') {
2253          return PrimitiveType.FLOAT;
2254        }
2255        break;
2256      case 'b' :
2257        if (name.length == 4
2258           && name[1] == 'y'
2259           && name[2] == 't'
2260           && name[3] == 'e') {
2261          return PrimitiveType.BYTE;
2262        } else
2263          if (name.length == 7
2264             && name[1] == 'o'
2265             && name[2] == 'o'
2266             && name[3] == 'l'
2267             && name[4] == 'e'
2268             && name[5] == 'a'
2269             && name[6] == 'n') {
2270          return PrimitiveType.BOOLEAN;
2271        }
2272        break;
2273      case 'c' :
2274        if (name.length == 4
2275           && name[1] == 'h'
2276           && name[2] == 'a'
2277           && name[3] == 'r') {
2278          return PrimitiveType.CHAR;
2279        }
2280        break;
2281      case 's' :
2282        if (name.length == 5
2283           && name[1] == 'h'
2284           && name[2] == 'o'
2285           && name[3] == 'r'
2286           && name[4] == 't') {
2287          return PrimitiveType.SHORT;
2288        }
2289        break;
2290      case 'v' :
2291        if (name.length == 4
2292           && name[1] == 'o'
2293           && name[2] == 'i'
2294           && name[3] == 'd') {
2295          return PrimitiveType.VOID;
2296        }
2297    }
2298    throw new IllegalArgumentException("Not a primitive type");//$NON-NLS-1$
2299  }
2300  
2301  /*
2302   * This method is used to set the right end position for expression
2303   * statement. The actual AST nodes don't include the trailing semicolon.
2304   * This method fixes the length of the corresponding node.
2305   */
2306  private void retrieveSemiColonPosition(ASTNode node) {
2307    int start = node.getStartPosition();
2308    int length = node.getLength();
2309    int end = start + length;
2310    int count = 0;
2311    this.scanner.resetTo(end, this.compilationUnitSource.length);
2312    try {
2313      int token;
2314      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2315        switch(token) {
2316          case TerminalTokens.TokenNameSEMICOLON:
2317            if (count == 0) {
2318              node.setSourceRange(start, this.scanner.currentPosition - start);
2319              return;
2320            }
2321            break;
2322          case TerminalTokens.TokenNameLBRACE :
2323            count++;
2324            break;
2325          case TerminalTokens.TokenNameRBRACE :
2326            count--;
2327            break;
2328          case TerminalTokens.TokenNameLPAREN :
2329            count++;
2330            break;
2331          case TerminalTokens.TokenNameRPAREN :
2332            count--;
2333            break;
2334          case TerminalTokens.TokenNameLBRACKET :
2335            count++;
2336            break;
2337          case TerminalTokens.TokenNameRBRACKET :
2338            count--;
2339        }
2340      }
2341    } catch(InvalidInputException e) {
2342      // ignore
2343    }
2344  }
2345
2346  /**
2347   * This method is used to set the right end position for expression
2348   * statement. The actual AST nodes don't include the trailing semicolon.
2349   * This method fixes the length of the corresponding node.
2350   */
2351  private void retrieveColonPosition(ASTNode node) {
2352    int start = node.getStartPosition();
2353    int length = node.getLength();
2354    int end = start + length;
2355    this.scanner.resetTo(end, this.compilationUnitSource.length);
2356    try {
2357      int token;
2358      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2359        switch(token) {
2360          case TerminalTokens.TokenNameCOLON:
2361            node.setSourceRange(start, this.scanner.currentPosition - start);
2362            return;
2363        }
2364      }
2365    } catch(InvalidInputException e) {
2366      // ignore
2367    }
2368  }
2369
2370  private int retrieveEndingSemiColonPosition(int start, int end) {
2371    int count = 0;
2372    this.scanner.resetTo(start, end);
2373    try {
2374      int token;
2375      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2376        switch(token) {
2377          case TerminalTokens.TokenNameSEMICOLON:
2378            if (count == 0) {
2379              return this.scanner.currentPosition - 1;
2380            }
2381            break;
2382          case TerminalTokens.TokenNameLBRACE :
2383            count++;
2384            break;
2385          case TerminalTokens.TokenNameRBRACE :
2386            count--;
2387            break;
2388          case TerminalTokens.TokenNameLPAREN :
2389            count++;
2390            break;
2391          case TerminalTokens.TokenNameRPAREN :
2392            count--;
2393            break;
2394          case TerminalTokens.TokenNameLBRACKET :
2395            count++;
2396            break;
2397          case TerminalTokens.TokenNameRBRACKET :
2398            count--;
2399        }
2400      }
2401    } catch(InvalidInputException e) {
2402      // ignore
2403    }
2404    return -1;
2405  }
2406
2407  /**
2408   * This method is used to retrieve the array dimension declared after the
2409   * name of a local or a field declaration.
2410   * For example:
2411   *    int i, j[] = null, k[][] = {{}};
2412   *    It should return 0 for i, 1 for j and 2 for k.
2413   * @return int the dimension found
2414   */
2415  private int retrieveExtraDimension(int start, int end) {
2416    this.scanner.resetTo(start, end);
2417    int dimensions = 0;
2418    try {
2419      int token;
2420      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2421        switch(token) {
2422          case TerminalTokens.TokenNameRBRACKET://166 
2423            dimensions++;
2424            break;
2425          case TerminalTokens.TokenNameLBRACE ://90            
2426          case TerminalTokens.TokenNameCOMMA ://90
2427          case TerminalTokens.TokenNameEQUAL ://167
2428          case TerminalTokens.TokenNameSEMICOLON ://64
2429          case TerminalTokens.TokenNameRPAREN : //86
2430            return dimensions;
2431        }
2432      }
2433    } catch(InvalidInputException e) {
2434      // ignore
2435    }
2436    return dimensions;
2437  }
2438
2439  /**
2440   * This method is used to retrieve the ending position for a type declaration when the dimension is right after the type
2441   * name.
2442   * For example:
2443   *    int[] i; => return 5, but int i[] => return -1;
2444   * @return int the dimension found
2445   */
2446  private int retrieveEndOfDimensionsPosition(int start, int end) {
2447    this.scanner.resetTo(start, end);
2448    int foundPosition = -1;
2449    try {
2450      int token;
2451      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2452        switch(token) {
2453          case TerminalTokens.TokenNameLBRACKET:
2454          case TerminalTokens.TokenNameCOMMENT_BLOCK:
2455          case TerminalTokens.TokenNameCOMMENT_JAVADOC:
2456          case TerminalTokens.TokenNameCOMMENT_LINE:
2457            break;
2458          case TerminalTokens.TokenNameRBRACKET://166
2459            foundPosition = this.scanner.currentPosition - 1;
2460            break;
2461          default:
2462            return foundPosition;
2463        }
2464      }
2465    } catch(InvalidInputException e) {
2466      // ignore
2467    }
2468    return foundPosition;
2469  }
2470
2471  /**
2472   * This method is used to retrieve the starting position of the catch keyword.
2473   * @return int the dimension found, -1 if none
2474   */
2475  private int retrieveStartingCatchPosition(int start, int end) {
2476    this.scanner.resetTo(start, end);
2477    try {
2478      int token;
2479      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2480        switch(token) {
2481          case TerminalTokens.TokenNamecatch://225
2482            return this.scanner.startPosition;
2483        }
2484      }
2485    } catch(InvalidInputException e) {
2486      // ignore
2487    }
2488    return -1;
2489  }
2490
2491  /**
2492   * This method is used to retrieve the position just before the left bracket.
2493   * @return int the dimension found, -1 if none
2494   */
2495  private int retrieveEndOfElementTypeNamePosition(int start, int end) {
2496    this.scanner.resetTo(start, end);
2497    try {
2498      int token;
2499      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2500        switch(token) {
2501          case TerminalTokens.TokenNameIdentifier:
2502          case TerminalTokens.TokenNamebyte:
2503          case TerminalTokens.TokenNamechar:
2504          case TerminalTokens.TokenNamedouble:
2505          case TerminalTokens.TokenNamefloat:
2506          case TerminalTokens.TokenNameint:
2507          case TerminalTokens.TokenNamelong:
2508          case TerminalTokens.TokenNameshort:
2509            return this.scanner.currentPosition - 1;
2510        }
2511      }
2512    } catch(InvalidInputException e) {
2513      // ignore
2514    }
2515    return -1;
2516  }
2517
2518  /**
2519   * This method is used to retrieve the position of the right bracket.
2520   * @return int the dimension found, -1 if none
2521   */
2522  private int retrieveRightBracketPosition(int start, int end) {
2523    this.scanner.resetTo(start, end);
2524    try {
2525      int token;
2526      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2527        switch(token) {
2528          case TerminalTokens.TokenNameRBRACKET:
2529            return this.scanner.currentPosition - 1;
2530        }
2531      }
2532    } catch(InvalidInputException e) {
2533      // ignore
2534    }
2535    return -1;
2536  }
2537
2538  /**
2539   * This method is used to retrieve the position after the right parenthesis.
2540   * @return int the position found
2541   */
2542  private int retrieveEndOfRightParenthesisPosition(int start, int end) {
2543    this.scanner.resetTo(start, end);
2544    try {
2545      int token;
2546      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2547        switch(token) {
2548          case TerminalTokens.TokenNameRPAREN:
2549            return this.scanner.currentPosition;
2550        }
2551      }
2552    } catch(InvalidInputException e) {
2553      // ignore
2554    }
2555    return -1;
2556  }
2557
2558  private int retrieveProperRightBracketPosition(int bracketNumber, int start, int end) {
2559    this.scanner.resetTo(start, end);
2560    try {
2561      int token, count = 0;
2562      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2563        switch(token) {
2564          case TerminalTokens.TokenNameRBRACKET:
2565            count++;
2566            if (count == bracketNumber) {
2567              return this.scanner.currentPosition - 1;
2568            }
2569        }
2570      }
2571    } catch(InvalidInputException e) {
2572      // ignore
2573    }
2574    return -1;
2575  }
2576  
2577  /**
2578   * This method is used to retrieve the start position of the block.
2579   * @return int the dimension found, -1 if none
2580   */
2581  private int retrieveStartBlockPosition(int start, int end) {
2582    this.scanner.resetTo(start, end);
2583    try {
2584      int token;
2585      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2586        switch(token) {
2587          case TerminalTokens.TokenNameLBRACE://110
2588            return this.scanner.startPosition;
2589        }
2590      }
2591    } catch(InvalidInputException e) {
2592      // ignore
2593    }
2594    return -1;
2595  }
2596  
2597  /**
2598   * This method is used to retrieve the start position of the block.
2599   * @return int the dimension found, -1 if none
2600   */
2601  private int retrieveIdentifierEndPosition(int start, int end) {
2602    this.scanner.resetTo(start, end);
2603    try {
2604      int token;
2605      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2606        switch(token) {
2607          case TerminalTokens.TokenNameIdentifier://110
2608            return this.scanner.getCurrentTokenEndPosition();
2609        }
2610      }
2611    } catch(InvalidInputException e) {
2612      // ignore
2613    }
2614    return -1;
2615  }  
2616  
2617  /**
2618   * This method is used to retrieve the end position of the block.
2619   * @return int the dimension found, -1 if none
2620   */
2621  private int retrieveEndBlockPosition(int start, int end) {
2622    this.scanner.resetTo(start, end);
2623    int count = 0;
2624    try {
2625      int token;
2626      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2627        switch(token) {
2628          case TerminalTokens.TokenNameLBRACE://110
2629            count++;
2630            break;
2631          case TerminalTokens.TokenNameRBRACE://95
2632            count--;
2633            if (count == 0) {
2634              return this.scanner.currentPosition - 1;
2635            }
2636        }
2637      }
2638    } catch(InvalidInputException e) {
2639      // ignore
2640    }
2641    return -1;
2642  }
2643
2644  /**
2645   * This method is used to retrieve position before the next right brace or semi-colon.
2646   * @return int the position found.
2647   */
2648  private int retrieveRightBraceOrSemiColonPosition(MethodDeclaration node, org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) {
2649    int start = node.getStartPosition();
2650    this.scanner.resetTo(start, methodDeclaration.declarationSourceEnd);
2651    try {
2652      int token;
2653      int braceCounter = 0;
2654      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2655        switch(token) {
2656          case TerminalTokens.TokenNameLBRACE :
2657            braceCounter++;
2658            break;
2659          case TerminalTokens.TokenNameRBRACE :
2660            braceCounter--;
2661            if (braceCounter == 0) {
2662              return this.scanner.currentPosition;
2663            }
2664            break;
2665          case TerminalTokens.TokenNameSEMICOLON :
2666            if (braceCounter == 0) {
2667              return this.scanner.currentPosition;
2668            }
2669        }
2670      }
2671    } catch(InvalidInputException e) {
2672      // ignore
2673    }
2674    return -1;
2675  }
2676
2677  /**
2678   * This method is used to retrieve position before the next comma or semi-colon.
2679   * @return int the position found.
2680   */
2681  private int retrievePositionBeforeNextCommaOrSemiColon(int start, int end) {
2682    this.scanner.resetTo(start, end);
2683    int braceCounter = 0;
2684    try {
2685      int token;
2686      while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
2687        switch(token) {
2688          case TerminalTokens.TokenNameLBRACE :
2689            braceCounter++;
2690            break;
2691          case TerminalTokens.TokenNameRBRACE :
2692            braceCounter--;
2693            break;
2694          case TerminalTokens.TokenNameLPAREN :
2695            braceCounter++;
2696            break;
2697          case TerminalTokens.TokenNameRPAREN :
2698            braceCounter--;
2699            break;
2700          case TerminalTokens.TokenNameLBRACKET :
2701            braceCounter++;
2702            break;
2703          case TerminalTokens.TokenNameRBRACKET :
2704            braceCounter--;
2705            break;
2706          case TerminalTokens.TokenNameCOMMA :
2707          case TerminalTokens.TokenNameSEMICOLON :
2708            if (braceCounter == 0) {
2709              return this.scanner.startPosition - 1;
2710            }
2711        }
2712      }
2713    } catch(InvalidInputException e) {
2714      // ignore
2715    }
2716    return -1;
2717  }
2718  
2719  private VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
2720    VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment();
2721    SimpleName name = this.ast.newSimpleName(new String(fieldDeclaration.name));
2722    name.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.sourceEnd - fieldDeclaration.sourceStart + 1);
2723    variableDeclarationFragment.setName(name);
2724    int end = retrievePositionBeforeNextCommaOrSemiColon(fieldDeclaration.sourceEnd, fieldDeclaration.declarationSourceEnd);
2725    if (end == -1) {
2726      variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.declarationSourceEnd - fieldDeclaration.sourceStart + 1);
2727      variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
2728    } else {
2729      variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, end - fieldDeclaration.sourceStart + 1);
2730    }
2731    if (fieldDeclaration.initialization != null) {
2732      variableDeclarationFragment.setInitializer(convert(fieldDeclaration.initialization));
2733    }
2734    variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd ));
2735    if (this.resolveBindings) {
2736      recordNodes(name, fieldDeclaration);
2737      recordNodes(variableDeclarationFragment, fieldDeclaration);
2738      variableDeclarationFragment.resolveBinding();
2739    }
2740    return variableDeclarationFragment;
2741  }
2742
2743  private VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
2744    VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment();
2745    SimpleName name = this.ast.newSimpleName(new String(localDeclaration.name));
2746    name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
2747    variableDeclarationFragment.setName(name);
2748    int end = retrievePositionBeforeNextCommaOrSemiColon(localDeclaration.sourceEnd, this.compilationUnitSource.length);
2749    if (end == -1) {
2750      if (localDeclaration.initialization != null) {
2751        variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, localDeclaration.initialization.sourceEnd - localDeclaration.sourceStart + 1);
2752      } else {
2753        variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
2754      }
2755    } else {
2756      variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, end - localDeclaration.sourceStart + 1);
2757    }
2758    if (localDeclaration.initialization != null) {
2759      variableDeclarationFragment.setInitializer(convert(localDeclaration.initialization));
2760    }
2761    variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSource.length));
2762    if (this.resolveBindings) {
2763      recordNodes(variableDeclarationFragment, localDeclaration);
2764      recordNodes(name, localDeclaration);
2765      variableDeclarationFragment.resolveBinding();
2766    }
2767    return variableDeclarationFragment;
2768  }
2769
2770  private FieldDeclaration convertToFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
2771    VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
2772    FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(variableDeclarationFragment);
2773    if (this.resolveBindings) {
2774      recordNodes(variableDeclarationFragment, fieldDecl);
2775      variableDeclarationFragment.resolveBinding();
2776    }
2777    fieldDeclaration.setSourceRange(fieldDecl.declarationSourceStart, fieldDecl.declarationEnd - fieldDecl.declarationSourceStart + 1);
2778    Type type = convertType(fieldDecl.type);
2779    setTypeForField(fieldDeclaration, type, variableDeclarationFragment.getExtraDimensions());
2780    fieldDeclaration.setModifiers(fieldDecl.modifiers & org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers.AccJustFlag);
2781    convert(fieldDecl.javadoc, fieldDeclaration);
2782    return fieldDeclaration;
2783  }
2784
2785  private VariableDeclarationStatement convertToVariableDeclarationStatement(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
2786    VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
2787    VariableDeclarationStatement variableDeclarationStatement = this.ast.newVariableDeclarationStatement(variableDeclarationFragment);
2788    if (this.resolveBindings) {
2789      recordNodes(variableDeclarationFragment, localDeclaration);
2790    }
2791    variableDeclarationStatement.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
2792    Type type = convertType(localDeclaration.type);
2793    setTypeForVariableDeclarationStatement(variableDeclarationStatement, type, variableDeclarationFragment.getExtraDimensions());
2794    variableDeclarationStatement.setModifiers(localDeclaration.modifiers & ~CompilerModifiers.AccBlankFinal);
2795    return variableDeclarationStatement;
2796  }
2797  
2798  private VariableDeclarationExpression convertToVariableDeclarationExpression(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
2799    VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
2800    VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment);
2801    if (this.resolveBindings) {
2802      recordNodes(variableDeclarationFragment, localDeclaration);
2803    }
2804    variableDeclarationExpression.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
2805    Type type = convertType(localDeclaration.type);
2806    setTypeForVariableDeclarationExpression(variableDeclarationExpression, type, variableDeclarationFragment.getExtraDimensions());
2807    variableDeclarationExpression.setModifiers(localDeclaration.modifiers & ~CompilerModifiers.AccBlankFinal);
2808    return variableDeclarationExpression;
2809  }
2810  
2811  private void setTypeForField(FieldDeclaration fieldDeclaration, Type type, int extraDimension) {
2812    if (extraDimension != 0) {
2813      if (type.isArrayType()) {
2814        ArrayType arrayType = (ArrayType) type;
2815        int remainingDimensions = arrayType.getDimensions() - extraDimension;
2816        if (remainingDimensions == 0)  {
2817          // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
2818          Type elementType = arrayType.getElementType();
2819          // cut the child loose from its parent (without creating garbage)
2820          elementType.setParent(null, null);
2821          this.ast.getBindingResolver().updateKey(type, elementType);
2822          fieldDeclaration.setType(elementType);
2823        } else {
2824          int start = type.getStartPosition();
2825          int length = type.getLength();
2826          ArrayType subarrayType = arrayType;
2827          int index = extraDimension;
2828          while (index > 0) {
2829            subarrayType = (ArrayType) subarrayType.getComponentType();
2830            index--;
2831          }
2832          int end = retrieveProperRightBracketPosition(remainingDimensions, start, start + length);
2833          subarrayType.setSourceRange(start, end - start + 1);
2834          // cut the child loose from its parent (without creating garbage)
2835          subarrayType.setParent(null, null);
2836          fieldDeclaration.setType(subarrayType);
2837          updateInnerPositions(subarrayType, remainingDimensions);
2838          this.ast.getBindingResolver().updateKey(type, subarrayType);
2839        }
2840      } else {
2841        fieldDeclaration.setType(type);
2842      }
2843    } else {
2844      if (type.isArrayType()) {
2845        // update positions of the component types of the array type
2846        int dimensions = ((ArrayType) type).getDimensions();
2847        updateInnerPositions(type, dimensions);
2848      }
2849      fieldDeclaration.setType(type);
2850    }
2851  }
2852
2853  private void updateInnerPositions(Type type, int dimensions) {
2854    if (dimensions > 1) {
2855      // need to set positions for intermediate array type see 42839
2856      int start = type.getStartPosition();
2857      int length = type.getLength();
2858      Type currentComponentType = ((ArrayType) type).getComponentType();
2859      int searchedDimension = dimensions - 1;
2860      int rightBracketEndPosition = start;
2861      while (currentComponentType.isArrayType()) {
2862        rightBracketEndPosition = retrieveProperRightBracketPosition(searchedDimension, start, start + length);
2863        currentComponentType.setSourceRange(start, rightBracketEndPosition - start + 1);
2864        currentComponentType = ((ArrayType) currentComponentType).getComponentType();
2865        searchedDimension--;
2866      }    
2867    }
2868  }
2869
2870  private void setTypeForSingleVariableDeclaration(SingleVariableDeclaration singleVariableDeclaration, Type type, int extraDimension) {
2871    if (extraDimension != 0) {
2872      if (type.isArrayType()) {
2873        ArrayType arrayType = (ArrayType) type;
2874        int remainingDimensions = arrayType.getDimensions() - extraDimension;
2875        if (remainingDimensions == 0)  {
2876          // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
2877          Type elementType = arrayType.getElementType();
2878          // cut the child loose from its parent (without creating garbage)
2879          elementType.setParent(null, null);
2880          this.ast.getBindingResolver().updateKey(type, elementType);
2881          singleVariableDeclaration.setType(elementType);
2882        } else {
2883          int start = type.getStartPosition();
2884          int length = type.getLength();
2885          ArrayType subarrayType = arrayType;
2886          int index = extraDimension;
2887          while (index > 0) {
2888            subarrayType = (ArrayType) subarrayType.getComponentType();
2889            index--;
2890          }
2891          int end = retrieveProperRightBracketPosition(remainingDimensions, start, start + length);
2892          subarrayType.setSourceRange(start, end - start + 1);
2893          // cut the child loose from its parent (without creating garbage)
2894          subarrayType.setParent(null, null);
2895          updateInnerPositions(subarrayType, remainingDimensions);
2896          singleVariableDeclaration.setType(subarrayType);
2897          this.ast.getBindingResolver().updateKey(type, subarrayType);
2898        }
2899      } else {
2900        singleVariableDeclaration.setType(type);
2901      }
2902    } else {
2903      singleVariableDeclaration.setType(type);
2904    }
2905  }
2906
2907  private void setTypeForMethodDeclaration(MethodDeclaration methodDeclaration, Type type, int extraDimension) {
2908    if (extraDimension != 0) {
2909      if (type.isArrayType()) {
2910        ArrayType arrayType = (ArrayType) type;
2911        int remainingDimensions = arrayType.getDimensions() - extraDimension;
2912        if (remainingDimensions == 0)  {
2913          // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
2914          Type elementType = arrayType.getElementType();
2915          // cut the child loose from its parent (without creating garbage)
2916          elementType.setParent(null, null);
2917          this.ast.getBindingResolver().updateKey(type, elementType);
2918          methodDeclaration.setReturnType(elementType);
2919        } else {
2920          int start = type.getStartPosition();
2921          int length = type.getLength();
2922          ArrayType subarrayType = arrayType;
2923          int index = extraDimension;
2924          while (index > 0) {
2925            subarrayType = (ArrayType) subarrayType.getComponentType();
2926            index--;
2927          }
2928          int end = retrieveProperRightBracketPosition(remainingDimensions, start, start + length);
2929          subarrayType.setSourceRange(start, end - start + 1);
2930          // cut the child loose from its parent (without creating garbage)
2931          subarrayType.setParent(null, null);
2932          updateInnerPositions(subarrayType, remainingDimensions);
2933          methodDeclaration.setReturnType(subarrayType);
2934          this.ast.getBindingResolver().updateKey(type, subarrayType);
2935        }
2936      } else {
2937        methodDeclaration.setReturnType(type);
2938      }
2939    } else {
2940      methodDeclaration.setReturnType(type);
2941    }
2942  }
2943
2944  private void setTypeForVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, Type type, int extraDimension) {
2945    if (extraDimension != 0) {
2946      if (type.isArrayType()) {
2947        ArrayType arrayType = (ArrayType) type;
2948        int remainingDimensions = arrayType.getDimensions() - extraDimension;
2949        if (remainingDimensions == 0)  {
2950          // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
2951          Type elementType = arrayType.getElementType();
2952          // cut the child loose from its parent (without creating garbage)
2953          elementType.setParent(null, null);
2954          this.ast.getBindingResolver().updateKey(type, elementType);
2955          variableDeclarationStatement.setType(elementType);
2956        } else {
2957          int start = type.getStartPosition();
2958          int length = type.getLength();
2959          ArrayType subarrayType = arrayType;
2960          int index = extraDimension;
2961          while (index > 0) {
2962            subarrayType = (ArrayType) subarrayType.getComponentType();
2963            index--;
2964          }
2965          int end = retrieveProperRightBracketPosition(remainingDimensions, start, start + length);
2966          subarrayType.setSourceRange(start, end - start + 1);
2967          // cut the child loose from its parent (without creating garbage)
2968          subarrayType.setParent(null, null);
2969          updateInnerPositions(subarrayType, remainingDimensions);
2970          variableDeclarationStatement.setType(subarrayType);
2971          this.ast.getBindingResolver().updateKey(type, subarrayType);
2972        }
2973      } else {
2974        variableDeclarationStatement.setType(type);
2975      }
2976    } else {
2977      variableDeclarationStatement.setType(type);
2978    }
2979  }
2980
2981  private void setTypeForVariableDeclarationExpression(VariableDeclarationExpression variableDeclarationExpression, Type type, int extraDimension) {
2982    if (extraDimension != 0) {
2983      if (type.isArrayType()) {
2984        ArrayType arrayType = (ArrayType) type;
2985        int remainingDimensions = arrayType.getDimensions() - extraDimension;
2986        if (remainingDimensions == 0)  {
2987          // the dimensions are after the name so the type of the fieldDeclaration is a simpleType
2988          Type elementType = arrayType.getElementType();
2989          // cut the child loose from its parent (without creating garbage)
2990          elementType.setParent(null, null);
2991          this.ast.getBindingResolver().updateKey(type, elementType);
2992          variableDeclarationExpression.setType(elementType);
2993        } else {
2994          int start = type.getStartPosition();
2995          int length = type.getLength();
2996          ArrayType subarrayType = arrayType;
2997          int index = extraDimension;
2998          while (index > 0) {
2999            subarrayType = (ArrayType) subarrayType.getComponentType();
3000            index--;
3001          }
3002          int end = retrieveProperRightBracketPosition(remainingDimensions, start, start + length);
3003          subarrayType.setSourceRange(start, end - start + 1);
3004          // cut the child loose from its parent (without creating garbage)
3005          subarrayType.setParent(null, null);
3006          updateInnerPositions(subarrayType, remainingDimensions);
3007          variableDeclarationExpression.setType(subarrayType);
3008          this.ast.getBindingResolver().updateKey(type, subarrayType);
3009        }
3010      } else {
3011        variableDeclarationExpression.setType(type);
3012      }
3013    } else {
3014      variableDeclarationExpression.setType(type);
3015    }
3016  }
3017
3018  public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, BodyDeclaration bodyDeclaration) {
3019    if (bodyDeclaration.getJavadoc() == null) {
3020      if (javadoc != null) {
3021        if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
3022          this.commentMapper = new DefaultCommentMapper(this.commentsTable);
3023        }
3024        Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
3025        if (comment != null && comment.isDocComment() && comment.getParent() == null) {
3026          Javadoc docComment = (Javadoc) comment;
3027          if (this.resolveBindings) {
3028            recordNodes(docComment, javadoc);
3029            // resolve member and method references binding
3030            Iterator tags = docComment.tags().listIterator();
3031            while (tags.hasNext()) {
3032              recordNodes(javadoc, (TagElement) tags.next());
3033            }
3034          }
3035          bodyDeclaration.setJavadoc(docComment);
3036        }
3037      }
3038    }
3039  }
3040  
3041  private void recordNodes(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, TagElement tagElement) {
3042    Iterator fragments = tagElement.fragments().listIterator();
3043    int size = tagElement.fragments().size();
3044    int[] replaceIndex = new int[size];
3045    int idx = 0;
3046    while (fragments.hasNext()) {
3047      ASTNode node = (ASTNode) fragments.next();
3048      replaceIndex[idx] = 0;
3049      if (node.getNodeType() == ASTNode.MEMBER_REF) {
3050        MemberRef memberRef = (MemberRef) node;
3051        Name name = memberRef.getName();
3052        // get compiler node and record nodes
3053        int start = name.getStartPosition();
3054        org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
3055        if (compilerNode instanceof JavadocMessageSend) {
3056          replaceIndex[idx] = 1;
3057        }
3058        if (compilerNode!= null) {
3059          recordNodes(name, compilerNode);
3060          recordNodes(node, compilerNode);
3061        }
3062        // Replace qualifier to have all nodes recorded
3063        if (memberRef.getQualifier() != null) {
3064          org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
3065          if (compilerNode instanceof JavadocFieldReference) {
3066            org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocFieldReference)compilerNode).receiver;
3067            if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3068              typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
3069            }
3070          } 
3071          else if (compilerNode instanceof JavadocMessageSend) {
3072            org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocMessageSend)compilerNode).receiver;
3073            if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3074              typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
3075            }
3076          }
3077          if (typeRef != null) {
3078            recordName(memberRef.getQualifier(), typeRef);
3079          }
3080        }
3081      } else if (node.getNodeType() == ASTNode.METHOD_REF) {
3082        MethodRef methodRef = (MethodRef) node;
3083        Name name = methodRef.getName();
3084        // get compiler node and record nodes
3085        int start = name.getStartPosition();
3086        // get compiler node and record nodes
3087        org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
3088        // record nodes
3089        if (compilerNode != null) {
3090          recordNodes(methodRef, compilerNode);
3091          // get type ref
3092          org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
3093          if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression) {
3094            typeRef = ((org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression)compilerNode).type;
3095            if (typeRef != null) recordNodes(name, typeRef);
3096          } 
3097          else if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend) {
3098            org.eclipse.jdt.internal.compiler.ast.Expression expression = ((org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend)compilerNode).receiver;
3099            if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3100              typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
3101            }
3102            // TODO (frederic) remove following line to fix bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=62650
3103            recordNodes(name, compilerNode);
3104          }
3105          // record name and qualifier
3106          if (typeRef != null && methodRef.getQualifier() != null) {
3107            recordName(methodRef.getQualifier(), typeRef);
3108          }
3109        }
3110        // Resolve parameters
3111        Iterator parameters = methodRef.parameters().listIterator();
3112        while (parameters.hasNext()) {
3113          MethodRefParameter param = (MethodRefParameter) parameters.next();
3114          org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) javadoc.getNodeStartingAt(param.getStartPosition());
3115          if (expression != null) {
3116            recordNodes(param, expression);
3117            if (expression instanceof JavadocArgumentExpression) {
3118              JavadocArgumentExpression argExpr = (JavadocArgumentExpression) expression;
3119              org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = argExpr.argument.type;
3120              recordNodes(param.getType(), typeRef);
3121              if (param.getType().isSimpleType()) {
3122                SimpleType type = (SimpleType)param.getType();
3123                recordName(type.getName(), typeRef);
3124              } else if (param.getType().isArrayType()) {
3125                Type type = ((ArrayType) param.getType()).getElementType();
3126                if (type.isSimpleType()) {
3127                  recordName(((SimpleType)type).getName(), typeRef);
3128                }
3129              }
3130            }
3131          }
3132        }
3133      } else if (node.getNodeType() == ASTNode.SIMPLE_NAME ||
3134          node.getNodeType() == ASTNode.QUALIFIED_NAME) {
3135        org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(node.getStartPosition());
3136        recordName((Name) node, compilerNode);
3137      } else if (node.getNodeType() == ASTNode.TAG_ELEMENT) {
3138        // resolve member and method references binding
3139        recordNodes(javadoc, (TagElement) node);
3140      }
3141    }
3142    for (int i=0; i<size; i++) {
3143      if (replaceIndex[i] == 1) {
3144        MemberRef memberRef = (MemberRef) tagElement.fragments().remove(i);
3145        MethodRef methodRef = this.ast.newMethodRef();
3146        methodRef.setName((SimpleName)memberRef.getName().clone(this.ast));
3147        if (memberRef.getQualifier() != null) {
3148          methodRef.setQualifier((Name)memberRef.getQualifier().clone(this.ast));
3149        }
3150        methodRef.setSourceRange(memberRef.getStartPosition(), memberRef.getLength());
3151        tagElement.fragments().add(i, methodRef);
3152      }
3153    }
3154  }
3155  
3156  private void recordName(Name name, org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode) {
3157    if (compilerNode != null) {
3158      recordNodes(name, compilerNode);
3159      if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
3160        org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) compilerNode;
3161        if (name.isQualifiedName()) {
3162          int count = 0;
3163          SimpleName simpleName = null;
3164          while (name.isQualifiedName()) {
3165            simpleName = ((QualifiedName) name).getName();
3166            recordNodes(simpleName, typeRef);
3167            simpleName.index = count++;
3168            name = ((QualifiedName) name).getQualifier();
3169            name.index = count;
3170            recordNodes(name, typeRef);
3171          }
3172        }
3173      }
3174    }
3175  }
3176
3177
3178  private Comment createComment(int[] positions) {
3179    // Create comment node
3180    Comment comment = null;
3181    int start = positions[0];
3182    int end = positions[1];
3183    if (positions[1]>0) { // Javadoc comments have positive end position
3184      this.ast.newJavadoc();
3185      Javadoc docComment = this.docParser.parse(positions);
3186      if (docComment == null) return null;
3187      comment = docComment;
3188    } else {
3189      end = -end;
3190      if (positions[0]>0) { // Block comment have positive start position
3191        comment = this.ast.newBlockComment();
3192      } else { // Line comment have negative start and end position
3193        start = -start;
3194        comment = this.ast.newLineComment();
3195      }
3196      comment.setSourceRange(start, end - start);
3197    }
3198    return comment;
3199  }
3200
3201  void propagateErrors(ASTNode astNode, IProblem[] problems) {
3202    ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(problems);
3203    astNode.accept(syntaxErrorPropagator);
3204  }
3205  
3206  private void recordNodes(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
3207    this.ast.getBindingResolver().store(node, oldASTNode);
3208  }
3209  
3210  /**
3211   * Remove whitespaces and comments before and after the expression.
3212   */  
3213  private void trimWhiteSpacesAndComments(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
3214    int start = expression.sourceStart;
3215    int end = expression.sourceEnd;
3216    int token;
3217    int trimLeftPosition = expression.sourceStart;
3218    int trimRightPosition = expression.sourceEnd;
3219    boolean first = true;
3220    Scanner removeBlankScanner = this.ast.scanner;
3221    try {
3222      removeBlankScanner.setSource(this.compilationUnitSource);
3223      removeBlankScanner.resetTo(start, end);
3224      while (true) {
3225        token = removeBlankScanner.getNextToken();
3226        switch (token) {
3227          case TerminalTokens.TokenNameCOMMENT_JAVADOC :
3228          case TerminalTokens.TokenNameCOMMENT_LINE :
3229          case TerminalTokens.TokenNameCOMMENT_BLOCK :
3230            if (first) {
3231              trimLeftPosition = removeBlankScanner.currentPosition;
3232            }
3233            break;
3234          case TerminalTokens.TokenNameWHITESPACE :
3235            if (first) {
3236              trimLeftPosition = removeBlankScanner.currentPosition;
3237            }
3238            break;
3239          case TerminalTokens.TokenNameEOF :
3240            expression.sourceStart = trimLeftPosition;
3241            expression.sourceEnd = trimRightPosition;
3242            return;
3243          default :
3244            /*
3245             * if we find something else than a whitespace or a comment,
3246             * then we reset the trimRigthPosition to the expression
3247             * source end.
3248             */
3249            trimRightPosition = removeBlankScanner.currentPosition - 1;
3250            first = false;        
3251        }
3252      }
3253    } catch (InvalidInputException e){
3254      // ignore
3255    }
3256  }
3257  
3258  private void adjustSourcePositionsForParent(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
3259    int start = expression.sourceStart;
3260    int end = expression.sourceEnd;
3261    int leftParentCount = 1;
3262    int rightParentCount = 0;
3263    this.scanner.resetTo(start, end);
3264    try {
3265      int token = this.scanner.getNextToken();
3266      expression.sourceStart = this.scanner.currentPosition;
3267      boolean stop = false;
3268      while (!stop && ((token  = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) {
3269        switch(token) {
3270          case TerminalTokens.TokenNameLPAREN:
3271            leftParentCount++;
3272            break;
3273          case TerminalTokens.TokenNameRPAREN:
3274            rightParentCount++;
3275            if (rightParentCount == leftParentCount) {
3276              // we found the matching parenthesis
3277              stop = true;
3278            }
3279        }
3280      }
3281      expression.sourceEnd = this.scanner.startPosition - 1;
3282    } catch(InvalidInputException e) {
3283      // ignore
3284    }
3285  }
3286
3287  private void retrieveIdentifierAndSetPositions(int start, int end, Name name) {
3288    this.scanner.resetTo(start, end);
3289    int token;
3290    try {
3291      while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
3292        if (token == TerminalTokens.TokenNameIdentifier) {
3293          int startName = this.scanner.startPosition;
3294          int endName = this.scanner.currentPosition - 1;
3295          name.setSourceRange(startName, endName - startName + 1);
3296          return;
3297        }
3298      }
3299    } catch(InvalidInputException e) {
3300      // ignore
3301    }
3302  }
3303  
3304  /**
3305   * Remove potential trailing comment by settings the source end on the closing parenthesis
3306   */
3307  private void removeTrailingCommentFromExpressionEndingWithAParen(ASTNode node) {
3308    int start = node.getStartPosition();
3309    this.scanner.resetTo(start, start + node.getLength());
3310    int token;
3311    int parenCounter = 0;
3312    try {
3313      while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
3314        switch(token) {
3315          case TerminalTokens.TokenNameLPAREN :
3316            parenCounter++;
3317            break;
3318          case TerminalTokens.TokenNameRPAREN :
3319            parenCounter--;
3320            if (parenCounter == 0) {
3321              int end = this.scanner.currentPosition - 1;
3322              node.setSourceRange(start, end - start + 1);
3323            }
3324        }
3325      }
3326    } catch(InvalidInputException e) {
3327      // ignore
3328    }
3329  }
3330
3331  /**
3332   * Remove potential trailing comment by settings the source end on the closing parenthesis
3333   */
3334  private void removeLeadingAndTrailingCommentsFromLiteral(ASTNode node) {
3335    int start = node.getStartPosition();
3336    this.scanner.resetTo(start, start + node.getLength());
3337    int token;
3338    int startPosition = -1;
3339    try {
3340      while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
3341        switch(token) {
3342          case TerminalTokens.TokenNameIntegerLiteral :
3343          case TerminalTokens.TokenNameFloatingPointLiteral :
3344          case TerminalTokens.TokenNameLongLiteral :
3345          case TerminalTokens.TokenNameDoubleLiteral :
3346          case TerminalTokens.TokenNameCharacterLiteral :
3347            if (startPosition == -1) {
3348              startPosition = this.scanner.startPosition;
3349            }
3350            int end = this.scanner.currentPosition;
3351            node.setSourceRange(startPosition, end - startPosition);
3352            return;
3353          case TerminalTokens.TokenNameMINUS :
3354            startPosition = this.scanner.startPosition;
3355            break;
3356        }
3357      }
3358    } catch(InvalidInputException e) {
3359      // ignore
3360    }
3361  }
3362  
3363  private void recordPendingThisExpressionScopeResolution(ThisExpression thisExpression) {
3364    if (this.pendingThisExpressionScopeResolution == null) {
3365      this.pendingThisExpressionScopeResolution = new HashSet();
3366    }
3367    this.pendingThisExpressionScopeResolution.add(thisExpression);
3368  }
3369  
3370  private void recordPendingNameScopeResolution(Name name) {
3371    if (this.pendingNameScopeResolution == null) {
3372      this.pendingNameScopeResolution = new HashSet();
3373    }
3374    this.pendingNameScopeResolution.add(name);
3375  }
3376  
3377  private void lookupForScopes() {
3378    if (this.pendingNameScopeResolution != null) {
3379      for (Iterator iterator = this.pendingNameScopeResolution.iterator(); iterator.hasNext(); ) {
3380        Name name = (Name) iterator.next();
3381        this.ast.getBindingResolver().recordScope(name, lookupScope(name));
3382      }
3383    }
3384    if (this.pendingThisExpressionScopeResolution != null) {
3385      for (Iterator iterator = this.pendingThisExpressionScopeResolution.iterator(); iterator.hasNext(); ) {
3386        ThisExpression thisExpression = (ThisExpression) iterator.next();
3387        this.ast.getBindingResolver().recordScope(thisExpression, lookupScope(thisExpression));
3388      }
3389    }
3390    
3391  }
3392  
3393  private BlockScope lookupScope(ASTNode node) {
3394    ASTNode currentNode = node;
3395    while(currentNode != null
3396      &&!(currentNode instanceof MethodDeclaration)
3397      && !(currentNode instanceof Initializer)
3398      && !(currentNode instanceof FieldDeclaration)) {
3399      currentNode = currentNode.getParent();
3400    }
3401    if (currentNode == null) {
3402      return null;
3403    }
3404    if (currentNode instanceof Initializer) {
3405      Initializer initializer = (Initializer) currentNode;
3406      while(!(currentNode instanceof TypeDeclaration)) {
3407        currentNode = currentNode.getParent();
3408      }
3409      org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3410      if ((initializer.getModifiers() & Modifier.STATIC) != 0) {
3411        return typeDecl.staticInitializerScope;
3412      } else {
3413        return typeDecl.initializerScope;
3414      }
3415    } else if (currentNode instanceof FieldDeclaration) {
3416      FieldDeclaration fieldDeclaration = (FieldDeclaration) currentNode;
3417      while(!(currentNode instanceof TypeDeclaration)) {
3418        currentNode = currentNode.getParent();
3419      }
3420      org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3421      if ((fieldDeclaration.getModifiers() & Modifier.STATIC) != 0) {
3422        return typeDecl.staticInitializerScope;
3423      } else {
3424        return typeDecl.initializerScope;
3425      }
3426    }
3427    AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
3428    return abstractMethodDeclaration.scope;
3429  }
3430
3431  private InfixExpression.Operator getOperatorFor(int operatorID) {
3432    switch (operatorID) {
3433      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
3434        return InfixExpression.Operator.EQUALS;
3435      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
3436        return InfixExpression.Operator.LESS_EQUALS;
3437      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
3438        return InfixExpression.Operator.GREATER_EQUALS;
3439      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
3440        return InfixExpression.Operator.NOT_EQUALS;
3441      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
3442        return InfixExpression.Operator.LEFT_SHIFT;
3443      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
3444        return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
3445      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
3446        return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
3447      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR_OR :
3448        return InfixExpression.Operator.CONDITIONAL_OR;
3449      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND_AND :
3450        return InfixExpression.Operator.CONDITIONAL_AND;
3451      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
3452        return InfixExpression.Operator.PLUS;
3453      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
3454        return InfixExpression.Operator.MINUS;
3455      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
3456        return InfixExpression.Operator.REMAINDER;
3457      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
3458        return InfixExpression.Operator.XOR;
3459      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
3460        return InfixExpression.Operator.AND;
3461      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
3462        return InfixExpression.Operator.TIMES;
3463      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
3464        return InfixExpression.Operator.OR;
3465      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
3466        return InfixExpression.Operator.DIVIDE;
3467      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER :
3468        return InfixExpression.Operator.GREATER;
3469      case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS :
3470        return InfixExpression.Operator.LESS;
3471    }
3472    return null;
3473  }
3474}
3475