/**
   * Process an MXMLTagData - this will write a String representation of the tag into the
   * StringWriter passed in. This will strip out any databinding expressions from the String, TODO:
   * databinding - add the databinding expressions as children of the MXMLXMLNode, and also record
   * what the TODO: target expressions for those are (these are the expressions to set the value in
   * the XML object when the TODO: PropertyChange event fires).
   */
  void processNode(MXMLTagData tag, StringWriter sw) {
    sw.write('<');
    if (tag.isCloseTag()) sw.write('/');
    sw.write(tag.getName());
    String tagPrefix = tag.getPrefix();

    // lookup the prefix in case it's defined elsewhere in the document outside the XML tag
    if (tagPrefix != null) lookupPrefix(tagPrefix, tag);

    List<MXMLTagAttributeData> attrs = getAttributes(tag);
    for (MXMLTagAttributeData attr : attrs) {
      sw.write(' ');
      sw.write(attr.getName());
      sw.write('=');
      sw.write('"');
      sw.write(attr.getRawValue());
      sw.write('"');

      // lookup the prefix in case it's defined outside the XML tag
      String prefix = attr.getPrefix();
      if (prefix != null) lookupPrefix(prefix, tag);
    }

    StringWriter childrenSW = new StringWriter();
    for (MXMLUnitData unit = tag.getFirstChildUnit();
        unit != null;
        unit = unit.getNextSiblingUnit()) {
      processNode(unit, childrenSW);
    }

    if (tag == rootTag) {
      // If we're the root tag, then add an xmlns for each prefix that was referenced by one of our
      // children, but was defined elsewhere in the document (like in the Application tag).
      for (String prefix : referencedPrefixes) {
        String uri = externalPrefixes.getNamespaceForPrefix(prefix);
        if (uri != null) {
          sw.write(" xmlns:");
          sw.write(prefix);
          sw.write("=\"");
          sw.write(uri);
          sw.write('\"');
        }
      }
    }
    if (tag.isEmptyTag()) {
      sw.write("/>");
    } else {
      sw.write('>');
    }
    sw.write(childrenSW.toString());

    MXMLTagData endTag = tag.findMatchingEndTag();
    if (endTag != null) {
      processNode(endTag, sw);
    }
  }
 /** Generate an AET Name for the attr passed in */
 private Name getNameForAttr(MXMLTagAttributeData attr) {
   String uri = attr.getURI();
   if (uri != null) {
     return new Name(
         ABCConstants.CONSTANT_QnameA,
         new Nsset(new Namespace(ABCConstants.CONSTANT_Namespace, uri)),
         attr.getShortName());
   } else {
     return new Name(
         ABCConstants.CONSTANT_QnameA,
         new Nsset(new Namespace(ABCConstants.CONSTANT_Namespace, "")),
         attr.getShortName());
   }
 }
  @Override
  protected void processTagSpecificAttribute(
      MXMLTreeBuilder builder, MXMLTagData tag, MXMLTagAttributeData attribute, MXMLNodeInfo info) {

    MXMLSpecifierNodeBase childNode = createSpecifierNode(builder, attribute.getName());
    if (childNode != null) {
      childNode.setLocation(attribute);
      childNode.setSuffix(builder, attribute.getStateName());
      childNode.initializeFromAttribute(builder, attribute, info);
      info.addChildNode(childNode);
    } else {
      super.processTagSpecificAttribute(builder, tag, attribute, info);
    }
  }
  /**
   * Attempt to parse a binding expression from the passed in attribute
   *
   * @param attr The Tag Attribute Data to parse
   * @return An IMXMLDataBindingNode that was parsed from attr, or null if no databinding expression
   *     was found
   */
  private IMXMLSingleDataBindingNode parseBindingExpression(MXMLTagAttributeData attr) {
    Object o =
        MXMLDataBindingParser.parse(
            parent,
            attr,
            attr.getValueFragments(builder.getProblems()),
            builder.getProblems(),
            builder.getWorkspace(),
            builder.getMXMLDialect());
    if (o instanceof IMXMLSingleDataBindingNode) {
      return ((IMXMLSingleDataBindingNode) o);
    }

    return null;
  }
 /**
  * Generate an MXMLBindingNode to represent the binding expression in the MXMLTagAttributeData
  * passed in.
  *
  * @param attr the Attribute that is the destination of the binding expression
  * @param dbnode the DataBinding Node that contains the source expression
  * @return An MXMLBindingNode with expressions for the source and destination
  */
 private MXMLBindingNode generateBindingNode(
     MXMLTagAttributeData attr, IMXMLSingleDataBindingNode dbnode) {
   return generateBindingNode(attr.getParent(), attr, dbnode);
 }