/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id:  $
 */

package org.apache.xml.serializer.dom3;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;

import org.apache.xml.serializer.dom3.NamespaceSupport;
import org.apache.xml.serializer.OutputPropertiesFactory;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.serializer.utils.MsgKey;
import org.apache.xml.serializer.utils.Utils;
import org.apache.xml.serializer.utils.XML11Char;
import org.apache.xml.serializer.utils.XMLChar;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.w3c.dom.ls.LSSerializerFilter;
import org.w3c.dom.traversal.NodeFilter;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.LocatorImpl;

/**
 * Built on org.apache.xml.serializer.TreeWalker and adds functionality to
 * traverse and serialize a DOM Node (Level 2 or Level 3) as specified in 
 * the DOM Level 3 LS Recommedation by evaluating and applying DOMConfiguration 
 * parameters and filters if any during serialization.
 *   
 * @xsl.usage internal
 */
final class DOM3TreeWalker {

    /**
     * The SerializationHandler, it extends ContentHandler and when
     * this class is instantiated via the constructor provided, a
     * SerializationHandler object is passed to it.
     */
    private SerializationHandler fSerializer = null;

    /** We do not need DOM2Helper since DOM Level 3 LS applies to DOM Level 2 or newer */

    /** Locator object for this TreeWalker          */
    private LocatorImpl fLocator = new LocatorImpl();

    /** ErrorHandler */
    private DOMErrorHandler fErrorHandler = null;

    /** LSSerializerFilter */
    private LSSerializerFilter fFilter = null;

    /** If the serializer is an instance of a LexicalHandler */
    private LexicalHandler fLexicalHandler = null;

    private int fWhatToShowFilter;

    /** New Line character to use in serialization */
    private char[] fNewLine = null;

    /** DOMConfiguration Properties */
    private Properties fDOMConfigProperties = null;

    /** Keeps track if we are in an entity reference when entities=true */
    private boolean fInEntityRef = false;

    /** Stores the version of the XML document to be serialize */
    private String fXMLVersion = null;

    /** XML Version, default 1.0 */
    private boolean fIsXMLVersion11 = false;

    /** Is the Node a Level 3 DOM node */
    private boolean fIsLevel3DOM = false;

    /** DOM Configuration Parameters */
    private int fFeatures = 0;

    /** Flag indicating whether following text to be processed is raw text          */
    boolean fNextIsRaw = false;

    // 
    private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";

    //
    private static final String XMLNS_PREFIX = "xmlns";

    // 
    private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";

    // 
    private static final String XML_PREFIX = "xml";

    /** stores namespaces in scope */
    protected NamespaceSupport fNSBinder;

    /** stores all namespace bindings on the current element */
    protected NamespaceSupport fLocalNSBinder;
    
    /** stores the current element depth */
    private int fElementDepth = 0;

    // ***********************************************************************
    // DOMConfiguration paramter settings 
    // ***********************************************************************
    // Parameter canonical-form, true [optional] - NOT SUPPORTED 
    private final static int CANONICAL = 0x1 << 0;

    // Parameter cdata-sections, true [required] (default)
    private final static int CDATA = 0x1 << 1;

    // Parameter check-character-normalization, true [optional] - NOT SUPPORTED 
    private final static int CHARNORMALIZE = 0x1 << 2;

    // Parameter comments, true [required] (default)
    private final static int COMMENTS = 0x1 << 3;

    // Parameter datatype-normalization, true [optional] - NOT SUPPORTED
    private final static int DTNORMALIZE = 0x1 << 4;

    // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED
    private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5;

    // Parameter entities, true [required] (default)
    private final static int ENTITIES = 0x1 << 6;

    // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer
    private final static int INFOSET = 0x1 << 7;

    // Parameter namespaces, true [required] (default)
    private final static int NAMESPACES = 0x1 << 8;

    // Parameter namespace-declarations, true [required] (default)
    private final static int NAMESPACEDECLS = 0x1 << 9;

    // Parameter normalize-characters, true [optional] - NOT SUPPORTED
    private final static int NORMALIZECHARS = 0x1 << 10;

    // Parameter split-cdata-sections, true [required] (default)
    private final static int SPLITCDATA = 0x1 << 11;

    // Parameter validate, true [optional] - NOT SUPPORTED
    private final static int VALIDATE = 0x1 << 12;

    // Parameter validate-if-schema, true [optional] - NOT SUPPORTED
    private final static int SCHEMAVALIDATE = 0x1 << 13;

    // Parameter split-cdata-sections, true [required] (default)
    private final static int WELLFORMED = 0x1 << 14;

    // Parameter discard-default-content, true [required] (default)
    // Not sure how this will be used in level 2 Documents
    private final static int DISCARDDEFAULT = 0x1 << 15;

    // Parameter format-pretty-print, true [optional] 
    private final static int PRETTY_PRINT = 0x1 << 16;

    // Parameter ignore-unknown-character-denormalizations, true [required] (default)
    // We currently do not support XML 1.1 character normalization
    private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17;

    // Parameter discard-default-content, true [required] (default)
    private final static int XMLDECL = 0x1 << 18;

    /**
     * Constructor.
     * @param   contentHandler serialHandler The implemention of the SerializationHandler interface
     */
    DOM3TreeWalker(
        SerializationHandler serialHandler,
        DOMErrorHandler errHandler,
        LSSerializerFilter filter,
        char[] newLine) {
        fSerializer = serialHandler;
        //fErrorHandler = errHandler == null ? new DOMErrorHandlerImpl() : errHandler; // Should we be using the default?
        fErrorHandler = errHandler;
        fFilter = filter;
        fLexicalHandler = null;
        fNewLine = newLine;

        fNSBinder = new NamespaceSupport();
        fLocalNSBinder = new NamespaceSupport();
        
        fDOMConfigProperties = fSerializer.getOutputFormat();
        fSerializer.setDocumentLocator(fLocator);
        initProperties(fDOMConfigProperties);
        
        try {
            // Bug see Bugzilla  26741
            fLocator.setSystemId(
                System.getProperty("user.dir") + File.separator + "dummy.xsl");
        } catch (SecurityException se) { // user.dir not accessible from applet

        }
    }

    /**
     * Perform a pre-order traversal non-recursive style.  
     *
     * Note that TreeWalker assumes that the subtree is intended to represent 
     * a complete (though not necessarily well-formed) document and, during a 
     * traversal, startDocument and endDocument will always be issued to the 
     * SAX listener.
     *  
     * @param pos Node in the tree where to start traversal
     *
     * @throws TransformerException
     */
    public void traverse(Node pos) throws org.xml.sax.SAXException {
        this.fSerializer.startDocument();

        // Determine if the Node is a DOM Level 3 Core Node.
        if (pos.getNodeType() != Node.DOCUMENT_NODE) {
            Document ownerDoc = pos.getOwnerDocument();
            if (ownerDoc != null
                && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
                fIsLevel3DOM = true;
            }
        } else {
            if (((Document) pos)
                .getImplementation()
                .hasFeature("Core", "3.0")) {
                fIsLevel3DOM = true;
            }
        }

        if (fSerializer instanceof LexicalHandler) {
            fLexicalHandler = ((LexicalHandler) this.fSerializer);
        }

        if (fFilter != null)
            fWhatToShowFilter = fFilter.getWhatToShow();

        Node top = pos;

        while (null != pos) {
            startNode(pos);

            Node nextNode = null;

            nextNode = pos.getFirstChild();

            while (null == nextNode) {
                endNode(pos);

                if (top.equals(pos))
                    break;

                nextNode = pos.getNextSibling();

                if (null == nextNode) {
                    pos = pos.getParentNode();

                    if ((null == pos) || (top.equals(pos))) {
                        if (null != pos)
                            endNode(pos);

                        nextNode = null;

                        break;
                    }
                }
            }

            pos = nextNode;
        }
        this.fSerializer.endDocument();
    }

    /**
     * Perform a pre-order traversal non-recursive style.
     
     * Note that TreeWalker assumes that the subtree is intended to represent 
     * a complete (though not necessarily well-formed) document and, during a 
     * traversal, startDocument and endDocument will always be issued to the 
     * SAX listener.
     *
     * @param pos Node in the tree where to start traversal
     * @param top Node in the tree where to end traversal
     *
     * @throws TransformerException
     */
    public void traverse(Node pos, Node top) throws org.xml.sax.SAXException {

        this.fSerializer.startDocument();

        // Determine if the Node is a DOM Level 3 Core Node.
        if (pos.getNodeType() != Node.DOCUMENT_NODE) {
            Document ownerDoc = pos.getOwnerDocument();
            if (ownerDoc != null
                && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
                fIsLevel3DOM = true;
            }
        } else {
            if (((Document) pos)
                .getImplementation()
                .hasFeature("Core", "3.0")) {
                fIsLevel3DOM = true;
            }
        }

        if (fSerializer instanceof LexicalHandler) {
            fLexicalHandler = ((LexicalHandler) this.fSerializer);
        }

        if (fFilter != null)
            fWhatToShowFilter = fFilter.getWhatToShow();

        while (null != pos) {
            startNode(pos);

            Node nextNode = null;

            nextNode = pos.getFirstChild();

            while (null == nextNode) {
                endNode(pos);

                if ((null != top) && top.equals(pos))
                    break;

                nextNode = pos.getNextSibling();

                if (null == nextNode) {
                    pos = pos.getParentNode();

                    if ((null == pos) || ((null != top) && top.equals(pos))) {
                        nextNode = null;

                        break;
                    }
                }
            }

            pos = nextNode;
        }
        this.fSerializer.endDocument();
    }

    /**
     * Optimized dispatch of characters.
     */
    private final void dispatachChars(Node node)
        throws org.xml.sax.SAXException {
        if (fSerializer != null) {
            this.fSerializer.characters(node);
        } else {
            String data = ((Text) node).getData();
            this.fSerializer.characters(data.toCharArray(), 0, data.length());
        }
    }

    /**
     * Start processing given node
     *
     * @param node Node to process
     *
     * @throws org.xml.sax.SAXException
     */
    protected void startNode(Node node) throws org.xml.sax.SAXException {
        if (node instanceof Locator) {
            Locator loc = (Locator) node;
            fLocator.setColumnNumber(loc.getColumnNumber());
            fLocator.setLineNumber(loc.getLineNumber());
            fLocator.setPublicId(loc.getPublicId());
            fLocator.setSystemId(loc.getSystemId());
        } else {
            fLocator.setColumnNumber(0);
            fLocator.setLineNumber(0);
        }

        switch (node.getNodeType()) {
            case Node.DOCUMENT_TYPE_NODE :
                serializeDocType((DocumentType) node, true);
                break;
            case Node.COMMENT_NODE :
                serializeComment((Comment) node);
                break;
            case Node.DOCUMENT_FRAGMENT_NODE :
                // Children are traversed
                break;
            case Node.DOCUMENT_NODE :
                break;
            case Node.ELEMENT_NODE :
                serializeElement((Element) node, true);
                break;
            case Node.PROCESSING_INSTRUCTION_NODE :
                serializePI((ProcessingInstruction) node);
                break;
            case Node.CDATA_SECTION_NODE :
                serializeCDATASection((CDATASection) node);
                break;
            case Node.TEXT_NODE :
                serializeText((Text) node);
                break;
            case Node.ENTITY_REFERENCE_NODE :
                serializeEntityReference((EntityReference) node, true);
                break;
            default :
                }
    }

    /**
     * End processing of given node 
     *
     *
     * @param node Node we just finished processing
     *
     * @throws org.xml.sax.SAXException
     */
    protected void endNode(Node node) throws org.xml.sax.SAXException {

        switch (node.getNodeType()) {
            case Node.DOCUMENT_NODE :
                break;
            case Node.DOCUMENT_TYPE_NODE :
                serializeDocType((DocumentType) node, false);
                break;
            case Node.ELEMENT_NODE :
                serializeElement((Element) node, false);
                break;
            case Node.CDATA_SECTION_NODE :
                break;
            case Node.ENTITY_REFERENCE_NODE :
                serializeEntityReference((EntityReference) node, false);
                break;
            default :
                }
    }

    // ***********************************************************************
    // Node serialization methods
    // ***********************************************************************
    /**
     * Applies a filter on the node to serialize
     * 
     * @param node The Node to serialize
     * @return True if the node is to be serialized else false if the node 
     *         is to be rejected or skipped. 
     */
    protected boolean applyFilter(Node node, int nodeType) {
        if (fFilter != null && (fWhatToShowFilter & nodeType) != 0) {

            short code = fFilter.acceptNode(node);
            switch (code) {
                case NodeFilter.FILTER_REJECT :
                case NodeFilter.FILTER_SKIP :
                    return false; // skip the node
                default : // fall through..
            }
        }
        return true;
    }

    /**
     * Serializes a Document Type Node.
     * 
     * @param node The Docuemnt Type Node to serialize
     * @param bStart Invoked at the start or end of node.  Default true. 
     */
    protected void serializeDocType(DocumentType node, boolean bStart)
        throws SAXException {
        // The DocType and internalSubset can not be modified in DOM and is
        // considered to be well-formed as the outcome of successful parsing.
        String docTypeName = node.getNodeName();
        String publicId = node.getPublicId();
        String systemId = node.getSystemId();
        String internalSubset = node.getInternalSubset();

        //DocumentType nodes are never passed to the filter
        
        if (internalSubset != null && !"".equals(internalSubset)) {

            if (bStart) {
                try {
                    // The Serializer does not provide a way to write out the
                    // DOCTYPE internal subset via an event call, so we write it
                    // out here.
                    Writer writer = fSerializer.getWriter();
                    StringBuffer dtd = new StringBuffer();

                    dtd.append("<!DOCTYPE ");
                    dtd.append(docTypeName);
                    if (null != publicId) {
                        dtd.append(" PUBLIC \"");
                        dtd.append(publicId);
                        dtd.append('\"');
                    }

                    if (null != systemId) {
                        if (null == publicId) {
                            dtd.append(" SYSTEM \"");
                        } else {
                            dtd.append(" \"");
                        }    
                        dtd.append(systemId);
                        dtd.append('\"');
                    }
                    
                    dtd.append(" [ ");
                    
                    dtd.append(fNewLine);
                    dtd.append(internalSubset);
                    dtd.append("]>");
                    dtd.append(new String(fNewLine));
                    
                    writer.write(dtd.toString());
                    writer.flush();
                    
                } catch (IOException e) {
                    throw new SAXException(Utils.messages.createMessage(
                            MsgKey.ER_WRITING_INTERNAL_SUBSET, null), e);
                }
            } // else if !bStart do nothing
            
        } else {
            
            if (bStart) {
                if (fLexicalHandler != null) {
                    fLexicalHandler.startDTD(docTypeName, publicId, systemId);
                }
            } else {
                if (fLexicalHandler != null) {
                    fLexicalHandler.endDTD();
                }
            }
        }
    }

    /**
     * Serializes a Comment Node.
     * 
     * @param node The Comment Node to serialize
     */
    protected void serializeComment(Comment node) throws SAXException {
        // comments=true
        if ((fFeatures & COMMENTS) != 0) {
            String data = node.getData();

            // well-formed=true
            if ((fFeatures & WELLFORMED) != 0) {
                isCommentWellFormed(data);
            }

            if (fLexicalHandler != null) {
                // apply the LSSerializer filter after the operations requested by the 
                // DOMConfiguration parameters have been applied 
                if (!applyFilter(node, NodeFilter.SHOW_COMMENT)) {
                    return;
                }

                fLexicalHandler.comment(data.toCharArray(), 0, data.length());
            }
        }
    }

    /**
     * Serializes an Element Node.
     * 
     * @param node The Element Node to serialize
     * @param bStart Invoked at the start or end of node.   
     */
    protected void serializeElement(Element node, boolean bStart)
        throws SAXException {
        if (bStart) {
            fElementDepth++;

            // We use the Xalan specific startElement and starPrefixMapping calls 
            // (and addAttribute and namespaceAfterStartElement) as opposed to
            // SAX specific, for performance reasons as they reduce the overhead
            // of creating an AttList object upfront.

            // well-formed=true
            if ((fFeatures & WELLFORMED) != 0) {
                isElementWellFormed(node);
            }

            // REVISIT: We apply the LSSerializer filter for elements before
            // namesapce fixup
            if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
                return;
            }

            // namespaces=true, record and fixup namspaced element
            if ((fFeatures & NAMESPACES) != 0) {
            	fNSBinder.pushContext();
            	fLocalNSBinder.reset();
            	
                recordLocalNSDecl(node);
                fixupElementNS(node);
            }

            // Namespace normalization
            fSerializer.startElement(
            		node.getNamespaceURI(),
                    node.getLocalName(),
                    node.getNodeName());

            serializeAttList(node);
            
        } else {
        	fElementDepth--;

            // apply the LSSerializer filter
            if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
                return;
            }

            this.fSerializer.endElement(
            	node.getNamespaceURI(),
                node.getLocalName(),
                node.getNodeName());
            // since endPrefixMapping was not used by SerializationHandler it was removed
            // for performance reasons.

            if ((fFeatures & NAMESPACES) != 0 ) {
                    fNSBinder.popContext();
            }
            
        }
    }

    /**
     * Serializes the Attr Nodes of an Element.
     * 
     * @param node The OwnerElement whose Attr Nodes are to be serialized.
     */
    protected void serializeAttList(Element node) throws SAXException {
        NamedNodeMap atts = node.getAttributes();
        int nAttrs = atts.getLength();

        for (int i = 0; i < nAttrs; i++) {
            Node attr = atts.item(i);

            String localName = attr.getLocalName();
            String attrName = attr.getNodeName();
            String attrPrefix = attr.getPrefix() == null ? "" : attr.getPrefix();
            String attrValue = attr.getNodeValue();

            // Determine the Attr's type.
            String type = null;
            if (fIsLevel3DOM) {
                type = ((Attr) attr).getSchemaTypeInfo().getTypeName();
            }
            type = type == null ? "CDATA" : type;

            String attrNS = attr.getNamespaceURI();
            if (attrNS !=null && attrNS.length() == 0) {
            	attrNS=null;
                // we must remove prefix for this attribute
            	attrName=attr.getLocalName();
            }

            boolean isSpecified = ((Attr) attr).getSpecified();
            boolean addAttr = true;
            boolean applyFilter = false;
            boolean xmlnsAttr =
                attrName.equals("xmlns") || attrName.startsWith("xmlns:");

            // well-formed=true
            if ((fFeatures & WELLFORMED) != 0) {
                isAttributeWellFormed(attr);
            }
            
            //-----------------------------------------------------------------
            // start Attribute namespace fixup
            //-----------------------------------------------------------------
            // namespaces=true, normalize all non-namespace attributes
            // Step 3. Attribute
            if ((fFeatures & NAMESPACES) != 0 && !xmlnsAttr) {
           	
        		// If the Attr has a namespace URI
        		if (attrNS != null) {
        			attrPrefix = attrPrefix == null ? "" : attrPrefix;

        			String declAttrPrefix = fNSBinder.getPrefix(attrNS);
        			String declAttrNS = fNSBinder.getURI(attrPrefix);
        			
        			// attribute has no prefix (default namespace decl does not apply to
        			// attributes)
        			// OR
        			// attribute prefix is not declared
        			// OR
        			// conflict: attribute has a prefix that conflicts with a binding
        			if ("".equals(attrPrefix) || "".equals(declAttrPrefix)
        					|| !attrPrefix.equals(declAttrPrefix)) {

        				// namespaceURI matches an in scope declaration of one or
        				// more prefixes
        				if (declAttrPrefix != null && !"".equals(declAttrPrefix)) {
        					// pick the prefix that was found and change attribute's
        					// prefix and nodeName.
        					attrPrefix = declAttrPrefix;
        					
        					if (declAttrPrefix.length() > 0 ) { 
        						attrName = declAttrPrefix + ":" + localName;
        					} else {
        						attrName = localName;
        					}	
        				} else {
        					// The current prefix is not null and it has no in scope
        					// declaration
        					if (attrPrefix != null && !"".equals(attrPrefix)
        							&& declAttrNS == null) {
        						// declare this prefix
        						if ((fFeatures & NAMESPACEDECLS) != 0) {
        							fSerializer.addAttribute(XMLNS_URI, attrPrefix,
        									XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
        									attrNS);
        							fNSBinder.declarePrefix(attrPrefix, attrNS);
        							fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
        						}
        					} else {
        						// find a prefix following the pattern "NS" +index
        						// (starting at 1)
        						// make sure this prefix is not declared in the current
        						// scope.
        						int counter = 1;
        						attrPrefix = "NS" + counter++;

        						while (fLocalNSBinder.getURI(attrPrefix) != null) {
        							attrPrefix = "NS" + counter++;
        						}
        						// change attribute's prefix and Name
        						attrName = attrPrefix + ":" + localName;
        						
        						// create a local namespace declaration attribute
        						// Add the xmlns declaration attribute
        						if ((fFeatures & NAMESPACEDECLS) != 0) {
                                       							
        							fSerializer.addAttribute(XMLNS_URI, attrPrefix,
        									XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
        									attrNS);
            						fNSBinder.declarePrefix(attrPrefix, attrNS);
            						fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
        						}
        					}
        				}
        			}

        		} else { // if the Attr has no namespace URI
        			// Attr has no localName
        			if (localName == null) {
        				// DOM Level 1 node!
        				String msg = Utils.messages.createMessage(
        						MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
        						new Object[] { attrName });

        				if (fErrorHandler != null) {
        					fErrorHandler
        							.handleError(new DOMErrorImpl(
        									DOMError.SEVERITY_ERROR, msg,
        									MsgKey.ER_NULL_LOCAL_ELEMENT_NAME, null,
        									null, null));
        				}

        			} else { // uri=null and no colon
        				// attr has no namespace URI and no prefix
        				// no action is required, since attrs don't use default
        			}
        		}

            }

            
            // discard-default-content=true
            // Default attr's are not passed to the filter and this contraint
            // is applied only when discard-default-content=true 
            // What about default xmlns attributes???? check for xmlnsAttr
            if ((((fFeatures & DISCARDDEFAULT) != 0) && isSpecified)
                || ((fFeatures & DISCARDDEFAULT) == 0)) {
                applyFilter = true;
            } else {
            	addAttr = false;
            }

            if (applyFilter) {
                // apply the filter for Attributes that are not default attributes
                // or namespace decl attributes
                if (fFilter != null
                    && (fFilter.getWhatToShow() & NodeFilter.SHOW_ATTRIBUTE)
                        != 0) {

                    if (!xmlnsAttr) {
                        short code = fFilter.acceptNode(attr);
                        switch (code) {
                            case NodeFilter.FILTER_REJECT :
                            case NodeFilter.FILTER_SKIP :
                                addAttr = false;
                                break;
                            default : //fall through..
                        }
                    }
                }
            }

            // if the node is a namespace node
            if (addAttr && xmlnsAttr) {
                // If namespace-declarations=true, add the node , else don't add it
                if ((fFeatures & NAMESPACEDECLS) != 0) {
               		// The namespace may have been fixed up, in that case don't add it.
                	if (localName != null && !"".equals(localName)) {
                		fSerializer.addAttribute(attrNS, localName, attrName, type, attrValue);
                	} 
                }
            } else if (
                addAttr && !xmlnsAttr) { // if the node is not a namespace node
                // If namespace-declarations=true, add the node with the Attr nodes namespaceURI
                // else add the node setting it's namespace to null or else the serializer will later
                // attempt to add a xmlns attr for the prefixed attribute
                if (((fFeatures & NAMESPACEDECLS) != 0) && (attrNS != null)) {
                    fSerializer.addAttribute(
                        attrNS,
                        localName,
                        attrName,
                        type,
                        attrValue);
                } else {
                    fSerializer.addAttribute(
                        "",
                        localName,
                        attrName,
                        type,
                        attrValue);
                }
            }

            // 
            if (xmlnsAttr && ((fFeatures & NAMESPACEDECLS) != 0)) {
                int index;
                // Use "" instead of null, as Xerces likes "" for the 
                // name of the default namespace.  Fix attributed 
                // to "Steven Murray" <smurray@ebt.com>.
                String prefix =
                    (index = attrName.indexOf(":")) < 0
                        ? ""
                        : attrName.substring(index + 1);

                if (!"".equals(prefix)) {
                    fSerializer.namespaceAfterStartElement(prefix, attrValue);
                }
            }
        }
        
    }
   
    /**
     * Serializes an ProcessingInstruction Node.
     * 
     * @param node The ProcessingInstruction Node to serialize
     */
    protected void serializePI(ProcessingInstruction node)
        throws SAXException {
        ProcessingInstruction pi = node;
        String name = pi.getNodeName();

        // well-formed=true
        if ((fFeatures & WELLFORMED) != 0) {
            isPIWellFormed(node);
        }

        // apply the LSSerializer filter
        if (!applyFilter(node, NodeFilter.SHOW_PROCESSING_INSTRUCTION)) {
            return;
        }

        // String data = pi.getData();
        if (name.equals("xslt-next-is-raw")) {
            fNextIsRaw = true;
        } else {
            this.fSerializer.processingInstruction(name, pi.getData());
        }
    }

    /**
     * Serializes an CDATASection Node.
     * 
     * @param node The CDATASection Node to serialize
     */
    protected void serializeCDATASection(CDATASection node)
        throws SAXException {
        // well-formed=true
        if ((fFeatures & WELLFORMED) != 0) {
            isCDATASectionWellFormed(node);
        }

        // cdata-sections = true
        if ((fFeatures & CDATA) != 0) {

            // split-cdata-sections = true
            // Assumption: This parameter has an effect only when
			// cdata-sections=true
            // ToStream, by default splits cdata-sections. Hence the check
			// below.
            String nodeValue = node.getNodeValue();
            int endIndex = nodeValue.indexOf("]]>");
            if ((fFeatures & SPLITCDATA) != 0) {
                if (endIndex >= 0) {
                    // The first node split will contain the ]] markers
                    String relatedData = nodeValue.substring(0, endIndex + 2);

                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_CDATA_SECTIONS_SPLIT,
                            null);

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_WARNING,
                                msg,
                                MsgKey.ER_CDATA_SECTIONS_SPLIT,
                                null,
                                relatedData,
                                null));
                    }
                }
            } else {
                if (endIndex >= 0) {
                    // The first node split will contain the ]] markers 
                    String relatedData = nodeValue.substring(0, endIndex + 2);

                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_CDATA_SECTIONS_SPLIT,
                            null);

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_ERROR,
                                msg,
                                MsgKey.ER_CDATA_SECTIONS_SPLIT));
                    }
                    // Report an error and return.  What error???
                    return;
                }
            }

            // apply the LSSerializer filter
            if (!applyFilter(node, NodeFilter.SHOW_CDATA_SECTION)) {
                return;
            }

            // splits the cdata-section
            if (fLexicalHandler != null) {
                fLexicalHandler.startCDATA();
            }
            dispatachChars(node);
            if (fLexicalHandler != null) {
                fLexicalHandler.endCDATA();
            }
        } else {
            dispatachChars(node);
        }
    }

    /**
     * Serializes an Text Node.
     * 
     * @param node The Text Node to serialize
     */
    protected void serializeText(Text node) throws SAXException {
        if (fNextIsRaw) {
            fNextIsRaw = false;
            fSerializer.processingInstruction(
                javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING,
                "");
            dispatachChars(node);
            fSerializer.processingInstruction(
                javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING,
                "");
        } else {
            // keep track of dispatch or not to avoid duplicaiton of filter code
            boolean bDispatch = false;

            // well-formed=true
            if ((fFeatures & WELLFORMED) != 0) {
                isTextWellFormed(node);
            }

            // if the node is whitespace
            // Determine the Attr's type.
            boolean isElementContentWhitespace = false;
            if (fIsLevel3DOM) {
                isElementContentWhitespace =
                       node.isElementContentWhitespace();
            }

            if (isElementContentWhitespace) {
                // element-content-whitespace=true
                if ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) {
                    bDispatch = true;
                }
            } else {
                bDispatch = true;
            }

            // apply the LSSerializer filter
            if (!applyFilter(node, NodeFilter.SHOW_TEXT)) {
                return;
            }

            if (bDispatch) {
                dispatachChars(node);
            }
        }
    }

    /**
     * Serializes an EntityReference Node.
     * 
     * @param node The EntityReference Node to serialize
     * @param bStart Inicates if called from start or endNode 
     */
    protected void serializeEntityReference(
        EntityReference node,
        boolean bStart)
        throws SAXException {
        if (bStart) {
            EntityReference eref = node;
            // entities=true
            if ((fFeatures & ENTITIES) != 0) {
                
                // perform well-formedness and other checking only if 
                // entities = true

                // well-formed=true
                if ((fFeatures & WELLFORMED) != 0) {
                    isEntityReferneceWellFormed(node);
                }

                // check "unbound-prefix-in-entity-reference" [fatal] 
                // Raised if the configuration parameter "namespaces" is set to true
                if ((fFeatures & NAMESPACES) != 0) {
                    checkUnboundPrefixInEntRef(node);
                }

                // The filter should not apply in this case, since the
                // EntityReference is not being expanded.
                // should we pass entity reference nodes to the filter???
            } 
            
            if (fLexicalHandler != null) {

                // startEntity outputs only Text but not Element, Attr, Comment 
                // and PI child nodes.  It does so by setting the m_inEntityRef 
                // in ToStream and using this to decide if a node is to be 
                // serialized or not.
                fLexicalHandler.startEntity(eref.getNodeName());
            } 

        } else {
            EntityReference eref = node;
            // entities=true or false, 
            if (fLexicalHandler != null) {
                fLexicalHandler.endEntity(eref.getNodeName());
            }
        }
    }

    
    // ***********************************************************************
    // Methods to check well-formedness
    // ***********************************************************************
    /**
     * Taken from org.apache.xerces.dom.CoreDocumentImpl
     * 
     * Check the string against XML's definition of acceptable names for
     * elements and attributes and so on using the XMLCharacterProperties
     * utility class
     */
    protected boolean isXMLName(String s, boolean xml11Version) {

        if (s == null) {
            return false;
        }
        if (!xml11Version)
            return XMLChar.isValidName(s);
        else
            return XML11Char.isXML11ValidName(s);
    }

    /**
     * Taken from org.apache.xerces.dom.CoreDocumentImpl
     *  
     * Checks if the given qualified name is legal with respect
     * to the version of XML to which this document must conform.
     *
     * @param prefix prefix of qualified name
     * @param local local part of qualified name
     */
    protected boolean isValidQName(
        String prefix,
        String local,
        boolean xml11Version) {

        // check that both prefix and local part match NCName
        if (local == null)
            return false;
        boolean validNCName = false;

        if (!xml11Version) {
            validNCName =
                (prefix == null || XMLChar.isValidNCName(prefix))
                    && XMLChar.isValidNCName(local);
        } else {
            validNCName =
                (prefix == null || XML11Char.isXML11ValidNCName(prefix))
                    && XML11Char.isXML11ValidNCName(local);
        }

        return validNCName;
    }

    /**
     * Checks if a XML character is well-formed
     * 
     * @param characters A String of characters to be checked for Well-Formedness
     * @param refInvalidChar A reference to the character to be returned that was determined invalid. 
     */
    protected boolean isWFXMLChar(String chardata, Character refInvalidChar) {
        if (chardata == null || (chardata.length() == 0)) {
            return true;
        }

        char[] dataarray = chardata.toCharArray();
        int datalength = dataarray.length;

        // version of the document is XML 1.1
        if (fIsXMLVersion11) {
            //we need to check all characters as per production rules of XML11
            int i = 0;
            while (i < datalength) {
                if (XML11Char.isXML11Invalid(dataarray[i++])) {
                    // check if this is a supplemental character
                    char ch = dataarray[i - 1];
                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
                        char ch2 = dataarray[i++];
                        if (XMLChar.isLowSurrogate(ch2)
                            && XMLChar.isSupplemental(
                                XMLChar.supplemental(ch, ch2))) {
                            continue;
                        }
                    }
                    // Reference to invalid character which is returned
                    refInvalidChar = new Character(ch);
                    return false;
                }
            }
        } // version of the document is XML 1.0
        else {
            // we need to check all characters as per production rules of XML 1.0
            int i = 0;
            while (i < datalength) {
                if (XMLChar.isInvalid(dataarray[i++])) {
                    // check if this is a supplemental character
                    char ch = dataarray[i - 1];
                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
                        char ch2 = dataarray[i++];
                        if (XMLChar.isLowSurrogate(ch2)
                            && XMLChar.isSupplemental(
                                XMLChar.supplemental(ch, ch2))) {
                            continue;
                        }
                    }
                    // Reference to invalid character which is returned                    
                    refInvalidChar = new Character(ch);
                    return false;
                }
            }
        } // end-else fDocument.isXMLVersion()

        return true;
    } // isXMLCharWF

    /**
     * Checks if a XML character is well-formed.  If there is a problem with
     * the character a non-null Character is returned else null is returned.
     * 
     * @param characters A String of characters to be checked for Well-Formedness
     * @return Character A reference to the character to be returned that was determined invalid. 
     */
    protected Character isWFXMLChar(String chardata) {
    	Character refInvalidChar;
        if (chardata == null || (chardata.length() == 0)) {
            return null;
        }

        char[] dataarray = chardata.toCharArray();
        int datalength = dataarray.length;

        // version of the document is XML 1.1
        if (fIsXMLVersion11) {
            //we need to check all characters as per production rules of XML11
            int i = 0;
            while (i < datalength) {
                if (XML11Char.isXML11Invalid(dataarray[i++])) {
                    // check if this is a supplemental character
                    char ch = dataarray[i - 1];
                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
                        char ch2 = dataarray[i++];
                        if (XMLChar.isLowSurrogate(ch2)
                            && XMLChar.isSupplemental(
                                XMLChar.supplemental(ch, ch2))) {
                            continue;
                        }
                    }
                    // Reference to invalid character which is returned
                    refInvalidChar = new Character(ch);
                    return refInvalidChar;
                }
            }
        } // version of the document is XML 1.0
        else {
            // we need to check all characters as per production rules of XML 1.0
            int i = 0;
            while (i < datalength) {
                if (XMLChar.isInvalid(dataarray[i++])) {
                    // check if this is a supplemental character
                    char ch = dataarray[i - 1];
                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
                        char ch2 = dataarray[i++];
                        if (XMLChar.isLowSurrogate(ch2)
                            && XMLChar.isSupplemental(
                                XMLChar.supplemental(ch, ch2))) {
                            continue;
                        }
                    }
                    // Reference to invalid character which is returned                    
                    refInvalidChar = new Character(ch);
                    return refInvalidChar;
                }
            }
        } // end-else fDocument.isXMLVersion()

        return null;
    } // isXMLCharWF

    /**
     * Checks if a comment node is well-formed
     * 
     * @param data The contents of the comment node
     * @return a boolean indiacating if the comment is well-formed or not.
     */
    protected void isCommentWellFormed(String data) {
        if (data == null || (data.length() == 0)) {
            return;
        }

        char[] dataarray = data.toCharArray();
        int datalength = dataarray.length;

        // version of the document is XML 1.1
        if (fIsXMLVersion11) {
            // we need to check all chracters as per production rules of XML11
            int i = 0;
            while (i < datalength) {
                char c = dataarray[i++];
                if (XML11Char.isXML11Invalid(c)) {
                    // check if this is a supplemental character
                    if (XMLChar.isHighSurrogate(c) && i < datalength) {
                        char c2 = dataarray[i++];
                        if (XMLChar.isLowSurrogate(c2)
                            && XMLChar.isSupplemental(
                                XMLChar.supplemental(c, c2))) {
                            continue;
                        }
                    }
                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
                            new Object[] { new Character(c)});

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_FATAL_ERROR,
                                msg,
                                MsgKey.ER_WF_INVALID_CHARACTER,
                                null,
                                null,
                                null));
                    }
                } else if (c == '-' && i < datalength && dataarray[i] == '-') {
                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_WF_DASH_IN_COMMENT,
                            null);

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_FATAL_ERROR,
                                msg,
                                MsgKey.ER_WF_INVALID_CHARACTER,
                                null,
                                null,
                                null));
                    }
                }
            }
        } // version of the document is XML 1.0
        else {
            // we need to check all chracters as per production rules of XML 1.0
            int i = 0;
            while (i < datalength) {
                char c = dataarray[i++];
                if (XMLChar.isInvalid(c)) {
                    // check if this is a supplemental character
                    if (XMLChar.isHighSurrogate(c) && i < datalength) {
                        char c2 = dataarray[i++];
                        if (XMLChar.isLowSurrogate(c2)
                            && XMLChar.isSupplemental(
                                XMLChar.supplemental(c, c2))) {
                            continue;
                        }
                    }
                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
                            new Object[] { new Character(c)});

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_FATAL_ERROR,
                                msg,
                                MsgKey.ER_WF_INVALID_CHARACTER,
                                null,
                                null,
                                null));
                    }
                } else if (c == '-' && i < datalength && dataarray[i] == '-') {
                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_WF_DASH_IN_COMMENT,
                            null);

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_FATAL_ERROR,
                                msg,
                                MsgKey.ER_WF_INVALID_CHARACTER,
                                null,
                                null,
                                null));
                    }
                }
            }
        }
        return;
    }

    /**
     * Checks if an element node is well-formed, by checking its Name for well-formedness.
     * 
     * @param data The contents of the comment node
     * @return a boolean indiacating if the comment is well-formed or not.
     */
    protected void isElementWellFormed(Node node) {
        boolean isNameWF = false;
        if ((fFeatures & NAMESPACES) != 0) {
            isNameWF =
                isValidQName(
                    node.getPrefix(),
                    node.getLocalName(),
                    fIsXMLVersion11);
        } else {
            isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
        }

        if (!isNameWF) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                    new Object[] { "Element", node.getNodeName()});

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                        null,
                        null,
                        null));
            }
        }
    }

    /**
     * Checks if an attr node is well-formed, by checking it's Name and value
     * for well-formedness.
     * 
     * @param data The contents of the comment node
     * @return a boolean indiacating if the comment is well-formed or not.
     */
    protected void isAttributeWellFormed(Node node) {
        boolean isNameWF = false;
        if ((fFeatures & NAMESPACES) != 0) {
            isNameWF =
                isValidQName(
                    node.getPrefix(),
                    node.getLocalName(),
                    fIsXMLVersion11);
        } else {
            isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
        }

        if (!isNameWF) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                    new Object[] { "Attr", node.getNodeName()});

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                        null,
                        null,
                        null));
            }
        }

        // Check the Attr's node value
        // WFC: No < in Attribute Values
        String value = node.getNodeValue();
        if (value.indexOf('<') >= 0) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_LT_IN_ATTVAL,
                    new Object[] {
                        ((Attr) node).getOwnerElement().getNodeName(),
                        node.getNodeName()});

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_LT_IN_ATTVAL,
                        null,
                        null,
                        null));
            }
        }

        // we need to loop through the children of attr nodes and check their values for
        // well-formedness  
        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            // An attribute node with no text or entity ref child for example
            // doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns");
            // followes by
            // element.setAttributeNodeNS(attribute);
            // can potentially lead to this situation.  If the attribute
            // was a prefix Namespace attribute declaration then then DOM Core 
            // should have some exception defined for this.
            if (child == null) {
                // we should probably report an error
                continue;
            }
            switch (child.getNodeType()) {
                case Node.TEXT_NODE :
                    isTextWellFormed((Text) child);
                    break;
                case Node.ENTITY_REFERENCE_NODE :
                    isEntityReferneceWellFormed((EntityReference) child);
                    break;
                default :
            }
        }

        // TODO:
        // WFC: Check if the attribute prefix is bound to 
        // http://www.w3.org/2000/xmlns/  

        // WFC: Unique Att Spec
        // Perhaps pass a seen boolean value to this method.  serializeAttList will determine
        // if the attr was seen before.
    }

    /**
     * Checks if a PI node is well-formed, by checking it's Name and data
     * for well-formedness.
     * 
     * @param data The contents of the comment node
     */
    protected void isPIWellFormed(ProcessingInstruction node) {
        // Is the PI Target a valid XML name
        if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                    new Object[] { "ProcessingInstruction", node.getTarget()});

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                        null,
                        null,
                        null));
            }
        }

        // Does the PI Data carry valid XML characters

        // REVISIT: Should we check if the PI DATA contains a ?> ???
        Character invalidChar = isWFXMLChar(node.getData());
        if (invalidChar != null) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER,
                        null,
                        null,
                        null));
            }
        }
    }

    /**
     * Checks if an CDATASection node is well-formed, by checking it's data
     * for well-formedness.  Note that the presence of a CDATA termination mark
     * in the contents of a CDATASection is handled by the parameter 
     * spli-cdata-sections
     * 
     * @param data The contents of the comment node
     */
    protected void isCDATASectionWellFormed(CDATASection node) {
        // Does the data valid XML character data        
        Character invalidChar = isWFXMLChar(node.getData());
        //if (!isWFXMLChar(node.getData(), invalidChar)) {
        if (invalidChar != null) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER,
                        null,
                        null,
                        null));
            }
        }
    }

    /**
     * Checks if an Text node is well-formed, by checking if it contains invalid
     * XML characters.
     * 
     * @param data The contents of the comment node
     */
    protected void isTextWellFormed(Text node) {
        // Does the data valid XML character data        
    	Character invalidChar = isWFXMLChar(node.getData());
    	if (invalidChar != null) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER,
                        null,
                        null,
                        null));
            }
        }
    }

    /**
     * Checks if an EntityRefernece node is well-formed, by checking it's node name.  Then depending
     * on whether it is referenced in Element content or in an Attr Node, checks if the EntityReference
     * references an unparsed entity or a external entity and if so throws raises the 
     * appropriate well-formedness error.  
     * 
     * @param data The contents of the comment node
     * @parent The parent of the EntityReference Node
     */
    protected void isEntityReferneceWellFormed(EntityReference node) {
        // Is the EntityReference name a valid XML name
        if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
            String msg =
                Utils.messages.createMessage(
                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                    new Object[] { "EntityReference", node.getNodeName()});

            if (fErrorHandler != null) {
                fErrorHandler.handleError(
                    new DOMErrorImpl(
                        DOMError.SEVERITY_FATAL_ERROR,
                        msg,
                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
                        null,
                        null,
                        null));
            }
        }

        // determine the parent node
        Node parent = node.getParentNode();

        // Traverse the declared entities and check if the nodeName and namespaceURI
        // of the EntityReference matches an Entity.  If so, check the if the notationName
        // is not null, if so, report an error.
        DocumentType docType = node.getOwnerDocument().getDoctype();
        if (docType != null) {
            NamedNodeMap entities = docType.getEntities();
            for (int i = 0; i < entities.getLength(); i++) {
                Entity ent = (Entity) entities.item(i);

                String nodeName =
                    node.getNodeName() == null ? "" : node.getNodeName();
                String nodeNamespaceURI =
                    node.getNamespaceURI() == null
                        ? ""
                        : node.getNamespaceURI();
                String entName =
                    ent.getNodeName() == null ? "" : ent.getNodeName();
                String entNamespaceURI =
                    ent.getNamespaceURI() == null ? "" : ent.getNamespaceURI();
                // If referenced in Element content
                // WFC: Parsed Entity
                if (parent.getNodeType() == Node.ELEMENT_NODE) {
                    if (entNamespaceURI.equals(nodeNamespaceURI)
                        && entName.equals(nodeName)) {

                        if (ent.getNotationName() != null) {
                            String msg =
                                Utils.messages.createMessage(
                                    MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
                                    new Object[] { node.getNodeName()});

                            if (fErrorHandler != null) {
                                fErrorHandler.handleError(
                                    new DOMErrorImpl(
                                        DOMError.SEVERITY_FATAL_ERROR,
                                        msg,
                                        MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
                                        null,
                                        null,
                                        null));
                            }
                        }
                    }
                } // end if WFC: Parsed Entity

                // If referenced in an Attr value
                // WFC: No External Entity References
                if (parent.getNodeType() == Node.ATTRIBUTE_NODE) {
                    if (entNamespaceURI.equals(nodeNamespaceURI)
                        && entName.equals(nodeName)) {

                        if (ent.getPublicId() != null
                            || ent.getSystemId() != null
                            || ent.getNotationName() != null) {
                            String msg =
                                Utils.messages.createMessage(
                                    MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
                                    new Object[] { node.getNodeName()});

                            if (fErrorHandler != null) {
                                fErrorHandler.handleError(
                                    new DOMErrorImpl(
                                        DOMError.SEVERITY_FATAL_ERROR,
                                        msg,
                                        MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
                                        null,
                                        null,
                                        null));
                            }
                        }
                    }
                } //end if WFC: No External Entity References
            }
        }
    } // isEntityReferneceWellFormed    

    /**
     * If the configuration parameter "namespaces" is set to true, this methods
     * checks if an entity whose replacement text contains unbound namespace 
     * prefixes is referenced in a location where there are no bindings for 
     * the namespace prefixes and if so raises a LSException with the error-type
     * "unbound-prefix-in-entity-reference"   
     * 
     * @param Node, The EntityReference nodes whose children are to be checked
     */
    protected void checkUnboundPrefixInEntRef(Node node) {
        Node child, next;
        for (child = node.getFirstChild(); child != null; child = next) {
            next = child.getNextSibling();

            if (child.getNodeType() == Node.ELEMENT_NODE) {

                //If a NamespaceURI is not declared for the current
                //node's prefix, raise a fatal error.
                String prefix = child.getPrefix();
                if (prefix != null
                		&& fNSBinder.getURI(prefix) == null) {
                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
                            new Object[] {
                                node.getNodeName(),
                                child.getNodeName(),
                                prefix });

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_FATAL_ERROR,
                                msg,
                                MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
                                null,
                                null,
                                null));
                    }
                }

                NamedNodeMap attrs = child.getAttributes();

                for (int i = 0; i < attrs.getLength(); i++) {
                    String attrPrefix = attrs.item(i).getPrefix();
                    if (attrPrefix != null
                    		&& fNSBinder.getURI(attrPrefix) == null) {
                        String msg =
                            Utils.messages.createMessage(
                                MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
                                new Object[] {
                                    node.getNodeName(),
                                    child.getNodeName(),
                                    attrs.item(i)});

                        if (fErrorHandler != null) {
                            fErrorHandler.handleError(
                                new DOMErrorImpl(
                                    DOMError.SEVERITY_FATAL_ERROR,
                                    msg,
                                    MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
                                    null,
                                    null,
                                    null));
                        }
                    }
                }
            }

            if (child.hasChildNodes()) {
                checkUnboundPrefixInEntRef(child);
            }
        }
    }

    // ***********************************************************************
    // Namespace normalization
    // ***********************************************************************
    /**
     * Records local namespace declarations, to be used for normalization later
     * 
     * @param Node, The element node, whose namespace declarations are to be recorded
     */
    protected void recordLocalNSDecl(Node node) {
        NamedNodeMap atts = ((Element) node).getAttributes();
        int length = atts.getLength();

        for (int i = 0; i < length; i++) {
            Node attr = atts.item(i);

            String localName = attr.getLocalName();
            String attrPrefix = attr.getPrefix();
            String attrValue = attr.getNodeValue();
            String attrNS = attr.getNamespaceURI();

            localName =
                localName == null
                    || XMLNS_PREFIX.equals(localName) ? "" : localName;
            attrPrefix = attrPrefix == null ? "" : attrPrefix;
            attrValue = attrValue == null ? "" : attrValue;
            attrNS = attrNS == null ? "" : attrNS;

            // check if attribute is a namespace decl
            if (XMLNS_URI.equals(attrNS)) {

                // No prefix may be bound to http://www.w3.org/2000/xmlns/.
                if (XMLNS_URI.equals(attrValue)) {
                    String msg =
                        Utils.messages.createMessage(
                            MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
                            new Object[] { attrPrefix, XMLNS_URI });

                    if (fErrorHandler != null) {
                        fErrorHandler.handleError(
                            new DOMErrorImpl(
                                DOMError.SEVERITY_ERROR,
                                msg,
                                MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
                                null,
                                null,
                                null));
                    }
                } else {
                    // store the namespace-declaration
                	if (XMLNS_PREFIX.equals(attrPrefix) ) {
                        // record valid decl
                        if (attrValue.length() != 0) {
                            fNSBinder.declarePrefix(localName, attrValue);
                        } else {
                            // Error; xmlns:prefix=""
                        }
                    } else { // xmlns
                        // empty prefix is always bound ("" or some string)
                        fNSBinder.declarePrefix("", attrValue);
                    }
                }
                
            }
        }
    }

    /**
     * Fixes an element's namespace
     * 
     * @param Node, The element node, whose namespace is to be fixed
     */
    protected void fixupElementNS(Node node) throws SAXException {
        String namespaceURI = ((Element) node).getNamespaceURI();
        String prefix = ((Element) node).getPrefix();
        String localName = ((Element) node).getLocalName();

        if (namespaceURI != null) {
            //if ( Element's prefix/namespace pair (or default namespace,
            // if no prefix) are within the scope of a binding )
            prefix = prefix == null ? "" : prefix;
            String inScopeNamespaceURI = fNSBinder.getURI(prefix);

            if ((inScopeNamespaceURI != null
                && inScopeNamespaceURI.equals(namespaceURI))) {
                // do nothing, declaration in scope is inherited
                
            } else {
                // Create a local namespace declaration attr for this namespace,
                // with Element's current prefix (or a default namespace, if
                // no prefix). If there's a conflicting local declaration
                // already present, change its value to use this namespace.
                
                // Add the xmlns declaration attribute
            	//fNSBinder.pushNamespace(prefix, namespaceURI, fElementDepth);
                if ((fFeatures & NAMESPACEDECLS) != 0) {
                    if ("".equals(prefix) || "".equals(namespaceURI)) {
                    	((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, namespaceURI);
                    } else {
                    	((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX + ":" + prefix, namespaceURI);
                    }
                }
                fLocalNSBinder.declarePrefix(prefix, namespaceURI);
                fNSBinder.declarePrefix(prefix, namespaceURI);

            } 
        } else {
            // Element has no namespace
            // DOM Level 1
            if (localName == null || "".equals(localName)) {
                //  DOM Level 1 node!
                String msg =
                    Utils.messages.createMessage(
                        MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
                        new Object[] { node.getNodeName()});

                if (fErrorHandler != null) {
                    fErrorHandler.handleError(
                        new DOMErrorImpl(
                            DOMError.SEVERITY_ERROR,
                            msg,
                            MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
                            null,
                            null,
                            null));
                }
            } else {
            	namespaceURI = fNSBinder.getURI("");
            	if (namespaceURI !=null && namespaceURI.length() > 0) {
            	    ((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, "");
            		fLocalNSBinder.declarePrefix("", "");
                    fNSBinder.declarePrefix("", "");
            	}
            }
        }
    }
    /** 
     * This table is a quick lookup of a property key (String) to the integer that
     * is the bit to flip in the fFeatures field, so the integers should have
     * values 1,2,4,8,16...
     * 
     */
    private static final Hashtable s_propKeys = new Hashtable();
    static {

        // Initialize the mappings of property keys to bit values (Integer objects)
        // or mappings to a String object "", which indicates we are interested
        // in the property, but it does not have a simple bit value to flip

        // cdata-sections
        int i = CDATA;
        Integer val = new Integer(i);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_CDATA_SECTIONS,
            val);

        // comments
        int i1 = COMMENTS;
        val = new Integer(i1);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_COMMENTS,
            val);

        // element-content-whitespace
        int i2 = ELEM_CONTENT_WHITESPACE;
        val = new Integer(i2);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS
                + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
            val);
        int i3 = ENTITIES;

        // entities
        val = new Integer(i3);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_ENTITIES,
            val);

        // namespaces
        int i4 = NAMESPACES;
        val = new Integer(i4);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_NAMESPACES,
            val);

        // namespace-declarations
        int i5 = NAMESPACEDECLS;
        val = new Integer(i5);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS
                + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
            val);

        // split-cdata-sections
        int i6 = SPLITCDATA;
        val = new Integer(i6);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_SPLIT_CDATA,
            val);

        // discard-default-content	
        int i7 = WELLFORMED;
        val = new Integer(i7);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_WELLFORMED,
            val);

        // discard-default-content	
        int i8 = DISCARDDEFAULT;
        val = new Integer(i8);
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS
                + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
            val);

        // We are interested in these properties, but they don't have a simple
        // bit value to deal with.
        s_propKeys.put(
            DOMConstants.S_DOM3_PROPERTIES_NS
                + DOMConstants.DOM_FORMAT_PRETTY_PRINT,
            "");
        s_propKeys.put(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "");
        s_propKeys.put(
            DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION,
            "");
        s_propKeys.put(DOMConstants.S_XSL_OUTPUT_ENCODING, "");
        s_propKeys.put(OutputPropertiesFactory.S_KEY_ENTITIES, "");
    }

    /**
     * Initializes fFeatures based on the DOMConfiguration Parameters set.
     *
     * @param properties DOMConfiguraiton properties that were set and which are
     * to be used while serializing the DOM. 
     */
    protected void initProperties(Properties properties) {

        for (Enumeration keys = properties.keys(); keys.hasMoreElements();) {

            final String key = (String) keys.nextElement();
    
            // caonical-form
            // Other features will be enabled or disabled when this is set to true or false.

            // error-handler; set via the constructor

            // infoset
            // Other features will be enabled or disabled when this is set to true

            // A quick lookup for the given set of properties (cdata-sections ...)
            final Object iobj = s_propKeys.get(key);
            if (iobj != null) {
                if (iobj instanceof Integer) {
                    // Dealing with a property that has a simple bit value that
                    // we need to set

                    // cdata-sections			
                    // comments
                    // element-content-whitespace
                    // entities
                    // namespaces
                    // namespace-declarations
                    // split-cdata-sections
                    // well-formed
                    // discard-default-content
                    final int BITFLAG = ((Integer) iobj).intValue();
                    if ((properties.getProperty(key).endsWith("yes"))) {
                        fFeatures = fFeatures | BITFLAG;
                    } else {
                        fFeatures = fFeatures & ~BITFLAG;
                    }
                } else {
                    // We are interested in the property, but it is not
                    // a simple bit that we need to set.

                    if ((DOMConstants.S_DOM3_PROPERTIES_NS
                        + DOMConstants.DOM_FORMAT_PRETTY_PRINT)
                        .equals(key)) {
                        // format-pretty-print; set internally on the serializers via xsl:output properties in LSSerializer
                        if ((properties.getProperty(key).endsWith("yes"))) {
                            fSerializer.setIndent(true);
                            fSerializer.setIndentAmount(3);
                        } else {
                            fSerializer.setIndent(false);
                        }
                    } else if (
                        (DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL).equals(
                            key)) {
                        // omit-xml-declaration; set internally on the serializers via xsl:output properties in LSSerializer
                        if ((properties.getProperty(key).endsWith("yes"))) {
                            fSerializer.setOmitXMLDeclaration(true);
                        } else {
                            fSerializer.setOmitXMLDeclaration(false);
                        }
                    } else if (
                        (
                            DOMConstants.S_XERCES_PROPERTIES_NS
                                + DOMConstants.S_XML_VERSION).equals(
                            key)) {
                        // Retreive the value of the XML Version attribute via the xml-version
                        String version = properties.getProperty(key);
                        if ("1.1".equals(version)) {
                            fIsXMLVersion11 = true;
                            fSerializer.setVersion(version);
                        } else {
                            fSerializer.setVersion("1.0");
                        }
                    } else if (
                        (DOMConstants.S_XSL_OUTPUT_ENCODING).equals(key)) {
                        // Retreive the value of the XML Encoding attribute
                        String encoding = properties.getProperty(key);
                        if (encoding != null) {
                            fSerializer.setEncoding(encoding);
                        }
                    } else if ((OutputPropertiesFactory.S_KEY_ENTITIES).equals(key)) {
                        // Retreive the value of the XML Encoding attribute
                        String entities = properties.getProperty(key);
                        if (DOMConstants.S_XSL_VALUE_ENTITIES.equals(entities)) {
                            fSerializer.setDTDEntityExpansion(false);
                        }
                    } else {
                        // We shouldn't get here, ever, now what?
                    }
                }
            }
        }
        // Set the newLine character to use
        if (fNewLine != null) {
            fSerializer.setOutputProperty(OutputPropertiesFactory.S_KEY_LINE_SEPARATOR,
                    fNewLine.toString());
        }
    }

} //TreeWalker
