protected void generateEndTag(
      String tagName, Node parentNode, CMElementDeclaration elementDecl, StringBuffer buffer) {
    if (elementDecl == null) return;
    if (elementDecl instanceof HTMLElementDeclaration) {
      if (((Boolean) elementDecl.getProperty(HTMLCMProperties.IS_JSP)).booleanValue()) {
        if (elementDecl.getContentType() == CMElementDeclaration.EMPTY) return;
      } else {
        String ommission = (String) elementDecl.getProperty(HTMLCMProperties.OMIT_TYPE);
        if (ommission.equals(HTMLCMProperties.Values.OMIT_END)
            || ommission.equals(HTMLCMProperties.Values.OMIT_END_DEFAULT)
            || ommission.equals(HTMLCMProperties.Values.OMIT_END_MUST)) {
          return;
        }
      }
    }

    if (elementDecl.getContentType() == CMElementDeclaration.EMPTY) return;
    buffer.append("</" + tagName + ">"); // $NON-NLS-2$//$NON-NLS-1$
    return;
  }
 protected CMElementDeclaration getDerivedCMElementDeclaration(
     Element element, CMElementDeclaration ed, NamespaceTable namespaceTable) {
   CMElementDeclaration result = null;
   String xsiPrefix =
       namespaceTable.getPrefixForURI("http://www.w3.org/2001/XMLSchema-instance"); // $NON-NLS-1$
   if (xsiPrefix != null) {
     String xsiTypeValue = element.getAttribute(xsiPrefix + ":type"); // $NON-NLS-1$
     if (xsiTypeValue != null && xsiTypeValue.length() > 0) {
       String typePrefix = DOMNamespaceHelper.getPrefix(xsiTypeValue);
       String typeName = DOMNamespaceHelper.getUnprefixedName(xsiTypeValue);
       String typeURI = namespaceTable.getURIForPrefix(typePrefix);
       String uriQualifiedTypeName = typeName;
       if (typeURI != null && typeURI.length() > 0) {
         uriQualifiedTypeName = "[" + typeURI + "]" + typeName; // $NON-NLS-1$ //$NON-NLS-2$
       }
       result =
           (CMElementDeclaration)
               ed.getProperty("DerivedElementDeclaration=" + uriQualifiedTypeName); // $NON-NLS-1$
       if (result == null) {
         String reference = null;
         NamespaceInfo namespaceInfo = namespaceTable.getNamespaceInfoForPrefix(typePrefix);
         if (namespaceInfo != null) {
           String locationHint =
               resolveGrammarURI(
                   element.getOwnerDocument(), namespaceInfo.uri, namespaceInfo.locationHint);
           if (locationHint != null) {
             reference = "[" + locationHint + "]" + typeName; // $NON-NLS-1$ //$NON-NLS-2$
           }
         }
         if (reference != null) {
           result =
               (CMElementDeclaration)
                   ed.getProperty(
                       "ExternallyDerivedElementDeclaration=" + reference); // $NON-NLS-1$
         }
       }
     }
   }
   return result;
 }
  public String getStartTagClose(Node parentNode, CMElementDeclaration elementDecl) {
    String other = getOtherClose(parentNode);
    if (other != null) return other;
    if (elementDecl == null) return ">"; // $NON-NLS-1$
    if (elementDecl instanceof HTMLElementDeclaration) {
      if (((Boolean) elementDecl.getProperty(HTMLCMProperties.IS_JSP)).booleanValue()) {
        if (elementDecl.getContentType() == CMElementDeclaration.EMPTY) return "/>"; // $NON-NLS-1$
      } else {
        String ommission = (String) elementDecl.getProperty(HTMLCMProperties.OMIT_TYPE);
        if (ommission.equals(HTMLCMProperties.Values.OMIT_END)
            || ommission.equals(HTMLCMProperties.Values.OMIT_END_DEFAULT)
            || ommission.equals(HTMLCMProperties.Values.OMIT_END_MUST)) {
          return ">"; //$NON-NLS-1$
        }
      }
    }

    // if not an html element and empty, assume start tag needs to be closed
    else if (elementDecl.getContentType() == CMElementDeclaration.EMPTY) {
      return "/>"; //$NON-NLS-1$
    }

    return ">"; //$NON-NLS-1$
  }