ca646ed368d3b120cf5e5f85fd87b0507ee6c154
[phpeclipse.git] /
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.corext.codemanipulation;
6
7 import net.sourceforge.phpdt.core.ICodeFormatter;
8 import net.sourceforge.phpdt.core.IJavaProject;
9 import net.sourceforge.phpdt.core.JavaCore;
10 import net.sourceforge.phpdt.core.ToolFactory;
11
12 import org.eclipse.jface.text.BadLocationException;
13 import org.eclipse.jface.text.IDocument;
14
15 public class StubUtility {
16         
17         
18 //      public static class GenStubSettings extends CodeGenerationSettings {
19 //      
20 //              public boolean callSuper;
21 //              public boolean methodOverwrites;
22 //              public boolean noBody;
23 //              
24 //              public GenStubSettings(CodeGenerationSettings settings) {
25 //                      settings.setSettings(this);     
26 //              }
27 //              
28 //              public GenStubSettings() {
29 //              }
30 //                      
31 //      }
32 //      
33 //
34 //      /**
35 //       * Generates a stub. Given a template method, a stub with the same signature
36 //       * will be constructed so it can be added to a type.
37 //       * @param destTypeName The name of the type to which the method will be added to (Used for the constructor)
38 //       * @param method A method template (method belongs to different type than the parent)
39 //       * @param options Options as defined above (<code>GenStubSettings</code>)
40 //       * @param imports Imports required by the stub are added to the imports structure. If imports structure is <code>null</code>
41 //       * all type names are qualified.
42 //       * @throws JavaModelException
43 //       */
44 //      public static String genStub(String destTypeName, IMethod method, GenStubSettings settings, IImportsStructure imports) throws JavaModelException {
45 //              IType declaringtype= method.getDeclaringType(); 
46 //              StringBuffer buf= new StringBuffer();
47 //              String methodName= method.getElementName();
48 //              String[] paramTypes= method.getParameterTypes();
49 //              String[] paramNames= method.getParameterNames();
50 //              String[] excTypes= method.getExceptionTypes();
51 //              String retTypeSig= method.getReturnType();
52 //              int flags= method.getFlags();
53 //              boolean isConstructor= method.isConstructor();
54 //              
55 //              int lastParam= paramTypes.length -1;            
56 //              
57 //              
58 //              if (settings.createComments) {
59 //                      if (isConstructor) {
60 //                              String desc= "Constructor for " + destTypeName; //$NON-NLS-1$
61 //                              genJavaDocStub(desc, paramNames, Signature.SIG_VOID, excTypes, buf);
62 //                      } else {                        
63 //                              // php doc
64 //                              if (settings.methodOverwrites) {
65 //                                      boolean isDeprecated= Flags.isDeprecated(flags);
66 //                                      genJavaDocSeeTag(declaringtype, methodName, paramTypes, settings.createNonJavadocComments, isDeprecated, buf);
67 //                              } else {
68 //                                      // generate a default php doc comment
69 //                                      String desc= "Method " + methodName; //$NON-NLS-1$
70 //                                      genJavaDocStub(desc, paramNames, retTypeSig, excTypes, buf);
71 //                              }
72 //                      }
73 //                      buf.append('\n');
74 //              }
75 //              
76 //              if (Flags.isPublic(flags) || isConstructor || (declaringtype.isInterface() && !settings.noBody)) {
77 //                      buf.append("public "); //$NON-NLS-1$
78 //              } else if (Flags.isProtected(flags)) {
79 //                      buf.append("protected "); //$NON-NLS-1$
80 //              } else if (Flags.isPrivate(flags)) {
81 //                      buf.append("private "); //$NON-NLS-1$
82 //              }
83 //              if (Flags.isSynchronized(flags)) {
84 //                      buf.append("synchronized "); //$NON-NLS-1$
85 //              }               
86 //              if (Flags.isVolatile(flags)) {
87 //                      buf.append("volatile "); //$NON-NLS-1$
88 //              }
89 //              if (Flags.isStrictfp(flags)) {
90 //                      buf.append("strictfp "); //$NON-NLS-1$
91 //              }
92 //              if (Flags.isStatic(flags)) {
93 //                      buf.append("static "); //$NON-NLS-1$
94 //              }               
95 //                      
96 //              if (isConstructor) {
97 //                      buf.append(destTypeName);
98 //              } else {
99 //                      String retTypeFrm;
100 //                      if (!isPrimitiveType(retTypeSig)) {
101 //                              retTypeFrm= resolveAndAdd(retTypeSig, declaringtype, imports);
102 //                      } else {
103 //                              retTypeFrm= Signature.toString(retTypeSig);
104 //                      }
105 //                      buf.append(retTypeFrm);
106 //                      buf.append(' ');
107 //                      buf.append(methodName);
108 //              }
109 //              buf.append('(');
110 //              for (int i= 0; i <= lastParam; i++) {
111 //                      String paramTypeSig= paramTypes[i];
112 //                      String paramTypeFrm;
113 //                      
114 //                      if (!isPrimitiveType(paramTypeSig)) {
115 //                              paramTypeFrm= resolveAndAdd(paramTypeSig, declaringtype, imports);
116 //                      } else {
117 //                              paramTypeFrm= Signature.toString(paramTypeSig);
118 //                      }
119 //                      buf.append(paramTypeFrm);
120 //                      buf.append(' ');
121 //                      buf.append(paramNames[i]);
122 //                      if (i < lastParam) {
123 //                              buf.append(", "); //$NON-NLS-1$
124 //                      }
125 //              }
126 //              buf.append(')');
127 //              
128 //              int lastExc= excTypes.length - 1;
129 //              if (lastExc >= 0) {
130 //                      buf.append(" throws "); //$NON-NLS-1$
131 //                      for (int i= 0; i <= lastExc; i++) {
132 //                              String excTypeSig= excTypes[i];
133 //                              String excTypeFrm= resolveAndAdd(excTypeSig, declaringtype, imports);
134 //                              buf.append(excTypeFrm);
135 //                              if (i < lastExc) {
136 //                                      buf.append(", "); //$NON-NLS-1$
137 //                              }
138 //                      }
139 //              }
140 //              if (settings.noBody) {
141 //                      buf.append(";\n\n"); //$NON-NLS-1$
142 //              } else {
143 //                      buf.append(" {\n\t"); //$NON-NLS-1$
144 //                      if (!settings.callSuper) {
145 //                              if (retTypeSig != null && !retTypeSig.equals(Signature.SIG_VOID)) {
146 //                                      buf.append('\t');
147 //                                      if (!isPrimitiveType(retTypeSig) || Signature.getArrayCount(retTypeSig) > 0) {
148 //                                              buf.append("return null;\n\t"); //$NON-NLS-1$
149 //                                      } else if (retTypeSig.equals(Signature.SIG_BOOLEAN)) {
150 //                                              buf.append("return false;\n\t"); //$NON-NLS-1$
151 //                                      } else {
152 //                                              buf.append("return 0;\n\t"); //$NON-NLS-1$
153 //                                      }
154 //                              }
155 //                      } else {
156 //                              buf.append('\t');
157 //                              if (!isConstructor) {
158 //                                      if (!Signature.SIG_VOID.equals(retTypeSig)) {
159 //                                              buf.append("return "); //$NON-NLS-1$
160 //                                      }
161 //                                      buf.append("super."); //$NON-NLS-1$
162 //                                      buf.append(methodName);
163 //                              } else {
164 //                                      buf.append("super"); //$NON-NLS-1$
165 //                              }
166 //                              buf.append('(');                        
167 //                              for (int i= 0; i <= lastParam; i++) {
168 //                                      buf.append(paramNames[i]);
169 //                                      if (i < lastParam) {
170 //                                              buf.append(", "); //$NON-NLS-1$
171 //                                      }
172 //                              }
173 //                              buf.append(");\n\t"); //$NON-NLS-1$
174 //                      }
175 //                      buf.append("}\n");                       //$NON-NLS-1$
176 //              }
177 //              return buf.toString();
178 //      }
179 //      
180 //      private static boolean isSet(int options, int flag) {
181 //              return (options & flag) != 0;
182 //      }       
183 //
184 //      private static boolean isPrimitiveType(String typeName) {
185 //              char first= Signature.getElementType(typeName).charAt(0);
186 //              return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED);
187 //      }
188 //
189 //      private static String resolveAndAdd(String refTypeSig, IType declaringType, IImportsStructure imports) throws JavaModelException {
190 //              String resolvedTypeName= JavaModelUtil.getResolvedTypeName(refTypeSig, declaringType);
191 //              if (resolvedTypeName != null) {
192 //                      StringBuffer buf= new StringBuffer();
193 //                      if (imports != null) {
194 //                              buf.append(imports.addImport(resolvedTypeName));
195 //                      } else {
196 //                              buf.append(resolvedTypeName);
197 //                      }
198 //                      int arrayCount= Signature.getArrayCount(refTypeSig);
199 //                      for (int i= 0; i < arrayCount; i++) {
200 //                              buf.append("[]"); //$NON-NLS-1$
201 //                      }
202 //                      return buf.toString();
203 //              }
204 //              return Signature.toString(refTypeSig);
205 //      }
206 //      
207 //      /**
208 //       * Generates a default JavaDoc comment stub for a method.
209 //       */
210 //      public static void genJavaDocStub(String descr, String[] paramNames, String retTypeSig, String[] excTypeSigs, StringBuffer buf) {
211 //              buf.append("/**\n"); //$NON-NLS-1$
212 //              buf.append(" * "); buf.append(descr); buf.append(".\n"); //$NON-NLS-2$ //$NON-NLS-1$
213 //              for (int i= 0; i < paramNames.length; i++) {
214 //                      buf.append(" * @param "); buf.append(paramNames[i]); buf.append('\n'); //$NON-NLS-1$
215 //              }
216 //              if (retTypeSig != null && !retTypeSig.equals(Signature.SIG_VOID)) {
217 //                      String simpleName= Signature.getSimpleName(Signature.toString(retTypeSig));
218 //                      buf.append(" * @return "); buf.append(simpleName); buf.append('\n'); //$NON-NLS-1$
219 //              }
220 //              if (excTypeSigs != null) {
221 //                      for (int i= 0; i < excTypeSigs.length; i++) {
222 //                              String simpleName= Signature.getSimpleName(Signature.toString(excTypeSigs[i]));
223 //                              buf.append(" * @throws "); buf.append(simpleName); buf.append('\n'); //$NON-NLS-1$
224 //                      }
225 //              }
226 //              buf.append(" */"); //$NON-NLS-1$
227 //      }
228 //      
229 //      /**
230 //       * Generates a '@see' tag to the defined method.
231 //       */
232 //      public static void genJavaDocSeeTag(IType declaringType, String methodName, String[] paramTypes, boolean nonJavaDocComment, boolean isDeprecated, StringBuffer buf) throws JavaModelException {
233 //              String[] fullParamNames= new String[paramTypes.length];
234 //              for (int i= 0; i < paramTypes.length; i++) {
235 //                      fullParamNames[i]= JavaModelUtil.getResolvedTypeName(paramTypes[i], declaringType);
236 //              }
237 //              String fullTypeName= JavaModelUtil.getFullyQualifiedName(declaringType);
238 //              
239 //              genJavaDocSeeTag(fullTypeName, methodName, fullParamNames, nonJavaDocComment, isDeprecated, buf);
240 //      }
241 //      
242 //      /**
243 //       * Generates a '@see' tag to the defined method.
244 //       */
245 //      public static void genJavaDocSeeTag(String fullyQualifiedTypeName, String methodName, String[] fullParamTypeNames, boolean nonJavaDocComment, boolean isDeprecated, StringBuffer buf) throws JavaModelException {
246 //              // create a @see link
247 //              buf.append("/*"); //$NON-NLS-1$
248 //              if (!nonJavaDocComment) {
249 //                      buf.append('*');
250 //              } else {
251 //                      buf.append(" (non-Javadoc)"); //$NON-NLS-1$
252 //              }
253 //              buf.append("\n * @see "); //$NON-NLS-1$
254 //              buf.append(fullyQualifiedTypeName);
255 //              buf.append('#'); 
256 //              buf.append(methodName);
257 //              buf.append('(');
258 //              for (int i= 0; i < fullParamTypeNames.length; i++) {
259 //                      if (i > 0) {
260 //                              buf.append(", "); //$NON-NLS-1$
261 //                      }
262 //                      buf.append(fullParamTypeNames[i]);
263 //              }
264 //              buf.append(")\n"); //$NON-NLS-1$
265 //              if (isDeprecated) {
266 //                      buf.append(" * @deprecated\n"); //$NON-NLS-1$
267 //              }
268 //              buf.append(" */"); //$NON-NLS-1$
269 //      }       
270 //      
271 //      
272 //
273 //      /**
274 //       * Finds a method in a list of methods.
275 //       * @return The found method or null, if nothing found
276 //       */
277 //      private static IMethod findMethod(IMethod method, List allMethods) throws JavaModelException {
278 //              String name= method.getElementName();
279 //              String[] paramTypes= method.getParameterTypes();
280 //              boolean isConstructor= method.isConstructor();
281 //
282 //              for (int i= allMethods.size() - 1; i >= 0; i--) {
283 //                      IMethod curr= (IMethod) allMethods.get(i);
284 //                      if (JavaModelUtil.isSameMethodSignature(name, paramTypes, isConstructor, curr)) {
285 //                              return curr;
286 //                      }                       
287 //              }
288 //              return null;
289 //      }
290
291
292         /**
293          * Creates needed constructors for a type.
294          * @param type The type to create constructors for
295          * @param supertype The type's super type
296          * @param settings Options for comment generation
297          * @param imports Required imports are added to the import structure. Structure can be <code>null</code>, types are qualified then.
298          * @return Returns the generated stubs or <code>null</code> if the creation has been canceled
299          */
300 //      public static String[] evalConstructors(IType type, IType supertype, CodeGenerationSettings settings, IImportsStructure imports) throws JavaModelException {
301 //              IMethod[] superMethods= supertype.getMethods();
302 //              String typeName= type.getElementName();
303 //              IMethod[] methods= type.getMethods();
304 //              GenStubSettings genStubSettings= new GenStubSettings(settings);
305 //              genStubSettings.callSuper= true;
306 //              ArrayList newMethods= new ArrayList(superMethods.length);
307 //              for (int i= 0; i < superMethods.length; i++) {
308 //                      IMethod curr= superMethods[i];
309 //                      if (curr.isConstructor() && (JavaModelUtil.isVisible(curr, type.getPackageFragment()) || Flags.isProtected(curr.getFlags()))) {
310 //                              if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null) {
311 //                                      String newStub= genStub(typeName, superMethods[i], genStubSettings, imports);
312 //                                      newMethods.add(newStub);
313 //                              }
314 //                      }
315 //              }
316 //              return (String[]) newMethods.toArray(new String[newMethods.size()]);
317 //      }
318 //
319 //      /**
320 //       * Searches for unimplemented methods of a type.
321 //       * @param isSubType If set, the evaluation is for a subtype of the given type. If not set, the
322 //       * evaluation is for the type itself.
323 //       * @param settings Options for comment generation
324 //       * @param selectionQuery If not null will select the methods to implement.
325 //       * @param imports Required imports are added to the import structure. Structure can be <code>null</code>, types are qualified then.
326 //       * @return Returns the generated stubs or <code>null</code> if the creation has been canceled
327 //       */
328 //      public static String[] evalUnimplementedMethods(IType type, ITypeHierarchy hierarchy, boolean isSubType, CodeGenerationSettings settings, 
329 //                              IOverrideMethodQuery selectionQuery, IImportsStructure imports) throws JavaModelException {
330 //              List allMethods= new ArrayList();
331 //              List toImplement= new ArrayList();
332 //
333 //              IMethod[] typeMethods= type.getMethods();
334 //              for (int i= 0; i < typeMethods.length; i++) {
335 //                      IMethod curr= typeMethods[i];
336 //                      if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) && !Flags.isPrivate(curr.getFlags())) {
337 //                              allMethods.add(curr);
338 //                      }
339 //              }
340 //
341 //              IType[] superTypes= hierarchy.getAllSuperclasses(type);
342 //              for (int i= 0; i < superTypes.length; i++) {
343 //                      IMethod[] methods= superTypes[i].getMethods();
344 //                      for (int k= 0; k < methods.length; k++) {
345 //                              IMethod curr= methods[k];
346 //                              if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) && !Flags.isPrivate(curr.getFlags())) {
347 //                                      if (findMethod(curr, allMethods) == null) {
348 //                                              allMethods.add(curr);
349 //                                      }
350 //                              }
351 //                      }
352 //              }
353 //
354 //              // do not call super
355 //              for (int i= 0; i < allMethods.size(); i++) {
356 //                      IMethod curr= (IMethod) allMethods.get(i);
357 //                      if ((Flags.isAbstract(curr.getFlags()) || curr.getDeclaringType().isInterface()) && (isSubType || !type.equals(curr.getDeclaringType()))) {
358 //                              // implement all abstract methods
359 //                              toImplement.add(curr);
360 //                      }
361 //              }
362 //
363 //              IType[] superInterfaces= hierarchy.getAllSuperInterfaces(type);
364 //              for (int i= 0; i < superInterfaces.length; i++) {
365 //                      IMethod[] methods= superInterfaces[i].getMethods();
366 //                      for (int k= 0; k < methods.length; k++) {
367 //                              IMethod curr= methods[k];
368 //
369 //                              // binary interfaces can contain static initializers (variable intializations)
370 //                              // 1G4CKUS
371 //                              if (!Flags.isStatic(curr.getFlags())) {
372 //                                      IMethod impl= findMethod(curr, allMethods);
373 //                                      if (impl == null || ((curr.getExceptionTypes().length < impl.getExceptionTypes().length) && !Flags.isFinal(impl.getFlags()))) {
374 //                                              if (impl != null) {
375 //                                                      allMethods.remove(impl);
376 //                                              }
377 //                                              // implement an interface method when it does not exist in the hierarchy
378 //                                              // or when it throws less exceptions that the implemented
379 //                                              toImplement.add(curr);
380 //                                              allMethods.add(curr);
381 //                                      }
382 //                              }
383 //                      }
384 //              }
385 //              IMethod[] toImplementArray= (IMethod[]) toImplement.toArray(new IMethod[toImplement.size()]);
386 //              if (selectionQuery != null) {
387 //                      if (!isSubType) {
388 //                              allMethods.removeAll(Arrays.asList(typeMethods));
389 //                      }
390 //                      // remove finals
391 //                      for (int i= allMethods.size() - 1; i >= 0; i--) {
392 //                              IMethod curr= (IMethod) allMethods.get(i);
393 //                              if (Flags.isFinal(curr.getFlags())) {
394 //                                      allMethods.remove(i);
395 //                              }
396 //                      }
397 //                      IMethod[] choice= (IMethod[]) allMethods.toArray(new IMethod[allMethods.size()]);
398 //                      toImplementArray= selectionQuery.select(choice, toImplementArray, hierarchy);
399 //                      if (toImplementArray == null) {
400 //                              //cancel pressed
401 //                              return null;
402 //                      }
403 //              }
404 //              GenStubSettings genStubSettings= new GenStubSettings(settings);
405 //              genStubSettings.methodOverwrites= true;
406 //              String[] result= new String[toImplementArray.length];
407 //              for (int i= 0; i < toImplementArray.length; i++) {
408 //                      IMethod curr= toImplementArray[i];
409 //                      IMethod overrides= JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type, curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
410 //                      genStubSettings.callSuper= (overrides != null);
411 //                                              
412 //                      IMethod desc= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy, type, curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
413 //                      if (desc != null) {
414 //                              curr= desc;
415 //                      }
416 //                      result[i]= genStub(type.getElementName(), curr, genStubSettings, imports);
417 //              }
418 //              return result;
419 //      }
420
421         /**
422          * Examines a string and returns the first line delimiter found.
423          */
424 //      public static String getLineDelimiterUsed(IJavaElement elem) throws JavaModelException {
425 //              ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
426 //              if (cu != null && cu.exists()) {
427 //                      IBuffer buf= cu.getBuffer();
428 //                      int length= buf.getLength();
429 //                      for (int i= 0; i < length; i++) {
430 //                              char ch= buf.getChar(i);
431 //                              if (ch == SWT.CR) {
432 //                                      if (i + 1 < length) {
433 //                                              if (buf.getChar(i + 1) == SWT.LF) {
434 //                                                      return "\r\n"; //$NON-NLS-1$
435 //                                              }
436 //                                      }
437 //                                      return "\r"; //$NON-NLS-1$
438 //                              } else if (ch == SWT.LF) {
439 //                                      return "\n"; //$NON-NLS-1$
440 //                              }
441 //                      }
442 //              }
443 //              return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
444 //      }
445
446         /**
447          * Embodies the policy which line delimiter to use when inserting into
448          * a document.
449          */     
450         public static String getLineDelimiterFor(IDocument doc) {
451                 // new for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in php editor inserts lines in wrong format
452                 String lineDelim= null;
453                 try {
454                         lineDelim= doc.getLineDelimiter(0);
455                 } catch (BadLocationException e) {
456                 }
457                 if (lineDelim == null) {
458                         String systemDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
459                         String[] lineDelims= doc.getLegalLineDelimiters();
460                         for (int i= 0; i < lineDelims.length; i++) {
461                                 if (lineDelims[i].equals(systemDelimiter)) {
462                                         lineDelim= systemDelimiter;
463                                         break;
464                                 }
465                         }
466                         if (lineDelim == null) {
467                                 lineDelim= lineDelims.length > 0 ? lineDelims[0] : systemDelimiter;
468                         }
469                 }
470                 return lineDelim;
471         }
472
473
474         /**
475          * Evaluates the indention used by a Java element. (in tabulators)
476          */     
477 //      public static int getIndentUsed(IJavaElement elem) throws JavaModelException {
478 //              if (elem instanceof ISourceReference) {
479 //                      ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
480 //                      if (cu != null) {
481 //                              IBuffer buf= cu.getBuffer();
482 //                              int offset= ((ISourceReference)elem).getSourceRange().getOffset();
483 //                              int i= offset;
484 //                              // find beginning of line
485 //                              while (i > 0 && !Strings.isLineDelimiterChar(buf.getChar(i - 1)) ){
486 //                                      i--;
487 //                              }
488 //                              return Strings.computeIndent(buf.getText(i, offset - i), CodeFormatterUtil.getTabWidth());
489 //                      }
490 //              }
491 //              return 0;
492 //      }
493         
494         public static String codeFormat(String sourceString, int initialIndentationLevel, String lineDelim) {
495                 ICodeFormatter formatter= ToolFactory.createDefaultCodeFormatter(null);
496                 return formatter.format(sourceString, initialIndentationLevel, null, lineDelim);
497         }
498         
499         /**
500          * Returns the element after the give element.
501          */
502 //      public static IJavaElement findNextSibling(IJavaElement member) throws JavaModelException {
503 //              IJavaElement parent= member.getParent();
504 //              if (parent instanceof IParent) {
505 //                      IJavaElement[] elements= ((IParent)parent).getChildren();
506 //                      for (int i= elements.length - 2; i >= 0 ; i--) {
507 //                              if (member.equals(elements[i])) {
508 //                                      return elements[i+1];
509 //                              }
510 //                      }
511 //              }
512 //              return null;
513 //      }
514 //      
515         public static String getTodoTaskTag(IJavaProject project) {
516                 String markers= null;
517                 if (project == null) {
518                         markers= JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS);
519                 } else {
520                         markers= project.getOption(JavaCore.COMPILER_TASK_TAGS, true);
521                 }
522                 
523                 if (markers != null && markers.length() > 0) {
524                         int idx= markers.indexOf(',');  
525                         if (idx == -1) {
526                                 return markers;
527                         } else {
528                                 return markers.substring(0, idx);
529                         }
530                 }
531                 return null;
532         }
533
534 }