protected CMDocument getCorrespondingCMDocument(Node node, boolean getDocumentFromCMNode) {
    CMDocument result = null;
    try {
      Document document =
          node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node : node.getOwnerDocument();

      String[] doctypeInfo = getDoctypeInfo(document);

      if (doctypeInfo != null) {
        result = getCMDocument(doctypeInfo[0], doctypeInfo[1], "DTD"); // $NON-NLS-1$
      }
      // defect 211236 ... in some cases calling this method can result in a cycle
      // we use the getDocumentFromCMNode as a flag to avoid this
      // TODO... see if there is a way to re-organize to avoid the need for this flag
      else if (getDocumentFromCMNode) {
        CMNode cmNode = getCMNode(node);
        if (cmNode != null) {
          // todo... add a getCMDocument() methods to CMNode
          // for now use the getProperty interface
          result = (CMDocument) cmNode.getProperty("CMDocument"); // $NON-NLS-1$
        }
      }
    } catch (Exception e) {
      Logger.logException("exception locating CMDocument for " + node, e); // $NON-NLS-1$
    }
    return result;
  }
  protected CMElementDeclaration getCMElementDeclaration(
      Element targetElement, List list, String publicId, String systemId) {
    CMElementDeclaration currentED = null;
    try {
      int listSize = list.size();
      for (int i = 0; i < listSize; i++) {
        Element element = (Element) list.get(i);

        final String nodeName = element.getNodeName();

        CMElementDeclaration ed = null;

        // see if the element is a local of the currentED
        //
        if (currentED != null) {
          ed = (CMElementDeclaration) currentED.getLocalElements().getNamedItem(nodeName);
        }

        if (ed == null) {
          CMDocument cmDocument = getCMDocument(publicId, systemId, "XSD"); // $NON-NLS-1$
          if (cmDocument != null) {
            ed = (CMElementDeclaration) cmDocument.getElements().getNamedItem(nodeName);
          }
        }
        currentED = ed;
      }
    } catch (Exception e) {
      Logger.logException(
          "exception locating element declaration for " + targetElement, e); // $NON-NLS-1$
    }

    return currentED;
  }
  public CommentElementHandler getHandler() {
    if (fHandler == null) {
      if (fElement != null) {
        try {
          if (isCustom()) {
            fHandler =
                (CommentElementHandler) fElement.createExecutableExtension("class"); // $NON-NLS-1$
          } else {
            String elementName = getProperty("elementname"); // $NON-NLS-1$
            if (elementName != null) {
              fHandler = new BasicCommentElementHandler(elementName, fEmpty);
            }
          }
          //
          //	((AbstractCommentElementHandler)fHandler).setElementPrefix(fElement.getAttribute("prefix"));
        } catch (Exception e) {
          // catch and log (and ignore) ANY exception created
          // by executable extension.
          Logger.logException(e);
          fHandler = null;
        }
      }
      if (fHandler == null) {
        fHandler =
            new CommentElementHandler() {
              public Element createElement(Document document, String data, boolean isJSPTag) {
                return null;
              }

              public String generateEndTagContent(IDOMElement element) {
                return null;
              }

              public String generateStartTagContent(IDOMElement element) {
                return null;
              }

              // removed in RC2, ro removed "unused" error/warning
              //					public String getElementPrefix() {
              //						return null;
              //					}

              public boolean isCommentElement(IDOMElement element) {
                return false;
              }

              public boolean isEmpty() {
                return false;
              }
            };
      }
    }
    return fHandler;
  }
  protected CMElementDeclaration getCMElementDeclaration(
      Element targetElement, List list, NamespaceTable namespaceTable) {
    CMElementDeclaration currentED = null;
    try {
      int listSize = list.size();
      for (int i = 0; i < listSize; i++) {
        Element element = (Element) list.get(i);

        if (i != 0) {
          namespaceTable.addElement(element);
        }

        String nodeName = element.getNodeName();
        String unprefixedName = DOMNamespaceHelper.getUnprefixedName(nodeName);
        String prefix = DOMNamespaceHelper.getPrefix(nodeName);

        CMElementDeclaration ed = null;

        // see if the element is a local of the currentED
        //
        if (currentED != null) {
          ed = (CMElementDeclaration) currentED.getLocalElements().getNamedItem(unprefixedName);
        }

        if (ed == null) {
          NamespaceInfo namespaceInfo = namespaceTable.getNamespaceInfoForPrefix(prefix);
          if (namespaceInfo != null) {
            CMDocument cmDocument =
                getCMDocument(namespaceInfo.uri, namespaceInfo.locationHint, "XSD"); // $NON-NLS-1$
            if (cmDocument != null) {
              ed = (CMElementDeclaration) cmDocument.getElements().getNamedItem(unprefixedName);
            }
          }
        }
        currentED = ed;

        // handle XSIType
        if (currentED != null) {
          CMElementDeclaration derivedED =
              getDerivedCMElementDeclaration(element, currentED, namespaceTable);
          if (derivedED != null) {
            currentED = derivedED;
          }
        }
      }
    } catch (Exception e) {
      Logger.logException(
          "exception locating element declaration for " + targetElement, e); // $NON-NLS-1$
    }

    return currentED;
  }
 protected CMElementDeclaration checkExternalSchema(Element element) {
   final Document document = element.getOwnerDocument();
   if (document instanceof IDOMDocument) {
     final String baseLocation = ((IDOMDocument) document).getModel().getBaseLocation();
     if (baseLocation != null) {
       final IPath basePath = new Path(baseLocation);
       IFile file = null;
       if (basePath.segmentCount() > 1) {
         file = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath);
       }
       final URI uri =
           (file == null || !file.isAccessible())
               ? new File(baseLocation).toURI()
               : file.getLocationURI();
       if (uri != null) {
         IExternalSchemaLocationProvider[] providers =
             ExternalSchemaLocationProviderRegistry.getInstance().getProviders();
         for (int i = 0; i < providers.length; i++) {
           long time = _trace ? System.currentTimeMillis() : 0;
           final Map locations = providers[i].getExternalSchemaLocation(uri);
           if (_trace) {
             long diff = System.currentTimeMillis() - time;
             if (diff > 250)
               Logger.log(
                   Logger.INFO,
                   "Schema location provider took ["
                       + diff
                       + "ms] for URI ["
                       + uri
                       + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
           }
           if (locations != null && !locations.isEmpty()) {
             Object location =
                 locations.get(IExternalSchemaLocationProvider.NO_NAMESPACE_SCHEMA_LOCATION);
             if (location != null)
               return getCMElementDeclaration(
                   element,
                   NamespaceTable.getElementLineage(element),
                   uri.toString(),
                   location.toString());
           }
         }
       }
     }
   }
   return null;
 }
 public String[] getPrefix() {
   if (fPrefix == null) {
     if (fElement != null) {
       if (isCustom()) { // custom
         IConfigurationElement[] prefixes = fElement.getChildren("startwith"); // $NON-NLS-1$
         if (prefixes != null) {
           List prefixValues = new ArrayList(prefixes.length);
           for (int i = 0; i < prefixes.length; i++) {
             String prefix = prefixes[i].getAttribute("prefix"); // $NON-NLS-1$
             if (prefix != null) {
               prefixValues.add(prefix);
             } else {
               try {
                 Logger.log(
                     Logger.WARNING,
                     "misconfigured comment element in" + fElement.getContributor().getName(),
                     new IllegalArgumentException("startwith")); // $NON-NLS-1$ //$NON-NLS-2$
               } catch (InvalidRegistryObjectException e) {
                 // stale bundle?
               }
             }
           }
           if (!prefixValues.isEmpty()) {
             fPrefix = (String[]) prefixValues.toArray(new String[prefixValues.size()]);
           }
         }
       } else { // basic
         String name = getProperty("elementname"); // $NON-NLS-1$
         if (name != null) {
           if (isEmpty()) {
             fPrefix = new String[1];
             fPrefix[0] = name;
           } else {
             fPrefix = new String[2];
             fPrefix[0] = name;
             fPrefix[1] = '/' + name;
           }
         }
       }
     }
   }
   if (fPrefix == null) {
     fPrefix = new String[0];
   }
   return fPrefix;
 }
 public static void loadAnnotationsForGrammar(String publicId, CMDocument cmDocument) {
   List annotationFiles = ContentModelManager.getInstance().getAnnotationFilesInfos(publicId);
   AnnotationMap map = (AnnotationMap) cmDocument.getProperty("annotationMap"); // $NON-NLS-1$
   if (map != null) {
     synchronized (annotationFiles) {
       for (Iterator i = annotationFiles.iterator(); i.hasNext(); ) {
         try {
           AnnotationFileInfo annotationFileInfo = (AnnotationFileInfo) i.next();
           AnnotationFileParser parser = new AnnotationFileParser();
           parser.parse(map, annotationFileInfo);
         } catch (Exception e) {
           Logger.logException(e);
         }
       }
     }
   }
 }