/**
   * Appends a package.
   *
   * @param comment
   */
  private void emitPackage(DocComment comment) {
    xml.append("\n<packageRec name='");
    xml.append(comment.getFullname());
    xml.append("' fullname='");
    xml.append(comment.getFullname());
    xml.append("'>");

    String desc = comment.getDescription();
    if (desc != null) appendTag("description", comment.getDescription());
    emitTags(comment.getAllTags());

    xml.append("\n</packageRec>");
  }
  /**
   * Appends a field.
   *
   * @param comment
   */
  private void emitField(DocComment comment) {
    xml.append("\n<field name='");
    xml.append(comment.getName());
    xml.append("' fullname='");
    xml.append(comment.getFullname());
    xml.append("' type='");
    String type = comment.getVartype();
    if (type != null) xml.append(comment.getVartype());
    xml.append("' isStatic='");
    xml.append(comment.isStatic());
    xml.append("' isConst='");
    xml.append(comment.isConst());
    xml.append("' ");
    String defaultValue = comment.getDefaultValue();
    if (defaultValue != null) {
      xml.append("defaultValue='");

      try {
        Pattern pattern = Pattern.compile("\\p{Cntrl}");
        Matcher matcher = pattern.matcher(defaultValue);
        defaultValue = matcher.replaceAll("");
      } catch (Exception ex) {
      }

      xml.append(defaultValue);
      xml.append("' ");
    }
    xml.append(">");

    String desc = comment.getDescription();
    if (desc != null) appendTag("description", comment.getDescription());
    emitTags(comment.getAllTags());

    if (comment.getMetadata() != null) emitMetadata(comment.getMetadata());
    xml.append("\n</field>");
  }
  /**
   * Appends a function
   *
   * @param comment
   */
  private void emitFunction(DocComment comment) {
    xml.append("\n<method name='");
    xml.append(comment.getName());
    xml.append("' fullname='");
    xml.append(comment.getFullname());
    xml.append("' ");
    xml.append("isStatic='");
    xml.append(comment.isStatic());
    xml.append("' ");
    xml.append("isFinal='");
    xml.append(comment.isFinal());
    xml.append("' ");
    xml.append("isOverride='");
    xml.append(comment.isOverride());
    xml.append("' ");

    String[] param_names = comment.getParamNames();
    if (param_names != null) {
      xml.append(" param_names='");
      for (int i = 0; i < param_names.length; i++) {
        String pname = param_names[i];
        if (pname != null) {
          if (i != 0) xml.append(";");
          xml.append(pname);
        }
      }
      xml.append("'");

      String[] param_types = comment.getParamTypes();
      xml.append(" param_types='");
      for (int i = 0; i < param_types.length; i++) {
        String ptype = param_types[i];
        if (ptype != null) {
          if (i != 0) xml.append(";");
          xml.append(ptype);
        }
      }
      xml.append("'");

      String[] param_defaults = comment.getParamDefaults();
      xml.append(" param_defaults='");
      for (int i = 0; i < param_defaults.length; i++) {
        String pdefa = param_defaults[i];
        if (pdefa != null) {
          if (i != 0) xml.append(";");
          xml.append(pdefa);
        }
      }
      xml.append("'");
    }

    xml.append(" result_type='");
    xml.append(comment.getResultType());
    xml.append("'>");

    String desc = comment.getDescription();
    if (desc != null) appendTag("description", comment.getDescription());
    emitTags(comment.getAllTags());

    if (comment.getMetadata() != null) emitMetadata(comment.getMetadata());
    xml.append("\n</method>");
  }
  /**
   * Appends a class or interface
   *
   * @param comment
   */
  private void emitClass(DocComment comment) {
    String tagName = (comment.getType() == DocComment.CLASS) ? "classRec" : "interfaceRec";
    xml.append("\n<");
    xml.append(tagName);
    xml.append(" name='");
    xml.append(comment.getName());
    xml.append("' fullname='");
    xml.append(comment.getFullname());
    String sourcefile = comment.getSourceFile();
    if (sourcefile != null) {
      xml.append("' sourcefile='");
      xml.append(sourcefile);
    }
    xml.append("' namespace='");
    xml.append(comment.getNamespace());
    xml.append("' access='");
    xml.append(comment.getAccess());
    xml.append("' ");
    if (comment.getType() == DocComment.INTERFACE) {
      String[] baseClasses = comment.getBaseclasses();
      if (baseClasses != null) {
        xml.append("baseClasses='");
        for (int i = 0; i < baseClasses.length; i++) {
          String baseclass = baseClasses[i];
          if (baseclass != null) {
            if (i != 0) xml.append(";");
            xml.append(baseclass);
          }
        }
        xml.append("' ");
      }
    } else {
      xml.append("baseclass='");
      xml.append(comment.getBaseClass());
      xml.append("' ");
      String[] interfaces = comment.getInterfaces();
      if (interfaces != null) {
        xml.append("interfaces='");
        for (int i = 0; i < interfaces.length; i++) {
          String inter = interfaces[i];
          if (inter != null) {
            if (i != 0) xml.append(";");
            xml.append(inter);
          }
        }
        xml.append("' ");
      }
    }
    xml.append("isFinal='");
    xml.append(comment.isFinal());
    xml.append("' ");
    xml.append("isDynamic='");
    xml.append(comment.isDynamic());
    xml.append("' ");
    xml.append(">");

    String desc = comment.getDescription();
    if (desc != null) appendTag("description", comment.getDescription());
    emitTags(comment.getAllTags());

    if (comment.getMetadata() != null) emitMetadata(comment.getMetadata());
    xml.append("\n</");
    xml.append(tagName);
    xml.append(">");
  }
  /**
   * appends metadata associated with a definition.
   *
   * @param metadata
   */
  private void emitMetadata(List metadata) {
    for (int i = 0; i < metadata.size(); i++) {
      DocComment meta = (DocComment) metadata.get(i);
      String metadataType = meta.getMetadataType().intern();
      xml.append("\n<metadata>\n");
      xml.append("\t<");
      xml.append(metadataType);
      xml.append(" owner='");
      xml.append(meta.getOwner());
      xml.append("' ");
      String name = meta.getName();
      if (!name.equals("IGNORE")) xml.append("name='").append(name).append("' ");
      String type_meta = meta.getType_meta();
      if (type_meta != null) {
        xml.append("type='").append(type_meta).append("' ");
      }

      String event_meta = meta.getEvent_meta();
      if (event_meta != null) {
        xml.append("event='").append(event_meta).append("' ");
      }
      String kind_meta = meta.getKind_meta();
      if (kind_meta != null) {
        xml.append("kind='").append(kind_meta).append("' ");
      }
      String arrayType_meta = meta.getArrayType_meta();
      if (arrayType_meta != null) {
        xml.append("arrayType='").append(arrayType_meta).append("' ");
      }
      String format_meta = meta.getFormat_meta();
      if (format_meta != null) {
        xml.append("format='").append(format_meta).append("' ");
      }
      String enumeration_meta = meta.getEnumeration_meta();
      if (enumeration_meta != null) {
        xml.append("enumeration='").append(enumeration_meta).append("' ");
      }
      String inherit_meta = meta.getInherit_meta();
      if (inherit_meta != null) {
        xml.append("inherit='").append(inherit_meta).append("' ");
      }

      if (metadataType == StandardDefs.MD_EVENT) {
        // if message meta data is present then emit it. Applicable for Deprecation
        String message_meta = meta.getMessage_meta();
        if (message_meta != null) {
          xml.append("deprecatedMessage='").append(message_meta).append("' ");
        }

        // if replacement meta data is present then emit it. Applicable for Deprecation
        String replacement_meta = meta.getReplacement_meta();
        if (replacement_meta != null) {
          xml.append("deprecatedReplacement='").append(replacement_meta).append("' ");
        }

        // if since meta data is present then emit it. Applicable for Deprecation
        String since_meta = meta.getSince_meta();
        if (since_meta != null) {
          xml.append("deprecatedSince='").append(since_meta).append("' ");
        }
      } else if (metadataType == StandardDefs.MD_SKINPART) {
        String variableType_meta = meta.getVariableType_meta();
        if (variableType_meta != null) {
          xml.append("var_type='").append(variableType_meta).append("' ");
        }

        String required_meta = meta.getRequired_meta();
        if (required_meta != null) {
          xml.append("required='").append(required_meta).append("' ");
        } else {
          // false is now the default value for required in case of SkinPart.
          xml.append("required='false' ");
        }
      } else {
        // if message meta data is present then emit it. Applicable for Deprecation
        String message_meta = meta.getMessage_meta();
        if (message_meta != null) {
          xml.append("message='").append(message_meta).append("' ");
        }

        // if replacement meta data is present then emit it. Applicable for Deprecation
        String replacement_meta = meta.getReplacement_meta();
        if (replacement_meta != null) {
          xml.append("replacement='").append(replacement_meta).append("' ");
        }

        // if since meta data is present then emit it. Applicable for Deprecation
        String since_meta = meta.getSince_meta();
        if (since_meta != null) {
          xml.append("since='").append(since_meta).append("' ");
        }
      }

      xml.append(">");

      // These types of metadata can have comments associated with them
      if (metadataType == StandardDefs.MD_EVENT
          || metadataType == StandardDefs.MD_SKINSTATE
          || metadataType == StandardDefs.MD_SKINPART
          || metadataType == StandardDefs.MD_ALTERNATIVE
          || metadataType == StandardDefs.MD_DISCOURAGEDFORPROFILE
          || metadataType == StandardDefs.MD_EXPERIMENTAL) {
        String desc = meta.getDescription();
        if (desc != null) appendTag("description", meta.getDescription());
        emitTags(meta.getAllTags());
      }
      xml.append("\n\t</");
      xml.append(metadataType);
      xml.append(">\n</metadata>");
    }
  }