return ;
  public void toXDFOutputStream (                                   OutputStream outputstream,                                   Hashtable XMLDeclAttribs,                                   String indent,                                   boolean dontCloseNode,                                   String newNodeNameString,                                   String noChildObjectNodeName                                )  {    String nodeNameString = this.classXDFNodeName;    // Setup. Sometimes the name of the node we are opening is different from    // that specified in the classXDFNodeName (*sigh*)    if (newNodeNameString != null) nodeNameString = newNodeNameString;    // 0. To be valid XML, we always start an XML block with an    //    XML declaration (e.g. somehting like "<?xml standalone="no"?>").    //    Here we deal with  printing out XML Declaration && its attributes    if ((XMLDeclAttribs !=null) &&(!XMLDeclAttribs.isEmpty())) {        indent = "";        writeXMLDeclToOutputStream(outputstream, XMLDeclAttribs);    }    // 1. open this node, print its simple XML attributes    if (nodeNameString != null) {      if (sPrettyXDFOutput)        writeOut(outputstream, indent); // indent node if desired      // For printing the opening statement we need to invoke a little      // Voodoo to keep the DTD happy: the first structure node is always      // called by the root node name instead of the usual nodeNameString      // We can tell this by checking if this object is derived from class      // Structure and if XMLDeclAttrib defined/populated with information      // NOTE: This isnt really the way to do this. We need to check if 'this' is      // is or has as a superclass xdf.Structure instead of the 'string check' below.      // check is class Strucuture & XMLDeclAttribs populated?      if ( nodeNameString.equals(sXDFStructureNodeName) && !XMLDeclAttribs.isEmpty() )      {        writeOut(outputstream,"<" + sXDFRootNodeName); // print opening root node statement      } else {        writeOut(outputstream,"<" + nodeNameString);   // print opening statement      }    }    // gather info about XMLAttributes in this object/node    Hashtable xmlInfo = getXMLInfo();    // 2. Print out string object XML attributes EXCEPT for the one that    //    matches PCDATAAttribute.    ArrayList attribs = (ArrayList) xmlInfo.get("attribList");    // is synchronized here correct?    synchronized(attribs) {      for (int i = 0; i < attribs.size(); i++) {        Hashtable item = (Hashtable) attribs.get(i);        writeOut(outputstream, " "+ item.get("name") + "=\"" + item.get("value") + "\"");      }    }    // 3. Print out Node PCData or Child Nodes as specified by object ref    //    XML attributes. The way this stuff occurs will also affect how we    //    close the node.    ArrayList childObjs = (ArrayList) xmlInfo.get("childObjList");    String pcdata = (String) xmlInfo.get("PCDATA");    //it is the simplest node, with opening/closing node, no child, no PCDATA    if ( childObjs.size() == 0 && pcdata == null && noChildObjectNodeName == null){      writeOut(outputstream, "></" + nodeNameString + ">");      if (sPrettyXDFOutput)        writeOut(outputstream, Constants.NEW_LINE);      return ;    }    if ( childObjs.size() > 0 || pcdata != null || noChildObjectNodeName != null)    {      // close the opening tag      if (nodeNameString != null) {        writeOut(outputstream, ">");        if ((sPrettyXDFOutput) && (pcdata == null)  && (childObjs.size() !=0))          writeOut(outputstream, Constants.NEW_LINE);      }      // deal with object/list XML attributes, if any in our list      for (int i = 0; i < childObjs.size(); i++) {        Hashtable item = (Hashtable) childObjs.get(i);        if (item.get("type") == Constants.LIST_TYPE)        {          List objectList = (List) item.get("value");          // Im not sure this synchronized wrapper is needed, we are          // only accessing stuff here.. Also, should synchronzied wrapper          // occur back in the getXMLInfo method instead where the orig          // access occured?!?          synchronized(objectList) {            Iterator iter = objectList.iterator(); // Must be in synchronized block            while (iter.hasNext()) {              BaseObject containedObj = (BaseObject) iter.next();              if (containedObj != null) { // can happen from pre-allocation of axis values, etc (?)                String newindent = indent + sPrettyXDFOutputIndentation;                dealWithOpeningGroupNodes(containedObj, outputstream, indent);                dealWithClosingGroupNodes(containedObj, outputstream, indent);                containedObj.toXDFOutputStream(outputstream, new Hashtable(), newindent);              }            }          }        }        else if (item.get("type") == Constants.OBJECT_TYPE)        {          BaseObject containedObj = (BaseObject) item.get("value");          if (containedObj != null) { // can happen from pre-allocation of axis values, etc (?)            // shouldnt this be synchronized too??            synchronized(containedObj) {              String newindent = indent + sPrettyXDFOutputIndentation;              dealWithOpeningGroupNodes(containedObj, outputstream, indent);              dealWithClosingGroupNodes(containedObj, outputstream, indent);              containedObj.toXDFOutputStream(outputstream, new Hashtable(), newindent);            }          }        } else {          // error: weird type, actually shouldnt occur. Is this needed??          Log.errorln("Weird error: unknown XML attribute type for item:"+item);        }      }      // print out PCDATA, if any      if(pcdata != null)  {        writeOut(outputstream, pcdata);        //write out closing node after PCDATA, leaving no space between them.        //k.z. 10/18/2000        if (!dontCloseNode)          if ( nodeNameString.equals(sXDFStructureNodeName) && !XMLDeclAttribs.isEmpty() )          {            writeOut(outputstream, "</"+sXDFRootNodeName+">");          } else {            writeOut(outputstream, "</"+nodeNameString+">");          }        if (sPrettyXDFOutput)          writeOut(outputstream, Constants.NEW_LINE);        return ; //now we are done, return!        //k.z. 10/18/2000      };      // if there are no PCDATA or child objects/nodes then      // we print out noChildObjectNodeName and close the node      if ( childObjs.size() == 0 && pcdata == null && noChildObjectNodeName != null)      {        writeOut(outputstream, "<" + noChildObjectNodeName + "/>");        writeOut(outputstream, "</"+nodeNameString + ">");        if (sPrettyXDFOutput)          writeOut(outputstream, Constants.NEW_LINE);        return ;      }      // ok, now deal with closing the node      if (nodeNameString != null) {        // Needed??        //dealWithClosingGroupNodes(containedObj, outputstream, indent);        //Brian: we have to fix this, no whitespace should be allowed between        //PCDATA and closing node        if (sPrettyXDFOutput) writeOut(outputstream, indent);        if (!dontCloseNode)          if ( nodeNameString.equals(sXDFStructureNodeName) && !XMLDeclAttribs.isEmpty() )          {            writeOut(outputstream, "</"+sXDFRootNodeName+">");          } else {            writeOut(outputstream, "</"+nodeNameString+">");          }      }    } else {      if(dontCloseNode) {         // it may not have sub-objects, but we dont want to close it         // (happens for group objects)      } else {        // no sub-objects, just close this node        writeOut(outputstream, "/>");      }    }    if (sPrettyXDFOutput) writeOut(outputstream, Constants.NEW_LINE);  }