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