KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > codemanipulation > StubUtility2


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.codemanipulation;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.CoreException;
22
23 import org.eclipse.jdt.core.Flags;
24 import org.eclipse.jdt.core.ICompilationUnit;
25 import org.eclipse.jdt.core.JavaCore;
26 import org.eclipse.jdt.core.NamingConventions;
27 import org.eclipse.jdt.core.dom.AST;
28 import org.eclipse.jdt.core.dom.ASTNode;
29 import org.eclipse.jdt.core.dom.Annotation;
30 import org.eclipse.jdt.core.dom.Assignment;
31 import org.eclipse.jdt.core.dom.Block;
32 import org.eclipse.jdt.core.dom.Expression;
33 import org.eclipse.jdt.core.dom.FieldAccess;
34 import org.eclipse.jdt.core.dom.IBinding;
35 import org.eclipse.jdt.core.dom.IMethodBinding;
36 import org.eclipse.jdt.core.dom.IPackageBinding;
37 import org.eclipse.jdt.core.dom.ITypeBinding;
38 import org.eclipse.jdt.core.dom.IVariableBinding;
39 import org.eclipse.jdt.core.dom.Javadoc;
40 import org.eclipse.jdt.core.dom.MethodDeclaration;
41 import org.eclipse.jdt.core.dom.MethodInvocation;
42 import org.eclipse.jdt.core.dom.Modifier;
43 import org.eclipse.jdt.core.dom.ParameterizedType;
44 import org.eclipse.jdt.core.dom.PrimitiveType;
45 import org.eclipse.jdt.core.dom.ReturnStatement;
46 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
47 import org.eclipse.jdt.core.dom.Statement;
48 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
49 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
50 import org.eclipse.jdt.core.dom.Type;
51 import org.eclipse.jdt.core.dom.TypeParameter;
52 import org.eclipse.jdt.core.dom.WildcardType;
53 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
54 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
55 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
56
57 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
58 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
59 import org.eclipse.jdt.internal.corext.dom.Bindings;
60 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
61
62 import org.eclipse.jdt.ui.CodeGeneration;
63
64 /**
65  * Utilities for code generation based on ast rewrite.
66  *
67  * @since 3.1
68  */

69 public final class StubUtility2 {
70
71     public static void addOverrideAnnotation(ASTRewrite rewrite, MethodDeclaration decl, IMethodBinding binding) {
72         String JavaDoc version= binding.getJavaElement().getJavaProject().getOption(JavaCore.COMPILER_COMPLIANCE, true);
73         if (!binding.getDeclaringClass().isInterface() || !JavaModelUtil.isVersionLessThan(version, JavaCore.VERSION_1_6)) {
74             final Annotation marker= rewrite.getAST().newMarkerAnnotation();
75             marker.setTypeName(rewrite.getAST().newSimpleName("Override")); //$NON-NLS-1$
76
rewrite.getListRewrite(decl, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(marker, null);
77         }
78     }
79
80     public static MethodDeclaration createConstructorStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, IMethodBinding binding, String JavaDoc type, int modifiers, boolean omitSuperForDefConst, boolean todo, CodeGenerationSettings settings) throws CoreException {
81         AST ast= rewrite.getAST();
82         MethodDeclaration decl= ast.newMethodDeclaration();
83         decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifiers & ~Modifier.ABSTRACT & ~Modifier.NATIVE));
84         decl.setName(ast.newSimpleName(type));
85         decl.setConstructor(true);
86
87         ITypeBinding[] typeParams= binding.getTypeParameters();
88         List JavaDoc typeParameters= decl.typeParameters();
89         for (int i= 0; i < typeParams.length; i++) {
90             ITypeBinding curr= typeParams[i];
91             TypeParameter newTypeParam= ast.newTypeParameter();
92             newTypeParam.setName(ast.newSimpleName(curr.getName()));
93             ITypeBinding[] typeBounds= curr.getTypeBounds();
94             if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) {//$NON-NLS-1$
95
List JavaDoc newTypeBounds= newTypeParam.typeBounds();
96                 for (int k= 0; k < typeBounds.length; k++) {
97                     newTypeBounds.add(imports.addImport(typeBounds[k], ast));
98                 }
99             }
100             typeParameters.add(newTypeParam);
101         }
102
103         List JavaDoc parameters= createParameters(unit, imports, ast, binding, decl, null);
104
105         List JavaDoc thrownExceptions= decl.thrownExceptions();
106         ITypeBinding[] excTypes= binding.getExceptionTypes();
107         for (int i= 0; i < excTypes.length; i++) {
108             String JavaDoc excTypeName= imports.addImport(excTypes[i]);
109             thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName));
110         }
111
112         Block body= ast.newBlock();
113         decl.setBody(body);
114
115         String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(unit);
116         String JavaDoc bodyStatement= ""; //$NON-NLS-1$
117
if (!omitSuperForDefConst || !parameters.isEmpty()) {
118             SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation();
119             SingleVariableDeclaration varDecl= null;
120             for (Iterator JavaDoc iterator= parameters.iterator(); iterator.hasNext();) {
121                 varDecl= (SingleVariableDeclaration) iterator.next();
122                 invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier()));
123             }
124             bodyStatement= ASTNodes.asFormattedString(invocation, 0, delimiter, unit.getJavaProject().getOptions(true));
125         }
126
127         if (todo) {
128             String JavaDoc placeHolder= CodeGeneration.getMethodBodyContent(unit, type, binding.getName(), true, bodyStatement, delimiter);
129             if (placeHolder != null) {
130                 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
131                 body.statements().add(todoNode);
132             }
133         } else {
134             ASTNode statementNode= rewrite.createStringPlaceholder(bodyStatement, ASTNode.RETURN_STATEMENT);
135             body.statements().add(statementNode);
136         }
137
138         if (settings != null && settings.createComments) {
139             String JavaDoc string= CodeGeneration.getMethodComment(unit, type, decl, binding, delimiter);
140             if (string != null) {
141                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
142                 decl.setJavadoc(javadoc);
143             }
144         }
145         return decl;
146     }
147
148     public static MethodDeclaration createConstructorStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, ITypeBinding typeBinding, AST ast, IMethodBinding superConstructor, IVariableBinding[] variableBindings, int modifiers, CodeGenerationSettings settings) throws CoreException {
149
150         MethodDeclaration decl= ast.newMethodDeclaration();
151         decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifiers & ~Modifier.ABSTRACT & ~Modifier.NATIVE));
152         decl.setName(ast.newSimpleName(typeBinding.getName()));
153         decl.setConstructor(true);
154
155         List JavaDoc parameters= decl.parameters();
156         if (superConstructor != null) {
157             ITypeBinding[] typeParams= superConstructor.getTypeParameters();
158             List JavaDoc typeParameters= decl.typeParameters();
159             for (int i= 0; i < typeParams.length; i++) {
160                 ITypeBinding curr= typeParams[i];
161                 TypeParameter newTypeParam= ast.newTypeParameter();
162                 newTypeParam.setName(ast.newSimpleName(curr.getName()));
163                 ITypeBinding[] typeBounds= curr.getTypeBounds();
164                 if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) {//$NON-NLS-1$
165
List JavaDoc newTypeBounds= newTypeParam.typeBounds();
166                     for (int k= 0; k < typeBounds.length; k++) {
167                         newTypeBounds.add(imports.addImport(typeBounds[k], ast));
168                     }
169                 }
170                 typeParameters.add(newTypeParam);
171             }
172
173             createParameters(unit, imports, ast, superConstructor, decl, null);
174
175             List JavaDoc thrownExceptions= decl.thrownExceptions();
176             ITypeBinding[] excTypes= superConstructor.getExceptionTypes();
177             for (int i= 0; i < excTypes.length; i++) {
178                 String JavaDoc excTypeName= imports.addImport(excTypes[i]);
179                 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName));
180             }
181         }
182
183         Block body= ast.newBlock();
184         decl.setBody(body);
185
186         String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(unit);
187
188         if (superConstructor != null) {
189             SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation();
190             SingleVariableDeclaration varDecl= null;
191             for (Iterator JavaDoc iterator= parameters.iterator(); iterator.hasNext();) {
192                 varDecl= (SingleVariableDeclaration) iterator.next();
193                 invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier()));
194             }
195             body.statements().add(invocation);
196         }
197
198         List JavaDoc prohibited= new ArrayList JavaDoc();
199         for (final Iterator JavaDoc iterator= parameters.iterator(); iterator.hasNext();)
200             prohibited.add(((SingleVariableDeclaration) iterator.next()).getName().getIdentifier());
201         String JavaDoc param= null;
202         List JavaDoc list= new ArrayList JavaDoc(prohibited);
203         String JavaDoc[] excluded= null;
204         for (int i= 0; i < variableBindings.length; i++) {
205             SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
206             var.setType(imports.addImport(variableBindings[i].getType(), ast));
207             excluded= new String JavaDoc[list.size()];
208             list.toArray(excluded);
209             param= getParameterName(unit, variableBindings[i], excluded);
210             list.add(param);
211             var.setName(ast.newSimpleName(param));
212             parameters.add(var);
213         }
214
215         list= new ArrayList JavaDoc(prohibited);
216         for (int i= 0; i < variableBindings.length; i++) {
217             excluded= new String JavaDoc[list.size()];
218             list.toArray(excluded);
219             final String JavaDoc paramName= getParameterName(unit, variableBindings[i], excluded);
220             list.add(paramName);
221             final String JavaDoc fieldName= variableBindings[i].getName();
222             Expression expression= null;
223             if (paramName.equals(fieldName) || settings.useKeywordThis) {
224                 FieldAccess access= ast.newFieldAccess();
225                 access.setExpression(ast.newThisExpression());
226                 access.setName(ast.newSimpleName(fieldName));
227                 expression= access;
228             } else
229                 expression= ast.newSimpleName(fieldName);
230             Assignment assignment= ast.newAssignment();
231             assignment.setLeftHandSide(expression);
232             assignment.setRightHandSide(ast.newSimpleName(paramName));
233             assignment.setOperator(Assignment.Operator.ASSIGN);
234             body.statements().add(ast.newExpressionStatement(assignment));
235         }
236
237         if (settings != null && settings.createComments) {
238             String JavaDoc string= CodeGeneration.getMethodComment(unit, typeBinding.getName(), decl, superConstructor, delimiter);
239             if (string != null) {
240                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
241                 decl.setJavadoc(javadoc);
242             }
243         }
244         return decl;
245     }
246
247     public static MethodDeclaration createDelegationStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, AST ast, IBinding[] bindings, CodeGenerationSettings settings) throws CoreException {
248         Assert.isNotNull(bindings);
249         Assert.isNotNull(settings);
250         Assert.isTrue(bindings.length == 2);
251         Assert.isTrue(bindings[0] instanceof IVariableBinding);
252         Assert.isTrue(bindings[1] instanceof IMethodBinding);
253
254         IVariableBinding variableBinding= (IVariableBinding) bindings[0];
255         IMethodBinding methodBinding= (IMethodBinding) bindings[1];
256
257         MethodDeclaration decl= ast.newMethodDeclaration();
258         decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, methodBinding.getModifiers() & ~Modifier.SYNCHRONIZED & ~Modifier.ABSTRACT & ~Modifier.NATIVE));
259
260         decl.setName(ast.newSimpleName(methodBinding.getName()));
261         decl.setConstructor(false);
262
263         ITypeBinding[] typeParams= methodBinding.getTypeParameters();
264         List JavaDoc typeParameters= decl.typeParameters();
265         for (int i= 0; i < typeParams.length; i++) {
266             ITypeBinding curr= typeParams[i];
267             TypeParameter newTypeParam= ast.newTypeParameter();
268             newTypeParam.setName(ast.newSimpleName(curr.getName()));
269             ITypeBinding[] typeBounds= curr.getTypeBounds();
270             if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) {//$NON-NLS-1$
271
List JavaDoc newTypeBounds= newTypeParam.typeBounds();
272                 for (int k= 0; k < typeBounds.length; k++) {
273                     newTypeBounds.add(imports.addImport(typeBounds[k], ast));
274                 }
275             }
276             typeParameters.add(newTypeParam);
277         }
278
279         decl.setReturnType2(imports.addImport(methodBinding.getReturnType(), ast));
280
281         List JavaDoc parameters= decl.parameters();
282         ITypeBinding[] params= methodBinding.getParameterTypes();
283         String JavaDoc[] paramNames= StubUtility.suggestArgumentNames(unit.getJavaProject(), methodBinding);
284         for (int i= 0; i < params.length; i++) {
285             SingleVariableDeclaration varDecl= ast.newSingleVariableDeclaration();
286             if (params[i].isWildcardType() && !params[i].isUpperbound())
287                 varDecl.setType(imports.addImport(params[i].getBound(), ast));
288             else {
289                 if (methodBinding.isVarargs() && params[i].isArray() && i == params.length - 1) {
290                     StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(imports.addImport(params[i].getElementType()));
291                     for (int dim= 1; dim < params[i].getDimensions(); dim++)
292                         buffer.append("[]"); //$NON-NLS-1$
293
varDecl.setType(ASTNodeFactory.newType(ast, buffer.toString()));
294                     varDecl.setVarargs(true);
295                 } else
296                     varDecl.setType(imports.addImport(params[i], ast));
297             }
298             varDecl.setName(ast.newSimpleName(paramNames[i]));
299             parameters.add(varDecl);
300         }
301
302         List JavaDoc thrownExceptions= decl.thrownExceptions();
303         ITypeBinding[] excTypes= methodBinding.getExceptionTypes();
304         for (int i= 0; i < excTypes.length; i++) {
305             String JavaDoc excTypeName= imports.addImport(excTypes[i]);
306             thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName));
307         }
308
309         Block body= ast.newBlock();
310         decl.setBody(body);
311
312         String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(unit);
313
314         Statement statement= null;
315         MethodInvocation invocation= ast.newMethodInvocation();
316         invocation.setName(ast.newSimpleName(methodBinding.getName()));
317         List JavaDoc arguments= invocation.arguments();
318         for (int i= 0; i < params.length; i++)
319             arguments.add(ast.newSimpleName(paramNames[i]));
320         if (settings.useKeywordThis) {
321             FieldAccess access= ast.newFieldAccess();
322             access.setExpression(ast.newThisExpression());
323             access.setName(ast.newSimpleName(variableBinding.getName()));
324             invocation.setExpression(access);
325         } else
326             invocation.setExpression(ast.newSimpleName(variableBinding.getName()));
327         if (methodBinding.getReturnType().isPrimitive() && methodBinding.getReturnType().getName().equals("void")) {//$NON-NLS-1$
328
statement= ast.newExpressionStatement(invocation);
329         } else {
330             ReturnStatement returnStatement= ast.newReturnStatement();
331             returnStatement.setExpression(invocation);
332             statement= returnStatement;
333         }
334         body.statements().add(statement);
335
336         ITypeBinding declaringType= variableBinding.getDeclaringClass();
337         if (declaringType == null) { // can be null for
338
return decl;
339         }
340
341         String JavaDoc qualifiedName= declaringType.getQualifiedName();
342         IPackageBinding packageBinding= declaringType.getPackage();
343         if (packageBinding != null) {
344             if (packageBinding.getName().length() > 0 && qualifiedName.startsWith(packageBinding.getName()))
345                 qualifiedName= qualifiedName.substring(packageBinding.getName().length());
346         }
347
348         if (settings.createComments) {
349             /*
350              * TODO: have API for delegate method comments This is an inlined
351              * version of
352              * {@link CodeGeneration#getMethodComment(ICompilationUnit, String, MethodDeclaration, IMethodBinding, String)}
353              */

354             methodBinding= methodBinding.getMethodDeclaration();
355             String JavaDoc declaringClassQualifiedName= methodBinding.getDeclaringClass().getQualifiedName();
356             String JavaDoc linkToMethodName= methodBinding.getName();
357             String JavaDoc[] parameterTypesQualifiedNames= StubUtility.getParameterTypeNamesForSeeTag(methodBinding);
358             String JavaDoc string= StubUtility.getMethodComment(unit, qualifiedName, decl, methodBinding.isDeprecated(), linkToMethodName, declaringClassQualifiedName, parameterTypesQualifiedNames, true, delimiter);
359             if (string != null) {
360                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
361                 decl.setJavadoc(javadoc);
362             }
363         }
364         return decl;
365     }
366
367     public static MethodDeclaration createImplementationStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, AST ast, IMethodBinding binding, String JavaDoc type, CodeGenerationSettings settings, boolean deferred, ImportRewriteContext context) throws CoreException {
368
369         MethodDeclaration decl= ast.newMethodDeclaration();
370         decl.modifiers().addAll(getImplementationModifiers(ast, binding, deferred));
371
372         decl.setName(ast.newSimpleName(binding.getName()));
373         decl.setConstructor(false);
374
375         ITypeBinding[] typeParams= binding.getTypeParameters();
376         List JavaDoc typeParameters= decl.typeParameters();
377         for (int i= 0; i < typeParams.length; i++) {
378             ITypeBinding curr= typeParams[i];
379             TypeParameter newTypeParam= ast.newTypeParameter();
380             newTypeParam.setName(ast.newSimpleName(curr.getName()));
381             ITypeBinding[] typeBounds= curr.getTypeBounds();
382             if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) {//$NON-NLS-1$
383
List JavaDoc newTypeBounds= newTypeParam.typeBounds();
384                 for (int k= 0; k < typeBounds.length; k++) {
385                     newTypeBounds.add(imports.addImport(typeBounds[k], ast, context));
386                 }
387             }
388             typeParameters.add(newTypeParam);
389         }
390
391         decl.setReturnType2(imports.addImport(binding.getReturnType(), ast, context));
392
393         List JavaDoc parameters= createParameters(unit, imports, ast, binding, decl, context);
394
395         List JavaDoc thrownExceptions= decl.thrownExceptions();
396         ITypeBinding[] excTypes= binding.getExceptionTypes();
397         for (int i= 0; i < excTypes.length; i++) {
398             String JavaDoc excTypeName= imports.addImport(excTypes[i], context);
399             thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName));
400         }
401
402         String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(unit);
403         if (!deferred) {
404             Map JavaDoc options= unit.getJavaProject().getOptions(true);
405
406             Block body= ast.newBlock();
407             decl.setBody(body);
408
409             String JavaDoc bodyStatement= ""; //$NON-NLS-1$
410
ITypeBinding declaringType= binding.getDeclaringClass();
411             if (Modifier.isAbstract(binding.getModifiers()) || declaringType.isAnnotation() || declaringType.isInterface()) {
412                 Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions());
413                 if (expression != null) {
414                     ReturnStatement returnStatement= ast.newReturnStatement();
415                     returnStatement.setExpression(expression);
416                     bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options);
417                 }
418             } else {
419                 SuperMethodInvocation invocation= ast.newSuperMethodInvocation();
420                 invocation.setName(ast.newSimpleName(binding.getName()));
421                 SingleVariableDeclaration varDecl= null;
422                 for (Iterator JavaDoc iterator= parameters.iterator(); iterator.hasNext();) {
423                     varDecl= (SingleVariableDeclaration) iterator.next();
424                     invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier()));
425                 }
426                 Expression expression= invocation;
427                 Type returnType= decl.getReturnType2();
428                 if (returnType != null && (returnType instanceof PrimitiveType) && ((PrimitiveType) returnType).getPrimitiveTypeCode().equals(PrimitiveType.VOID)) {
429                     bodyStatement= ASTNodes.asFormattedString(ast.newExpressionStatement(expression), 0, delimiter, options);
430                 } else {
431                     ReturnStatement returnStatement= ast.newReturnStatement();
432                     returnStatement.setExpression(expression);
433                     bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options);
434                 }
435             }
436
437             String JavaDoc placeHolder= CodeGeneration.getMethodBodyContent(unit, type, binding.getName(), false, bodyStatement, delimiter);
438             if (placeHolder != null) {
439                 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
440                 body.statements().add(todoNode);
441             }
442         }
443
444         if (settings.createComments) {
445             String JavaDoc string= CodeGeneration.getMethodComment(unit, type, decl, binding, delimiter);
446             if (string != null) {
447                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
448                 decl.setJavadoc(javadoc);
449             }
450         }
451         if (settings.overrideAnnotation && JavaModelUtil.is50OrHigher(unit.getJavaProject())) {
452             addOverrideAnnotation(rewrite, decl, binding);
453         }
454
455         return decl;
456     }
457
458     public static MethodDeclaration createImplementationStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite importRewrite, IMethodBinding binding, String JavaDoc type, boolean deferred, CodeGenerationSettings settings) throws CoreException {
459         AST ast= rewrite.getAST();
460         MethodDeclaration decl= ast.newMethodDeclaration();
461         decl.modifiers().addAll(getImplementationModifiers(ast, binding, deferred));
462
463         decl.setName(ast.newSimpleName(binding.getName()));
464         decl.setConstructor(false);
465
466         ITypeBinding[] typeParams= binding.getTypeParameters();
467         List JavaDoc typeParameters= decl.typeParameters();
468         for (int index= 0; index < typeParams.length; index++) {
469             ITypeBinding curr= typeParams[index];
470             TypeParameter newTypeParam= ast.newTypeParameter();
471             newTypeParam.setName(ast.newSimpleName(curr.getName()));
472             ITypeBinding[] typeBounds= curr.getTypeBounds();
473             if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) {//$NON-NLS-1$
474
List JavaDoc newTypeBounds= newTypeParam.typeBounds();
475                 for (int offset= 0; offset < typeBounds.length; offset++) {
476                     newTypeBounds.add(createTypeNode(importRewrite, typeBounds[offset], ast));
477                 }
478             }
479             typeParameters.add(newTypeParam);
480         }
481
482         decl.setReturnType2(createTypeNode(importRewrite, binding.getReturnType(), ast));
483
484         List JavaDoc parameters= createParameters(unit, importRewrite, ast, binding, decl);
485
486         List JavaDoc thrownExceptions= decl.thrownExceptions();
487         ITypeBinding[] excTypes= binding.getExceptionTypes();
488         for (int index= 0; index < excTypes.length; index++)
489             thrownExceptions.add(ASTNodeFactory.newName(ast, importRewrite != null ? importRewrite.addImport(excTypes[index]) : excTypes[index].getQualifiedName()));
490
491         String JavaDoc delimiter= StubUtility.getLineDelimiterUsed(unit);
492         if (!deferred) {
493             Map JavaDoc options= unit.getJavaProject().getOptions(true);
494             
495             Block body= ast.newBlock();
496             decl.setBody(body);
497
498             String JavaDoc bodyStatement= ""; //$NON-NLS-1$
499
ITypeBinding declaringType= binding.getDeclaringClass();
500             if (Modifier.isAbstract(binding.getModifiers()) || declaringType.isAnnotation() || declaringType.isInterface()) {
501                 Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions());
502                 if (expression != null) {
503                     ReturnStatement returnStatement= ast.newReturnStatement();
504                     returnStatement.setExpression(expression);
505                     bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options);
506                 }
507             } else {
508                 SuperMethodInvocation invocation= ast.newSuperMethodInvocation();
509                 invocation.setName(ast.newSimpleName(binding.getName()));
510                 SingleVariableDeclaration varDecl= null;
511                 for (Iterator JavaDoc iterator= parameters.iterator(); iterator.hasNext();) {
512                     varDecl= (SingleVariableDeclaration) iterator.next();
513                     invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier()));
514                 }
515                 Expression expression= invocation;
516                 Type returnType= decl.getReturnType2();
517                 if (returnType instanceof PrimitiveType && ((PrimitiveType) returnType).getPrimitiveTypeCode().equals(PrimitiveType.VOID)) {
518                     bodyStatement= ASTNodes.asFormattedString(ast.newExpressionStatement(expression), 0, delimiter, options);
519                 } else {
520                     ReturnStatement returnStatement= ast.newReturnStatement();
521                     returnStatement.setExpression(expression);
522                     bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options);
523                 }
524             }
525
526             String JavaDoc placeHolder= CodeGeneration.getMethodBodyContent(unit, type, binding.getName(), false, bodyStatement, delimiter);
527             if (placeHolder != null) {
528                 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
529                 body.statements().add(todoNode);
530             }
531         }
532
533         if (settings != null && settings.createComments) {
534             String JavaDoc string= CodeGeneration.getMethodComment(unit, type, decl, binding, delimiter);
535             if (string != null) {
536                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
537                 decl.setJavadoc(javadoc);
538             }
539         }
540         if (settings != null && settings.overrideAnnotation && JavaModelUtil.is50OrHigher(unit.getJavaProject())) {
541             addOverrideAnnotation(rewrite, decl, binding);
542         }
543         return decl;
544     }
545
546     private static List JavaDoc createParameters(ICompilationUnit unit, ImportRewrite imports, AST ast, IMethodBinding binding, MethodDeclaration decl, ImportRewriteContext context) {
547         List JavaDoc parameters= decl.parameters();
548         ITypeBinding[] params= binding.getParameterTypes();
549         String JavaDoc[] paramNames= StubUtility.suggestArgumentNames(unit.getJavaProject(), binding);
550         for (int i= 0; i < params.length; i++) {
551             SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
552             if (binding.isVarargs() && params[i].isArray() && i == params.length - 1) {
553                 StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(imports.addImport(params[i].getElementType(), context));
554                 for (int dim= 1; dim < params[i].getDimensions(); dim++)
555                     buffer.append("[]"); //$NON-NLS-1$
556
var.setType(ASTNodeFactory.newType(ast, buffer.toString()));
557                 var.setVarargs(true);
558             } else
559                 var.setType(imports.addImport(params[i], ast, context));
560             var.setName(ast.newSimpleName(paramNames[i]));
561             parameters.add(var);
562         }
563         return parameters;
564     }
565
566     private static List JavaDoc createParameters(ICompilationUnit unit, ImportRewrite imports, AST ast, IMethodBinding binding, MethodDeclaration decl) {
567         List JavaDoc parameters= decl.parameters();
568         ITypeBinding[] params= binding.getParameterTypes();
569         String JavaDoc[] paramNames= StubUtility.suggestArgumentNames(unit.getJavaProject(), binding);
570         for (int i= 0; i < params.length; i++) {
571             SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
572             if (binding.isVarargs() && params[i].isArray() && i == params.length - 1) {
573                 final ITypeBinding elementType= params[i].getElementType();
574                 StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(imports != null ? imports.addImport(elementType) : elementType.getQualifiedName());
575                 for (int dim= 1; dim < params[i].getDimensions(); dim++)
576                     buffer.append("[]"); //$NON-NLS-1$
577
var.setType(ASTNodeFactory.newType(ast, buffer.toString()));
578                 var.setVarargs(true);
579             } else
580                 var.setType(createTypeNode(imports, params[i], ast));
581             var.setName(ast.newSimpleName(paramNames[i]));
582             parameters.add(var);
583         }
584         return parameters;
585     }
586
587     private static Type createTypeNode(ImportRewrite importRewrite, ITypeBinding binding, AST ast) {
588         if (importRewrite != null)
589             return importRewrite.addImport(binding, ast);
590         return createTypeNode(binding, ast);
591     }
592
593     private static Type createTypeNode(ITypeBinding binding, AST ast) {
594         if (binding.isPrimitive())
595             return ast.newPrimitiveType(PrimitiveType.toCode(binding.getName()));
596         ITypeBinding normalized= Bindings.normalizeTypeBinding(binding);
597         if (normalized == null)
598             return ast.newSimpleType(ast.newSimpleName("invalid")); //$NON-NLS-1$
599
else if (normalized.isTypeVariable())
600             return ast.newSimpleType(ast.newSimpleName(binding.getName()));
601         else if (normalized.isWildcardType()) {
602             WildcardType type= ast.newWildcardType();
603             ITypeBinding bound= normalized.getBound();
604             if (bound != null)
605                 type.setBound(createTypeNode(bound, ast), normalized.isUpperbound());
606             return type;
607         } else if (normalized.isArray())
608             return ast.newArrayType(createTypeNode(normalized.getElementType(), ast), normalized.getDimensions());
609         String JavaDoc qualified= Bindings.getRawQualifiedName(normalized);
610         if (qualified.length() > 0) {
611             ITypeBinding[] typeArguments= normalized.getTypeArguments();
612             if (typeArguments.length > 0) {
613                 ParameterizedType type= ast.newParameterizedType(ast.newSimpleType(ASTNodeFactory.newName(ast, qualified)));
614                 List JavaDoc arguments= type.typeArguments();
615                 for (int index= 0; index < typeArguments.length; index++)
616                     arguments.add(createTypeNode(typeArguments[index], ast));
617                 return type;
618             }
619             return ast.newSimpleType(ASTNodeFactory.newName(ast, qualified));
620         }
621         return ast.newSimpleType(ASTNodeFactory.newName(ast, Bindings.getRawName(normalized)));
622     }
623
624     private static IMethodBinding findMethodBinding(IMethodBinding method, List JavaDoc allMethods) {
625         for (int i= 0; i < allMethods.size(); i++) {
626             IMethodBinding curr= (IMethodBinding) allMethods.get(i);
627             if (Bindings.isSubsignature(method, curr)) {
628                 return curr;
629             }
630         }
631         return null;
632     }
633
634     private static IMethodBinding findOverridingMethod(IMethodBinding method, List JavaDoc allMethods) {
635         for (int i= 0; i < allMethods.size(); i++) {
636             IMethodBinding curr= (IMethodBinding) allMethods.get(i);
637             if (Bindings.areOverriddenMethods(curr, method) || Bindings.isSubsignature(curr, method))
638                 return curr;
639         }
640         return null;
641     }
642
643     private static void findUnimplementedInterfaceMethods(ITypeBinding typeBinding, HashSet JavaDoc visited, ArrayList JavaDoc allMethods, IPackageBinding currPack, ArrayList JavaDoc toImplement) {
644         if (visited.add(typeBinding)) {
645             IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods();
646             for (int i= 0; i < typeMethods.length; i++) {
647                 IMethodBinding curr= typeMethods[i];
648                 IMethodBinding impl= findMethodBinding(curr, allMethods);
649                 if (impl == null || !Bindings.isVisibleInHierarchy(impl, currPack)) {
650                     if (impl != null)
651                         allMethods.remove(impl);
652                     toImplement.add(curr);
653                     allMethods.add(curr);
654                 }
655             }
656             ITypeBinding[] superInterfaces= typeBinding.getInterfaces();
657             for (int i= 0; i < superInterfaces.length; i++)
658                 findUnimplementedInterfaceMethods(superInterfaces[i], visited, allMethods, currPack, toImplement);
659         }
660     }
661
662     public static IBinding[][] getDelegatableMethods(AST ast, ITypeBinding binding) {
663         final List JavaDoc tuples= new ArrayList JavaDoc();
664         final List JavaDoc declared= new ArrayList JavaDoc();
665         IMethodBinding[] typeMethods= binding.getDeclaredMethods();
666         for (int index= 0; index < typeMethods.length; index++)
667             declared.add(typeMethods[index]);
668         IVariableBinding[] typeFields= binding.getDeclaredFields();
669         for (int index= 0; index < typeFields.length; index++) {
670             IVariableBinding fieldBinding= typeFields[index];
671             if (fieldBinding.isField() && !fieldBinding.isEnumConstant() && !fieldBinding.isSynthetic())
672                 getDelegatableMethods(ast, tuples, new ArrayList JavaDoc(declared), fieldBinding, fieldBinding.getType(), binding);
673         }
674         // list of tuple<IVariableBinding, IMethodBinding>
675
return (IBinding[][]) tuples.toArray(new IBinding[tuples.size()][2]);
676     }
677
678     private static void getDelegatableMethods(AST ast, List JavaDoc tuples, List JavaDoc methods, IVariableBinding fieldBinding, ITypeBinding typeBinding, ITypeBinding binding) {
679         boolean match= false;
680         if (typeBinding.isTypeVariable()) {
681             ITypeBinding[] typeBounds= typeBinding.getTypeBounds();
682             if (typeBounds == null || typeBounds.length == 0)
683                 typeBounds= new ITypeBinding[] { ast.resolveWellKnownType("java.lang.Object") }; //$NON-NLS-1$
684
for (int index= 0; index < typeBounds.length; index++) {
685                 IMethodBinding[] candidates= getDelegateCandidates(typeBounds[index], binding);
686                 for (int candidate= 0; candidate < candidates.length; candidate++) {
687                     match= false;
688                     final IMethodBinding methodBinding= candidates[candidate];
689                     for (int offset= 0; offset < methods.size() && !match; offset++) {
690                         if (Bindings.areOverriddenMethods((IMethodBinding) methods.get(offset), methodBinding))
691                             match= true;
692                     }
693                     if (!match) {
694                         tuples.add(new IBinding[] { fieldBinding, methodBinding });
695                         methods.add(methodBinding);
696                     }
697                 }
698                 final ITypeBinding superclass= typeBounds[index].getSuperclass();
699                 if (superclass != null)
700                     getDelegatableMethods(ast, tuples, methods, fieldBinding, superclass, binding);
701                 ITypeBinding[] superInterfaces= typeBounds[index].getInterfaces();
702                 for (int offset= 0; offset < superInterfaces.length; offset++)
703                     getDelegatableMethods(ast, tuples, methods, fieldBinding, superInterfaces[offset], binding);
704             }
705         } else {
706             IMethodBinding[] candidates= getDelegateCandidates(typeBinding, binding);
707             for (int index= 0; index < candidates.length; index++) {
708                 match= false;
709                 final IMethodBinding methodBinding= candidates[index];
710                 for (int offset= 0; offset < methods.size() && !match; offset++) {
711                     if (Bindings.areOverriddenMethods((IMethodBinding) methods.get(offset), methodBinding))
712                         match= true;
713                 }
714                 if (!match) {
715                     tuples.add(new IBinding[] { fieldBinding, methodBinding });
716                     methods.add(methodBinding);
717                 }
718             }
719             final ITypeBinding superclass= typeBinding.getSuperclass();
720             if (superclass != null)
721                 getDelegatableMethods(ast, tuples, methods, fieldBinding, superclass, binding);
722             ITypeBinding[] superInterfaces= typeBinding.getInterfaces();
723             for (int offset= 0; offset < superInterfaces.length; offset++)
724                 getDelegatableMethods(ast, tuples, methods, fieldBinding, superInterfaces[offset], binding);
725         }
726     }
727
728     private static IMethodBinding[] getDelegateCandidates(ITypeBinding binding, ITypeBinding hierarchy) {
729         List JavaDoc allMethods= new ArrayList JavaDoc();
730         boolean isInterface= binding.isInterface();
731         IMethodBinding[] typeMethods= binding.getDeclaredMethods();
732         for (int index= 0; index < typeMethods.length; index++) {
733             final int modifiers= typeMethods[index].getModifiers();
734             if (!typeMethods[index].isConstructor() && !Modifier.isStatic(modifiers) && (isInterface || Modifier.isPublic(modifiers))) {
735                 IMethodBinding result= Bindings.findOverriddenMethodInHierarchy(hierarchy, typeMethods[index]);
736                 if (result != null && Flags.isFinal(result.getModifiers()))
737                     continue;
738                 ITypeBinding[] parameterBindings= typeMethods[index].getParameterTypes();
739                 boolean upper= false;
740                 for (int offset= 0; offset < parameterBindings.length; offset++) {
741                     if (parameterBindings[offset].isWildcardType() && parameterBindings[offset].isUpperbound())
742                         upper= true;
743                 }
744                 if (!upper)
745                     allMethods.add(typeMethods[index]);
746             }
747         }
748         return (IMethodBinding[]) allMethods.toArray(new IMethodBinding[allMethods.size()]);
749     }
750
751     private static List JavaDoc getImplementationModifiers(AST ast, IMethodBinding method, boolean deferred) {
752         int modifiers= method.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE & ~Modifier.PRIVATE;
753         if (deferred) {
754             modifiers= modifiers & ~Modifier.PROTECTED;
755             modifiers= modifiers | Modifier.PUBLIC;
756         }
757         return ASTNodeFactory.newModifiers(ast, modifiers);
758     }
759
760     public static IMethodBinding[] getOverridableMethods(AST ast, ITypeBinding typeBinding, boolean isSubType) {
761         List JavaDoc allMethods= new ArrayList JavaDoc();
762         IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods();
763         for (int index= 0; index < typeMethods.length; index++) {
764             final int modifiers= typeMethods[index].getModifiers();
765             if (!typeMethods[index].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers))
766                 allMethods.add(typeMethods[index]);
767         }
768         ITypeBinding clazz= typeBinding.getSuperclass();
769         while (clazz != null) {
770             IMethodBinding[] methods= clazz.getDeclaredMethods();
771             for (int offset= 0; offset < methods.length; offset++) {
772                 final int modifiers= methods[offset].getModifiers();
773                 if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) {
774                     if (findOverridingMethod(methods[offset], allMethods) == null)
775                         allMethods.add(methods[offset]);
776                 }
777             }
778             clazz= clazz.getSuperclass();
779         }
780         clazz= typeBinding;
781         while (clazz != null) {
782             ITypeBinding[] superInterfaces= clazz.getInterfaces();
783             for (int index= 0; index < superInterfaces.length; index++) {
784                 getOverridableMethods(ast, superInterfaces[index], allMethods);
785             }
786             clazz= clazz.getSuperclass();
787         }
788         if (typeBinding.isInterface())
789             getOverridableMethods(ast, ast.resolveWellKnownType("java.lang.Object"), allMethods); //$NON-NLS-1$
790
if (!isSubType)
791             allMethods.removeAll(Arrays.asList(typeMethods));
792         int modifiers= 0;
793         if (!typeBinding.isInterface()) {
794             for (int index= allMethods.size() - 1; index >= 0; index--) {
795                 IMethodBinding method= (IMethodBinding) allMethods.get(index);
796                 modifiers= method.getModifiers();
797                 if (Modifier.isFinal(modifiers))
798                     allMethods.remove(index);
799             }
800         }
801         return (IMethodBinding[]) allMethods.toArray(new IMethodBinding[allMethods.size()]);
802     }
803
804     private static void getOverridableMethods(AST ast, ITypeBinding superBinding, List JavaDoc allMethods) {
805         IMethodBinding[] methods= superBinding.getDeclaredMethods();
806         for (int offset= 0; offset < methods.length; offset++) {
807             final int modifiers= methods[offset].getModifiers();
808             if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) {
809                 if (findOverridingMethod(methods[offset], allMethods) == null && !Modifier.isStatic(modifiers))
810                     allMethods.add(methods[offset]);
811             }
812         }
813         ITypeBinding[] superInterfaces= superBinding.getInterfaces();
814         for (int index= 0; index < superInterfaces.length; index++) {
815             getOverridableMethods(ast, superInterfaces[index], allMethods);
816         }
817     }
818
819     private static String JavaDoc getParameterName(ICompilationUnit unit, IVariableBinding binding, String JavaDoc[] excluded) {
820         final String JavaDoc name= NamingConventions.removePrefixAndSuffixForFieldName(unit.getJavaProject(), binding.getName(), binding.getModifiers());
821         return StubUtility.suggestArgumentName(unit.getJavaProject(), name, excluded);
822     }
823
824     public static IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding) {
825         ArrayList JavaDoc allMethods= new ArrayList JavaDoc();
826         ArrayList JavaDoc toImplement= new ArrayList JavaDoc();
827
828         IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods();
829         for (int i= 0; i < typeMethods.length; i++) {
830             IMethodBinding curr= typeMethods[i];
831             int modifiers= curr.getModifiers();
832             if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) {
833                 allMethods.add(curr);
834             }
835         }
836
837         ITypeBinding superClass= typeBinding.getSuperclass();
838         while (superClass != null) {
839             typeMethods= superClass.getDeclaredMethods();
840             for (int i= 0; i < typeMethods.length; i++) {
841                 IMethodBinding curr= typeMethods[i];
842                 int modifiers= curr.getModifiers();
843                 if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) {
844                     if (findMethodBinding(curr, allMethods) == null) {
845                         allMethods.add(curr);
846                     }
847                 }
848             }
849             superClass= superClass.getSuperclass();
850         }
851
852         for (int i= 0; i < allMethods.size(); i++) {
853             IMethodBinding curr= (IMethodBinding) allMethods.get(i);
854             int modifiers= curr.getModifiers();
855             if ((Modifier.isAbstract(modifiers) || curr.getDeclaringClass().isInterface()) && (typeBinding != curr.getDeclaringClass())) {
856                 // implement all abstract methods
857
toImplement.add(curr);
858             }
859         }
860
861         HashSet JavaDoc visited= new HashSet JavaDoc();
862         ITypeBinding curr= typeBinding;
863         while (curr != null) {
864             ITypeBinding[] superInterfaces= curr.getInterfaces();
865             for (int i= 0; i < superInterfaces.length; i++) {
866                 findUnimplementedInterfaceMethods(superInterfaces[i], visited, allMethods, typeBinding.getPackage(), toImplement);
867             }
868             curr= curr.getSuperclass();
869         }
870
871         return (IMethodBinding[]) toImplement.toArray(new IMethodBinding[toImplement.size()]);
872     }
873
874     public static IMethodBinding[] getVisibleConstructors(ITypeBinding binding, boolean accountExisting, boolean proposeDefault) {
875         List JavaDoc constructorMethods= new ArrayList JavaDoc();
876         List JavaDoc existingConstructors= null;
877         ITypeBinding superType= binding.getSuperclass();
878         if (superType == null)
879             return new IMethodBinding[0];
880         if (accountExisting) {
881             IMethodBinding[] methods= binding.getDeclaredMethods();
882             existingConstructors= new ArrayList JavaDoc(methods.length);
883             for (int index= 0; index < methods.length; index++) {
884                 IMethodBinding method= methods[index];
885                 if (method.isConstructor() && !method.isDefaultConstructor())
886                     existingConstructors.add(method);
887             }
888         }
889         if (existingConstructors != null)
890             constructorMethods.addAll(existingConstructors);
891         IMethodBinding[] methods= binding.getDeclaredMethods();
892         IMethodBinding[] superMethods= superType.getDeclaredMethods();
893         for (int index= 0; index < superMethods.length; index++) {
894             IMethodBinding method= superMethods[index];
895             if (method.isConstructor()) {
896                 if (Bindings.isVisibleInHierarchy(method, binding.getPackage()) && (!accountExisting || !Bindings.containsSignatureEquivalentConstructor(methods, method)))
897                     constructorMethods.add(method);
898             }
899         }
900         if (existingConstructors != null)
901             constructorMethods.removeAll(existingConstructors);
902         if (constructorMethods.isEmpty()) {
903             superType= binding;
904             while (superType.getSuperclass() != null)
905                 superType= superType.getSuperclass();
906             IMethodBinding method= Bindings.findMethodInType(superType, "Object", new ITypeBinding[0]); //$NON-NLS-1$
907
if (method != null) {
908                 if ((proposeDefault || (!accountExisting || (existingConstructors == null || existingConstructors.isEmpty()))) && (!accountExisting || !Bindings.containsSignatureEquivalentConstructor(methods, method)))
909                     constructorMethods.add(method);
910             }
911         }
912         return (IMethodBinding[]) constructorMethods.toArray(new IMethodBinding[constructorMethods.size()]);
913     }
914
915
916
917     /**
918      * Creates a new stub utility.
919      */

920     private StubUtility2() {
921         // Not for instantiation
922
}
923 }
924
Popular Tags