/*
 * Copyright (c) 2014, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.internal.oxm;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;

import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;

import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ExtendedResult;
import org.eclipse.persistence.internal.oxm.record.namespaces.PrefixMapperNamespaceResolver;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.JSONWithPadding;
import org.eclipse.persistence.oxm.attachment.XMLAttachmentMarshaller;
import org.eclipse.persistence.oxm.record.ContentHandlerRecord;
import org.eclipse.persistence.oxm.record.FormattedOutputStreamRecord;
import org.eclipse.persistence.oxm.record.FormattedWriterRecord;
import org.eclipse.persistence.oxm.record.JSONFormattedWriterRecord;
import org.eclipse.persistence.oxm.record.JSONWriterRecord;
import org.eclipse.persistence.oxm.record.MarshalRecord;
import org.eclipse.persistence.oxm.record.NodeRecord;
import org.eclipse.persistence.oxm.record.OutputStreamRecord;
import org.eclipse.persistence.oxm.record.ValidatingMarshalRecord;
import org.eclipse.persistence.oxm.record.WriterRecord;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;

public abstract class XMLMarshaller<
    ABSTRACT_SESSION extends CoreAbstractSession,
    CHARACTER_ESCAPE_HANDLER extends CharacterEscapeHandler,
    CONTEXT extends Context<ABSTRACT_SESSION, DESCRIPTOR, ?, ?, ?, SESSION, ?>,
    DESCRIPTOR extends Descriptor<?, ?, ?, ?, ?, ?, ?, ?, ?, ?>,
    MARSHALLER_LISTENER extends Marshaller.Listener,
    MEDIA_TYPE extends MediaType,
    NAMESPACE_PREFIX_MAPPER extends NamespacePrefixMapper,
    OBJECT_BUILDER extends ObjectBuilder<?, ABSTRACT_SESSION, ?, XMLMarshaller>,
    SESSION extends CoreSession> extends Marshaller<CHARACTER_ESCAPE_HANDLER, CONTEXT, MARSHALLER_LISTENER, MEDIA_TYPE, NAMESPACE_PREFIX_MAPPER> {

    protected final static String DEFAULT_XML_VERSION = "1.0";
    private static final String STAX_RESULT_CLASS_NAME = "javax.xml.transform.stax.StAXResult";
    private static final String GET_XML_STREAM_WRITER_METHOD_NAME = "getXMLStreamWriter";
    private static final String GET_XML_EVENT_WRITER_METHOD_NAME = "getXMLEventWriter";
    private static final String XML_STREAM_WRITER_RECORD_CLASS_NAME = "org.eclipse.persistence.oxm.record.XMLStreamWriterRecord";
    private static final String XML_EVENT_WRITER_RECORD_CLASS_NAME = "org.eclipse.persistence.oxm.record.XMLEventWriterRecord";
    private static final String XML_STREAM_WRITER_CLASS_NAME = "javax.xml.stream.XMLStreamWriter";
    private static final String XML_EVENT_WRITER_CLASS_NAME = "javax.xml.stream.XMLEventWriter";
    private static final String DOM_TO_STREAM_WRITER_CLASS_NAME = "org.eclipse.persistence.internal.oxm.record.DomToXMLStreamWriter";
    private static final String DOM_TO_EVENT_WRITER_CLASS_NAME = "org.eclipse.persistence.internal.oxm.record.DomToXMLEventWriter";
    private static final String WRITE_TO_STREAM_METHOD_NAME = "writeToStream";
    private static final String WRITE_TO_EVENT_WRITER_METHOD_NAME = "writeToEventWriter";

    protected static Class staxResultClass;
    protected static Method staxResultGetStreamWriterMethod;
    protected static Method staxResultGetEventWriterMethod;
    private static Constructor xmlStreamWriterRecordConstructor;
    private static Constructor xmlEventWriterRecordConstructor;
    protected static Method writeToStreamMethod;
    protected static Method writeToEventWriterMethod;
    protected static Class domToStreamWriterClass;
    protected static Class domToEventWriterClass;

    static {
        try {
            staxResultClass = PrivilegedAccessHelper.getClassForName(STAX_RESULT_CLASS_NAME);
            if(staxResultClass != null) {
                staxResultGetStreamWriterMethod = PrivilegedAccessHelper.getDeclaredMethod(staxResultClass, GET_XML_STREAM_WRITER_METHOD_NAME, new Class[]{});
                staxResultGetEventWriterMethod = PrivilegedAccessHelper.getDeclaredMethod(staxResultClass, GET_XML_EVENT_WRITER_METHOD_NAME, new Class[]{});
            }
            Class<Object> streamWriterRecordClass = PrivilegedAccessHelper.getClassForName(XML_STREAM_WRITER_RECORD_CLASS_NAME);
            Class<Object> streamWriterClass = PrivilegedAccessHelper.getClassForName(XML_STREAM_WRITER_CLASS_NAME);
            xmlStreamWriterRecordConstructor = PrivilegedAccessHelper.getConstructorFor(streamWriterRecordClass, new Class[]{streamWriterClass}, true);

            Class<Object> eventWriterRecordClass = PrivilegedAccessHelper.getClassForName(XML_EVENT_WRITER_RECORD_CLASS_NAME);
            Class<Object> eventWriterClass = PrivilegedAccessHelper.getClassForName(XML_EVENT_WRITER_CLASS_NAME);
            xmlEventWriterRecordConstructor = PrivilegedAccessHelper.getConstructorFor(eventWriterRecordClass, new Class[]{eventWriterClass}, true);

            domToStreamWriterClass = PrivilegedAccessHelper.getClassForName(DOM_TO_STREAM_WRITER_CLASS_NAME);
            writeToStreamMethod = PrivilegedAccessHelper.getMethod(domToStreamWriterClass, WRITE_TO_STREAM_METHOD_NAME, new Class[] {CoreClassConstants.NODE, CoreClassConstants.STRING, CoreClassConstants.STRING, streamWriterClass}, true);

            domToEventWriterClass = PrivilegedAccessHelper.getClassForName(DOM_TO_EVENT_WRITER_CLASS_NAME);
            writeToEventWriterMethod = PrivilegedAccessHelper.getMethod(domToEventWriterClass, WRITE_TO_EVENT_WRITER_METHOD_NAME, new Class[] {CoreClassConstants.NODE, CoreClassConstants.STRING, CoreClassConstants.STRING, eventWriterClass}, true);

        } catch (Exception ex) {
            // Do nothing
        }
    }

    protected XMLAttachmentMarshaller attachmentMarshaller;
    private String attributePrefix;
    private boolean fragment;
    private boolean includeRoot = true;
    private boolean marshalEmptyCollections = true;
    protected MEDIA_TYPE mediaType;
    private char namespaceSeparator;
    private String noNamespaceSchemaLocation;
    private boolean reduceAnyArrays;
    private Schema schema;
    private String schemaLocation;
    protected XMLTransformer transformer;
    private String valueWrapper;
    private boolean wrapperAsCollectionName = false;
    private String xmlHeader;
    private Object marshalAttributeGroup;
    private Boolean logPayload;

    protected XMLMarshaller(CONTEXT context) {
        super(context);
        this.includeRoot = true;
        this.marshalEmptyCollections = true;
        this.namespaceSeparator = Constants.DOT;
        this.reduceAnyArrays = false;
        this.valueWrapper = Constants.VALUE_WRAPPER;
    }

    /**
     * Copy constructor
     */
    protected XMLMarshaller(XMLMarshaller xmlMarshaller) {
        super(xmlMarshaller);
        attachmentMarshaller = xmlMarshaller.getAttachmentMarshaller();
        attributePrefix = xmlMarshaller.getAttributePrefix();
        fragment = xmlMarshaller.isFragment();
        includeRoot = xmlMarshaller.isIncludeRoot();
        marshalEmptyCollections = xmlMarshaller.isMarshalEmptyCollections();
        mediaType = (MEDIA_TYPE) xmlMarshaller.mediaType;
        namespaceSeparator = xmlMarshaller.getNamespaceSeparator();
        noNamespaceSchemaLocation = xmlMarshaller.getNoNamespaceSchemaLocation();
        reduceAnyArrays = xmlMarshaller.isReduceAnyArrays();

        if(null != xmlMarshaller.getSchema()) {
            setSchema(xmlMarshaller.getSchema());
        }

        schemaLocation = xmlMarshaller.getSchemaLocation();
        valueWrapper = xmlMarshaller.getValueWrapper();
        wrapperAsCollectionName = xmlMarshaller.isWrapperAsCollectionName();
        xmlHeader = xmlMarshaller.getXmlHeader();
    }

    protected void addDescriptorNamespacesToXMLRecord(DESCRIPTOR xmlDescriptor, AbstractMarshalRecord record) {
        if (null == xmlDescriptor) {
            return;
        }
        copyNamespaces(xmlDescriptor.getNamespaceResolver(), record.getNamespaceResolver());
    }

    private XPathFragment buildRootFragment(Object object, DESCRIPTOR descriptor, boolean isXMLRoot, MarshalRecord marshalRecord) {
        XPathFragment rootFragment = null;
        if (isXMLRoot) {
            String xmlRootUri = ((Root) object).getNamespaceURI();
            String xmlRootLocalName = ((Root) object).getLocalName();
            rootFragment = new XPathFragment();
            rootFragment.setLocalName(xmlRootLocalName);
            rootFragment.setNamespaceURI(xmlRootUri);
            rootFragment.setNamespaceAware(marshalRecord.isNamespaceAware());
            rootFragment.setNamespaceSeparator(marshalRecord.getNamespaceSeparator());

            if (xmlRootUri != null) {
                if (descriptor != null) {
                    String xmlRootPrefix = marshalRecord.getNamespaceResolver().resolveNamespaceURI(xmlRootUri);
                    if (xmlRootPrefix == null && !(xmlRootUri.equals(marshalRecord.getNamespaceResolver().getDefaultNamespaceURI()))) {
                        xmlRootPrefix = marshalRecord.getNamespaceResolver().generatePrefix();
                        marshalRecord.getNamespaceResolver().put(xmlRootPrefix, xmlRootUri);
                    }
                    if(xmlRootPrefix == null) {
                        rootFragment.setXPath(xmlRootLocalName);
                    } else {
                         rootFragment.setPrefix(xmlRootPrefix);
                    }
                } else {
                    if(marshalRecord.isNamespaceAware()){
                        String xmlRootPrefix = "ns0";
                        marshalRecord.getNamespaceResolver().put(xmlRootPrefix, xmlRootUri);
                        rootFragment.setXPath(xmlRootPrefix + marshalRecord.getNamespaceSeparator() + xmlRootLocalName);
                    }else{
                        rootFragment.setXPath(xmlRootLocalName);
                    }
                }
            }
        } else {
            Field defaultRootField = descriptor.getDefaultRootElementField();
            if(defaultRootField != null){
                rootFragment = defaultRootField.getXPathFragment();
            }
        }
        return rootFragment;
    }

    protected void copyNamespaces(NamespaceResolver source, NamespaceResolver target) {
        if (null != source && null != target) {
            if(source.hasPrefixesToNamespaces()) {
                target.getPrefixesToNamespaces().putAll(source.getPrefixesToNamespaces());
            }
            target.setDefaultNamespaceURI(source.getDefaultNamespaceURI());
        }
    }

    @Override
    public XMLAttachmentMarshaller getAttachmentMarshaller() {
        return this.attachmentMarshaller;
    }

    /**
     * Value that will be used to prefix attributes.
     * Ignored marshalling XML.
     * @since 2.4
     */
    public String getAttributePrefix() {
        return attributePrefix;
    }

    /**
     * INTERNAL:
     * Return the descriptor for the root object.
     */
     protected DESCRIPTOR getDescriptor(Class clazz, ABSTRACT_SESSION session) throws XMLMarshalException {
         DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(clazz);
         if (descriptor == null) {
             throw XMLMarshalException.descriptorNotFoundInProject(clazz.getName());
         }

         return descriptor;
    }

     /**
      * INTERNAL:
      * Return the descriptor for the root object.
      */
      public DESCRIPTOR getDescriptor(Object object) throws XMLMarshalException {
          DESCRIPTOR descriptor = (DESCRIPTOR) context.getSession(object).getDescriptor(object);
          if (descriptor == null) {
              throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
          }

          return descriptor;
      }

     /**
      * INTERNAL:
      * Return the descriptor for the root object.
      */
      protected DESCRIPTOR getDescriptor(Object object, ABSTRACT_SESSION session) throws XMLMarshalException {
          DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(object);
          if (descriptor == null) {
              throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
          }

          return descriptor;
      }

      protected DESCRIPTOR getDescriptor(Object object, boolean isXMLRoot) {
          if (isXMLRoot) {
              return getDescriptor((Root) object);
          } else {
              return getDescriptor(object);
          }
      }

      protected DESCRIPTOR getDescriptor(Root object) throws XMLMarshalException {
          DESCRIPTOR descriptor = null;

          try {
              ABSTRACT_SESSION session = context.getSession(object.getObject());
              if(null == session) {
                  return null;
              }
              descriptor = (DESCRIPTOR) session.getDescriptor(object.getObject());
          } catch (XMLMarshalException marshalException) {
              if ((descriptor == null) && isSimpleXMLRoot(object)) {
                  return null;
              }
              throw marshalException;
          }

          if (descriptor == null) {
              throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
          }

          return descriptor;
      }

      protected DESCRIPTOR getDescriptor(Root object, ABSTRACT_SESSION session) throws XMLMarshalException {
          DESCRIPTOR descriptor = null;

          try {
              if(null == session) {
                  return null;
              }
              descriptor = (DESCRIPTOR) session.getDescriptor(object.getObject());
          } catch (XMLMarshalException marshalException) {
              if ((descriptor == null) && isSimpleXMLRoot(object)) {
                  return null;
              }
              throw marshalException;
          }

          if (descriptor == null) {
              throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
          }

          return descriptor;
      }

    protected Node getNode(Object object, Node parentNode, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isRoot) {
        if(isRoot) {
            object = ((Root) object).getObject();
            if(object instanceof Node) {
                return (Node) object;
            }
        }
        return null;
    }

    /**
     * Get the no namespace schema location set on this XMLMarshaller
     * @return the no namespace schema location specified on this XMLMarshaller
     */
    public String getNoNamespaceSchemaLocation() {
       return noNamespaceSchemaLocation;
    }

    public Schema getSchema() {
        return schema;
    }

    /**
     * INTERNAL
     * @return the transformer instance for this marshaller
     */
    @Override
    public XMLTransformer getTransformer() {
        if(null == transformer) {
            XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
            transformer = xmlPlatform.newXMLTransformer();
            transformer.setEncoding(getEncoding());
            transformer.setFormattedOutput(isFormattedOutput());
            transformer.setFragment(fragment);

        }
        return transformer;
    }

    /**
     * Name of the property to marshal/unmarshal as a wrapper on the text() mappings
     * Ignored marshalling XML.
     * @since 2.4
     */
    public String getValueWrapper() {
        return valueWrapper;
    }

    /**
     * Get this Marshaller's XML Header.
     * @since 2.4
     */
    public String getXmlHeader() {
        return xmlHeader;
    }

    /**
     * Get the schema location set on this XMLMarshaller
     * @return the schema location specified on this XMLMarshaller
     */
    public String getSchemaLocation() {
       return schemaLocation;
    }

    /**
     * INTERNAL
     * @return true if the media type is application/json, else false.
     * @since EclipseLink 2.6.0
     */
    @Override
    public boolean isApplicationJSON() {
        return null != mediaType && mediaType.isApplicationJSON();
    }

    /**
     * INTERNAL
     * @return true if the media type is application/xml, else false.
     * @since EclipseLink 2.6.0
     */
    @Override
    public boolean isApplicationXML() {
        return null == mediaType || mediaType.isApplicationXML();
    }

    /**
     * PUBLIC:
     * Returns if this should marshal to a fragment.  If true an XML header string is not written out.
     * @return if this should marshal to a fragment or not
     */
    public boolean isFragment() {
        return isApplicationXML() && fragment;
    }

    /**
     * Determine if the @XMLRootElement should be marshalled when present.
     * Ignored marshalling XML.
     * @since 2.4
     */
    @Override
    public boolean isIncludeRoot() {
       if(isApplicationJSON()){
           return includeRoot;
       }
       return true;
    }

    /**
     * Property to determine if size 1 any collections should be treated as collections
     * Ignored marshalling XML.
     */
    @Override
    public boolean isReduceAnyArrays() {
        return reduceAnyArrays;
    }

    /**
     * Get the namespace separator used during marshal operations.
     * If mediaType is application/json '.' is the default
     * Ignored marshalling XML.
     * @since 2.4
     */
    public char getNamespaceSeparator() {
        return namespaceSeparator;
    }

    /**
     * Name of the property to determine if empty collections should be marshalled as []
     * Ignored marshalling XML.
     * @since 2.4
     */
    public boolean isMarshalEmptyCollections() {
        return marshalEmptyCollections;
    }

    @Override
    public boolean isWrapperAsCollectionName() {
        return wrapperAsCollectionName;
    }

    protected boolean isSimpleXMLRoot(Root xmlRoot) {
        Class<? extends Object> xmlRootObjectClass = xmlRoot.getObject().getClass();

        ConversionManager conversionManager = (ConversionManager) context.getSession().getDatasourcePlatform().getConversionManager();
        if (conversionManager.schemaType(xmlRootObjectClass) != null || CoreClassConstants.List_Class.isAssignableFrom(xmlRootObjectClass) || CoreClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(xmlRootObjectClass) || CoreClassConstants.DURATION.isAssignableFrom(xmlRootObjectClass)) {
            return true;
        } else if(xmlRoot.getObject() instanceof org.w3c.dom.Node) {
            return true;
        }
        return false;
    }

    /**
     * PUBLIC:
     * Convert the given object to XML and update the given contentHandler with that XML Document
     * @param object the object to marshal
     * @param contentHandler the contentHandler which the specified object should be marshalled to
     * @throws XMLMarshalException if an error occurred during marshalling
     */
    public void marshal(Object object, ContentHandler contentHandler) throws XMLMarshalException {
        if (contentHandler instanceof LexicalHandler) {
            marshal(object, contentHandler, (LexicalHandler)contentHandler);
        } else {
            marshal(object, contentHandler, null);
        }
    }

    /**
     * PUBLIC:
     * Convert the given object to XML and update the given contentHandler with that XML Document
     * @param object the object to marshal
     * @param contentHandler the contentHandler which the specified object should be marshalled to
     * @throws XMLMarshalException if an error occurred during marshalling
     */
    public void marshal(Object object, ContentHandler contentHandler, LexicalHandler lexicalHandler) throws XMLMarshalException {
        if(object instanceof JSONWithPadding && !isApplicationJSON()){
            object = ((JSONWithPadding)object).getObject();
        }

        if ((object == null) || (contentHandler == null)) {
            throw XMLMarshalException.nullArgumentException();
        }

        ABSTRACT_SESSION session = null;
        DESCRIPTOR xmlDescriptor = null;

        boolean isXMLRoot = (object instanceof Root);
        if(isXMLRoot){
            try{
                session = context.getSession(((Root)object).getObject());
                if(session != null){
                    xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
                }
            }catch (XMLMarshalException marshalException) {
                if (!isSimpleXMLRoot((Root) object)) {
                    throw marshalException;
                }
            }
        }else{
            Class<? extends Object> objectClass = object.getClass();
            session = context.getSession(objectClass);
            xmlDescriptor = getDescriptor(objectClass, session);
        }

        ContentHandlerRecord contentHandlerRecord = new ContentHandlerRecord();
        contentHandlerRecord.setMarshaller(this);
        contentHandlerRecord.setContentHandler(contentHandler);
        contentHandlerRecord.setLexicalHandler(lexicalHandler);
        marshal(object, contentHandlerRecord, session, xmlDescriptor,isXMLRoot);
    }

    /**
     * Convert the given object to XML and update the given marshal record with
     * that XML Document.
     * @param object the object to marshal
     * @param marshalRecord the marshalRecord to marshal the object to
     */
    public void marshal(Object object, MarshalRecord marshalRecord) {
        if(object instanceof JSONWithPadding && !isApplicationJSON()){
            object = ((JSONWithPadding)object).getObject();
        }
        if ((object == null) || (marshalRecord == null)) {
            throw XMLMarshalException.nullArgumentException();
        }

        boolean isXMLRoot = (object instanceof Root);

        ABSTRACT_SESSION session = null;
        DESCRIPTOR xmlDescriptor = null;
        if(isXMLRoot){
            try{
                session = context.getSession(((Root)object).getObject());
                if(session != null){
                    xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
                }
            }catch (XMLMarshalException marshalException) {
                if (!isSimpleXMLRoot((Root) object)) {
                    throw marshalException;
                }
            }
        }else{
            Class<? extends Object> objectClass = object.getClass();
            session = context.getSession(objectClass);
            xmlDescriptor = getDescriptor(objectClass, session);
        }

        marshal(object, marshalRecord, session, xmlDescriptor, isXMLRoot);
    }

    /**
     * Convert the given object to XML and update the given marshal record with
     * that XML Document.
     * @param object the object to marshal
     * @param marshalRecord the marshalRecord to marshal the object to
     * @param descriptor the XMLDescriptor for the object being marshalled
     */
    protected void marshal(Object object, MarshalRecord marshalRecord, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) {
        SessionLog logger = AbstractSessionLog.getLog();

        if (logger.shouldLog(SessionLog.FINE, SessionLog.MOXY)) {
            logger.log(SessionLog.FINE, SessionLog.MOXY, "moxy_start_marshalling", new Object[] { (object!= null)?object.getClass().getName():"N/A", this.mediaType});
        }
        if (object != null && logPayload != null && this.isLogPayload()) {
                AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, object.toString(), new Object[0], false);
        }

        if(null != schema) {
            marshalRecord = new ValidatingMarshalRecord(marshalRecord, this);
        }
        if (this.attachmentMarshaller != null) {
            marshalRecord.setXOPPackage(this.attachmentMarshaller.isXOPPackage());
        }
        marshalRecord.setMarshaller(this);

        Root root = null;
        if(isXMLRoot) {
            root = (Root) object;
        }
        Node node = getNode(object, marshalRecord.getDOM(), session, descriptor, isXMLRoot);

        if(this.mapper == null) {
            if(null == node) {
                addDescriptorNamespacesToXMLRecord(descriptor, marshalRecord);
            }
        } else {
            if(descriptor == null || null != node){
                marshalRecord.setNamespaceResolver(new PrefixMapperNamespaceResolver(mapper, null));
            }else{
                marshalRecord.setNamespaceResolver(new PrefixMapperNamespaceResolver(mapper, descriptor.getNamespaceResolver()));
            }
            marshalRecord.setCustomNamespaceMapper(true);
        }

        if(this.getMarshalAttributeGroup() != null) {
            if(marshalAttributeGroup.getClass() == CoreClassConstants.STRING) {
                CoreAttributeGroup group = descriptor.getAttributeGroup((String)marshalAttributeGroup);
                if(group != null) {
                    marshalRecord.pushAttributeGroup(group);
                } else {
                    throw XMLMarshalException.invalidAttributeGroupName((String)marshalAttributeGroup, descriptor.getJavaClassName());
                }
            } else if(marshalAttributeGroup instanceof CoreAttributeGroup) {
                marshalRecord.pushAttributeGroup((CoreAttributeGroup)marshalAttributeGroup);
            } else {
                //Error case
            }
        }
        NamespaceResolver nr = marshalRecord.getNamespaceResolver();
        if(node != null) {
            if(isXMLRoot) {
                if (isFragment()) {
                    marshalRecord.node(node, null,  root.getNamespaceURI(), root.getLocalName());
               } else {
                   String encoding = root.getEncoding();
                   if(null == encoding) {
                       encoding = Constants.DEFAULT_XML_ENCODING;
                   }
                   String version = root.getXMLVersion();
                   if(null == version) {
                       version = DEFAULT_XML_VERSION;
                   }
                   marshalRecord.startDocument(encoding, version);
                   marshalRecord.node(node, marshalRecord.getNamespaceResolver(), root.getNamespaceURI(), root.getLocalName());
                   marshalRecord.endDocument();
               }
            } else {
                marshalRecord.node(node, nr);
            }
            marshalRecord.flush();
            return;
        }

        if(isXMLRoot){
            if(descriptor != null){
                marshalRecord.beforeContainmentMarshal(root.getObject());
            }
        }else{
            marshalRecord.beforeContainmentMarshal(object);
        }

        if (!isFragment()) {
            String encoding = getEncoding();
            String version = DEFAULT_XML_VERSION;
            if (!isXMLRoot && descriptor!= null) {
                marshalRecord.setLeafElementType(descriptor.getDefaultRootElementType());
            } else {
                if (root.getEncoding() != null) {
                    encoding = root.getEncoding();
                }
                if (root.getXMLVersion() != null) {
                    version = root.getXMLVersion();
                }
            }
            marshalRecord.startDocument(encoding, version);
        }
        if (getXmlHeader() != null) {
            marshalRecord.writeHeader();
        }
        if(isXMLRoot) {
            if(root.getObject() instanceof Node) {
                marshalRecord.node((Node)root.getObject(), new NamespaceResolver(), root.getNamespaceURI(), root.getLocalName());
                marshalRecord.endDocument();
                return;
            }
        }
        XPathFragment rootFragment = buildRootFragment(object, descriptor, isXMLRoot, marshalRecord);

        String schemaLocation = getSchemaLocation();
        String noNsSchemaLocation = getNoNamespaceSchemaLocation();
        boolean isNil = false;
        if (isXMLRoot) {
            object = root.getObject();
            if (root.getSchemaLocation() != null) {
                schemaLocation = root.getSchemaLocation();
            }
            if (root.getNoNamespaceSchemaLocation() != null) {
                noNsSchemaLocation = root.getNoNamespaceSchemaLocation();
            }
            marshalRecord.setLeafElementType(root.getSchemaType());
            isNil = root.isNil();
        }

        String xsiPrefix = null;
        if ((null != getSchemaLocation()) || (null != getNoNamespaceSchemaLocation()) || (isNil)) {
            xsiPrefix = nr.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
            if (null == xsiPrefix) {
                xsiPrefix = Constants.SCHEMA_INSTANCE_PREFIX;
                nr.put(Constants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
            }
        }

        OBJECT_BUILDER treeObjectBuilder = null;
        if (descriptor != null) {
            treeObjectBuilder = (OBJECT_BUILDER) descriptor.getObjectBuilder();
        }
        if(session == null){
            session = (ABSTRACT_SESSION) context.getSession();
        }
        marshalRecord.setSession(session);

        if (null != rootFragment && !(rootFragment.getLocalName().equals(Constants.EMPTY_STRING))) {
            marshalRecord.startPrefixMappings(nr);
            if (!isXMLRoot && descriptor != null && descriptor.getNamespaceResolver() == null && rootFragment.hasNamespace()) {
                // throw an exception if the name has a : in it but the namespaceresolver is null
                throw XMLMarshalException.namespaceResolverNotSpecified(rootFragment.getShortName());
            }

            if(isIncludeRoot()){
                marshalRecord.openStartElement(rootFragment, nr);
            }
            if (null != schemaLocation) {
                marshalRecord.attributeWithoutQName(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_LOCATION, xsiPrefix, schemaLocation);
            }
            if (null != noNsSchemaLocation) {
                marshalRecord.attributeWithoutQName(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.NO_NS_SCHEMA_LOCATION, xsiPrefix, noNsSchemaLocation);
            }
            if (isNil) {
                marshalRecord.nilSimple(nr);
            }

            marshalRecord.namespaceDeclarations(nr);

            if (descriptor != null && !isNil) {
                marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, null, descriptor.getDefaultRootElementField(), root, object, isXMLRoot, true);
                treeObjectBuilder.marshalAttributes(marshalRecord, object, session);
            }

            if(isIncludeRoot()) {
                marshalRecord.closeStartElement();
            }
        }else{
            //no rootfragment
            marshalRecord.marshalWithoutRootElement(treeObjectBuilder,object, descriptor, root, isXMLRoot);
        }
        if (treeObjectBuilder != null && !isNil) {
            treeObjectBuilder.buildRow(marshalRecord, object, session, this, rootFragment);
        } else if (isXMLRoot) {
             if(object != null && !isNil) {
                 if(root.getDeclaredType() != null && root.getObject() != null && root.getDeclaredType() != root.getObject().getClass()) {
                      QName type = marshalRecord.getConversionManager().schemaType(object.getClass());
                      if(type != null) {
                          xsiPrefix = nr.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                          if (null == xsiPrefix) {
                              xsiPrefix = Constants.SCHEMA_INSTANCE_PREFIX;
                              marshalRecord.namespaceDeclaration(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                          }
                          marshalRecord.namespaceDeclaration(Constants.SCHEMA_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
                          String typeValue = type.getLocalPart();
                          if(marshalRecord.isNamespaceAware() && (mediaType.isApplicationXML() || getJsonTypeConfiguration().useXsdTypesWithPrefix())){
                              typeValue = Constants.SCHEMA_PREFIX + marshalRecord.getNamespaceSeparator() + typeValue;
                          }
                          marshalRecord.attribute(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE, xsiPrefix + Constants.COLON + Constants.SCHEMA_TYPE_ATTRIBUTE, typeValue);
                      }
                 }

                marshalRecord.characters(root.getSchemaType(), object, null, false);
            }
        }

        if (null != rootFragment && !(rootFragment.getLocalName().equals(Constants.EMPTY_STRING)) && isIncludeRoot()) {
            marshalRecord.endElement(rootFragment, nr);
            marshalRecord.endPrefixMappings(nr);
        }
        if (!isFragment() ) {
            marshalRecord.endDocument();
        }
        if(isXMLRoot){
            if(descriptor != null){
                marshalRecord.afterContainmentMarshal(null, root.getObject());
            }
        }else{
            marshalRecord.afterContainmentMarshal(null, object);
        }
        marshalRecord.flush();
    }

    /**
     * PUBLIC:
     * @param object the object to marshal
     * @param node the node which the specified object should be marshalled to
     * @throws XMLMarshalException if an error occurred during marshalling
     */
    public void marshal(Object object, Node node) throws XMLMarshalException {
        if(object instanceof JSONWithPadding && !isApplicationJSON()){
            object = ((JSONWithPadding)object).getObject();
        }

        if ((object == null) || (node == null)) {
            throw XMLMarshalException.nullArgumentException();
        }

        ABSTRACT_SESSION session = null;
        DESCRIPTOR xmlDescriptor = null;

        boolean isXMLRoot = (object instanceof Root);
        if(isXMLRoot){
            try{
                session = context.getSession(((Root)object).getObject());
                if(session != null){
                    xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
                }
            }catch (XMLMarshalException marshalException) {
                if (!isSimpleXMLRoot((Root) object)) {
                    throw marshalException;
                }
            }
        }else{
            Class<? extends Object> objectClass = object.getClass();
            session = context.getSession(objectClass);
            xmlDescriptor = getDescriptor(objectClass, session);
        }

        NodeRecord contentHandlerRecord = new NodeRecord(node);
        contentHandlerRecord.setMarshaller(this);
        if (!isXMLRoot) {
            if ((null == xmlDescriptor.getDefaultRootElement()) && (node.getNodeType() == Node.ELEMENT_NODE) && (xmlDescriptor.getSchemaReference() != null) && (xmlDescriptor.getSchemaReference().getType() == XMLSchemaReference.COMPLEX_TYPE)) {
                Attr typeAttr = ((Element) node).getAttributeNodeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE);
                if (typeAttr == null) {
                    NamespaceResolver namespaceResolver = xmlDescriptor.getNonNullNamespaceResolver();
                    String xsiPrefix = namespaceResolver.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);

                    if (null == xsiPrefix) {
                        xsiPrefix = namespaceResolver.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX);
                    }

                    String value = xmlDescriptor.getSchemaReference().getSchemaContext();

                    ((Element) node).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                    ((Element) node).setAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, xsiPrefix + Constants.COLON + Constants.SCHEMA_TYPE_ATTRIBUTE, value);

                } else {
                    String value = xmlDescriptor.getSchemaReference().getSchemaContext();
                    typeAttr.setValue(value);
                }
            }
        }
        marshal(object, contentHandlerRecord, session, xmlDescriptor,isXMLRoot);
    }

    /**
     * PUBLIC:
     * Convert the given object to XML and update the given outputStream with that XML Document
     * @param object the object to marshal
     * @param outputStream the outputStream to marshal the object to
     * @throws XMLMarshalException if an error occurred during marshalling
     */
    public void marshal(Object object, OutputStream outputStream) throws XMLMarshalException {
        marshal (object, outputStream, null, null);
    }

    private void marshal(Object object, OutputStream outputStream, ABSTRACT_SESSION session, DESCRIPTOR xmlDescriptor) throws XMLMarshalException {
        if ((object == null) || (outputStream == null)) {
            throw XMLMarshalException.nullArgumentException();
        }
        boolean isXMLRoot = false;
        String version = DEFAULT_XML_VERSION;
        String encoding = getEncoding();

        String callbackName = null;
        if(object instanceof JSONWithPadding){
            callbackName = ((JSONWithPadding)object).getCallbackName();
            object = ((JSONWithPadding)object).getObject();
            if(object == null){
                throw XMLMarshalException.nullArgumentException();
            }
        }

        if (object instanceof Root) {
            isXMLRoot = true;
            Root xroot = (Root) object;
            encoding = xroot.getEncoding() != null ? xroot.getEncoding() : encoding;
        }

        if(!encoding.equals(Constants.DEFAULT_XML_ENCODING)) {
            try {
                OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding);
                marshal(object, writer, session, xmlDescriptor);
                writer.flush();
            } catch(EclipseLinkException e) {
                throw e;
            } catch(Exception e) {
                throw XMLMarshalException.marshalException(e);
            }
            return;
        }

        MarshalRecord marshalRecord;
        if (isFormattedOutput()) {
            if(isApplicationJSON()) {
                marshalRecord = new JSONFormattedWriterRecord(outputStream, callbackName);
            } else {
                marshalRecord = new FormattedOutputStreamRecord();
                ((FormattedOutputStreamRecord)marshalRecord).setOutputStream(outputStream);
            }
        } else {
            if(isApplicationJSON()) {
                marshalRecord = new JSONWriterRecord(outputStream, callbackName);
            } else {
                marshalRecord = new OutputStreamRecord();
                ((OutputStreamRecord)marshalRecord).setOutputStream(outputStream);
            }
        }

        marshalStreamOrWriter(object, marshalRecord, session, xmlDescriptor, isXMLRoot);
   }

    /**
     * PUBLIC:
     * Convert the given object to XML and update the given result with that XML Document
     * @param object the object to marshal
     * @param result the result to marshal the object to
     * @throws XMLMarshalException if an error occurred during marshalling
     */
    public void marshal(Object object, Result result) throws XMLMarshalException {
        if ((object == null) || (result == null)) {
            throw XMLMarshalException.nullArgumentException();
        }
        DESCRIPTOR xmlDescriptor = null;
        ABSTRACT_SESSION session = null;

        boolean isXMLRoot = (object instanceof Root);

        if(isXMLRoot){
            try{
                session = context.getSession(((Root)object).getObject());
                if(session != null){
                    xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
                }
           }catch (XMLMarshalException marshalException) {
                if (!isSimpleXMLRoot((Root) object)) {
                    throw marshalException;
                }
            }
        }else{
            Class<? extends Object> objectClass = object.getClass();
            session = context.getSession(objectClass);
            xmlDescriptor = getDescriptor(objectClass, session);
        }

        //if this is a simple xml root, the session and descriptor will be null
        if (result instanceof StreamResult) {
            StreamResult streamResult = (StreamResult) result;
            Writer writer = streamResult.getWriter();
            if (writer != null) {
                marshal(object, writer, session, xmlDescriptor);
            } else if (streamResult.getOutputStream() != null) {
                marshal(object, streamResult.getOutputStream(), session, xmlDescriptor);
            } else {
                try {
                    File f;
                    try {
                        f = new File(new URL(streamResult.getSystemId()).toURI());
                    } catch(MalformedURLException malformedURLException) {
                        try {
                            f = new File(streamResult.getSystemId());
                        } catch(Exception e) {
                            throw malformedURLException;
                        }
                    }
                    writer = new FileWriter(f);
                    try {
                        marshal(object, writer, session, xmlDescriptor);
                    } finally {
                        writer.close();
                    }
                } catch (Exception e) {
                    throw XMLMarshalException.marshalException(e);
                }
            }
        }else if (result instanceof DOMResult) {
            DOMResult domResult = (DOMResult) result;
            // handle case where the node is null
            if (domResult.getNode() == null) {
                domResult.setNode(this.objectToXML(object));
            } else {
                marshal(object, domResult.getNode());
            }
        } else if (result instanceof SAXResult) {
            SAXResult saxResult = (SAXResult) result;
            marshal(object, saxResult.getHandler());
        } else if (result instanceof ExtendedResult){
            marshal(object, ((ExtendedResult)result).createRecord(), session, xmlDescriptor, isXMLRoot);
        }else {
            if (result.getClass().equals(staxResultClass)) {
                try {
                    Object xmlStreamWriter = PrivilegedAccessHelper.invokeMethod(staxResultGetStreamWriterMethod, result);
                    if (xmlStreamWriter != null) {
                        MarshalRecord record = (MarshalRecord)PrivilegedAccessHelper.invokeConstructor(xmlStreamWriterRecordConstructor, new Object[]{xmlStreamWriter});
                        record.setMarshaller(this);
                        marshal(object, record, session, xmlDescriptor, isXMLRoot);
                        return;
                    } else {
                        Object xmlEventWriter = PrivilegedAccessHelper.invokeMethod(staxResultGetEventWriterMethod, result);
                        if(xmlEventWriter != null) {
                            MarshalRecord record = (MarshalRecord)PrivilegedAccessHelper.invokeConstructor(xmlEventWriterRecordConstructor, new Object[]{xmlEventWriter});
                            record.setMarshaller(this);
                            marshal(object, record, session, xmlDescriptor, isXMLRoot);
                            return;
                        }
                    }
                } catch(EclipseLinkException e) {
                    throw e;
                } catch (Exception e) {
                    throw XMLMarshalException.marshalException(e);
                }
            }
            java.io.StringWriter writer = new java.io.StringWriter();
            marshal(object, writer);
            javax.xml.transform.stream.StreamSource source = new javax.xml.transform.stream.StreamSource(new java.io.StringReader(writer.toString()));
            getTransformer().transform(source, result);
        }
        return;
    }

    /**
    * PUBLIC:
    * Convert the given object to XML and update the given writer with that XML Document
    * @param object the object to marshal
    * @param writer the writer to marshal the object to
    * @throws XMLMarshalException if an error occurred during marshalling
    */
    public void marshal(Object object, Writer writer) throws XMLMarshalException {
        marshal(object, writer, null, null);
    }

    private void marshal(Object object, Writer writer, ABSTRACT_SESSION session, DESCRIPTOR xmlDescriptor) throws XMLMarshalException {
        if ((object == null) || (writer == null)) {
            throw XMLMarshalException.nullArgumentException();
        }
        boolean isXMLRoot = false;
        String version = DEFAULT_XML_VERSION;
        String encoding = getEncoding();

        String callbackName = null;
        if(object instanceof JSONWithPadding){
            callbackName = ((JSONWithPadding)object).getCallbackName();
            object = ((JSONWithPadding)object).getObject();
            if(object == null){
                throw XMLMarshalException.nullArgumentException();
            }
        }

        if (object instanceof Root) {
            isXMLRoot = true;
            Root xroot = (Root) object;
            version = xroot.getXMLVersion() != null ? xroot.getXMLVersion() : version;
            encoding = xroot.getEncoding() != null ? xroot.getEncoding() : encoding;
        }

        MarshalRecord marshalRecord;
        writer = wrapWriter(writer);
        if (isFormattedOutput()) {
            if(isApplicationJSON()) {
                marshalRecord = new JSONFormattedWriterRecord(writer, callbackName);
            } else {
                marshalRecord = new FormattedWriterRecord();
                ((FormattedWriterRecord) marshalRecord).setWriter(writer);
            }
        } else {
            if(isApplicationJSON()) {
                marshalRecord = new JSONWriterRecord(writer, callbackName);
            } else {
                marshalRecord = new WriterRecord();
                ((WriterRecord) marshalRecord).setWriter(writer);
            }
        }

        marshalStreamOrWriter(object, marshalRecord, session, xmlDescriptor, isXMLRoot);
     }

    private void marshalStreamOrWriter(Object object, MarshalRecord marshalRecord, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) {
        marshalRecord.setMarshaller(this);

        if(isXMLRoot){
            if(session == null || descriptor == null){
                try{
                    session = context.getSession(((Root)object).getObject());
                    if(session != null){
                        descriptor = getDescriptor(((Root)object).getObject(), session);
                    } else if (descriptor == null) {
                        descriptor = context.getDescriptor(new QName(((Root)object).getNamespaceURI(),((Root)object).getLocalName()));
                    }
                }catch (XMLMarshalException marshalException) {
                    if (!isSimpleXMLRoot((Root) object)) {
                        throw marshalException;
                    }
                }
            }
        }else{
            Class<? extends Object> objectClass = object.getClass();
            if(object instanceof Collection) {
                int valueSize = ((Collection)object).size();
                if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
                    marshalRecord.startCollection();
                }
                String valueWrapper;
                for(Object o : (Collection) object) {
                    if (o == null) {
                        valueWrapper = this.getValueWrapper();
                        if (isApplicationJSON()) {
                            this.setValueWrapper("");
                            marshalRecord.setMarshaller(this);
                        }
                        marshalRecord.nilSimple(null);
                        this.setValueWrapper(valueWrapper);
                    } else {
                        if (isApplicationJSON() && o != null && (o.getClass() == CoreClassConstants.STRING || o.getClass() == CoreClassConstants.BOOLEAN || CoreClassConstants.NUMBER.isAssignableFrom(o.getClass()))) {
                            if (marshalRecord.getSession() == null) {
                                marshalRecord.setSession((ABSTRACT_SESSION) this.getContext().getSession());
                            }
                            valueWrapper = this.getValueWrapper();
                            this.setValueWrapper("");
                            marshalRecord.setMarshaller(this);
                            marshalRecord.characters(null, o, null, false);
                            this.setValueWrapper(valueWrapper);
                        } else {
                            marshal(o, marshalRecord);
                        }
                    }
                }
                if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
                    marshalRecord.endCollection();
                }
                marshalRecord.flush();
                return;
            } else if(objectClass.isArray()) {
                int arrayLength = Array.getLength(object);
                if(marshalRecord.getMarshaller().isApplicationJSON() && (arrayLength > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
                    marshalRecord.startCollection();
                }
                for(int x=0; x<arrayLength; x++) {
                    marshal(Array.get(object, x), marshalRecord);
                }
                if(marshalRecord.getMarshaller().isApplicationJSON() && (arrayLength > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
                    marshalRecord.endCollection();
                }
                marshalRecord.flush();
                return;
            }
            if(session == null || descriptor == null){
                session = context.getSession(objectClass);
                descriptor = getDescriptor(objectClass, session);
            }
        }

        marshal(object, marshalRecord, session, descriptor, isXMLRoot);
        marshalRecord.flush();
    }

    /**
     * INTERNAL:
     * Wrap Writer in a BufferedWriter only if its write() operations may be costly
     * (such as FileWriters and OutputStreamWriters).
     */
    private Writer wrapWriter(Writer writer) {
        if (writer instanceof OutputStreamWriter) {
            return new BufferedWriter(writer);
        }
        return writer;
    }

    /**
     * PUBLIC:
     * Convert the given object to an XML Document
     * @param object the object to marshal
     * @return the document which the specified object has been marshalled to
     * @throws XMLMarshalException if an error occurred during marshalling
     */
    public Document objectToXML(Object object) throws XMLMarshalException {
        boolean isXMLRoot = (object instanceof Root);
        DESCRIPTOR xmlDescriptor = getDescriptor(object, isXMLRoot);
        return objectToXML(object, xmlDescriptor, isXMLRoot);
    }

    /**
    * INTERNAL:
    * Convert the given object to an XML Document
    * @param object the object to marshal
    * @return the document which the specified object has been marshalled to
    * @param descriptor the XMLDescriptor for the object being marshalled
    * @throws XMLMarshalException if an error occurred during marshalling
    */
    protected Document objectToXML(Object object, DESCRIPTOR descriptor, boolean isXMLRoot) throws XMLMarshalException {
        ABSTRACT_SESSION session = context.getSession(descriptor);
        MarshalRecord marshalRecord = new NodeRecord();
        marshalRecord.setMarshaller(this);
        marshal(object, marshalRecord, session, descriptor, isXMLRoot);
        return marshalRecord.getDocument();
    }

    /**
     * INTERNAL:
     * Like ObjectToXML but is may also return a document fragment instead of a document in the
     * case of a non-root object.
     */
    protected Node objectToXMLNode(Object object, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) throws XMLMarshalException {
        return objectToXMLNode(object, null, session, descriptor, isXMLRoot);
    }

    protected Node objectToXMLNode(Object object, Node rootNode, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) throws XMLMarshalException {
        MarshalRecord marshalRecord = new NodeRecord();
        marshalRecord.setMarshaller(this);
        marshalRecord.getNamespaceResolver().setDOM(rootNode);
        marshal(object, marshalRecord, session, descriptor, isXMLRoot);
        return marshalRecord.getDocument();
    }

    public void setAttachmentMarshaller(XMLAttachmentMarshaller atm) {
        this.attachmentMarshaller = atm;
    }

    /**
     * Value that will be used to prefix attributes.
     * Ignored marshalling XML.
     * @since 2.4
     */
    public void setAttributePrefix(String attributePrefix) {
        this.attributePrefix = attributePrefix;
    }

    /**
     * Set the encoding on this XMLMarshaller
     * If the encoding is not set the default UTF-8 will be used
     * @param newEncoding the encoding to set on this XMLMarshaller
     */
    @Override
    public void setEncoding(String newEncoding) {
        super.setEncoding(newEncoding);
        if(null != transformer) {
            transformer.setEncoding(newEncoding);
        }
    }

    /**
     * Set if this XMLMarshaller should format the XML
     * By default this is set to true and the XML marshalled will be formatted.
     * @param shouldFormat if this XMLMarshaller should format the XML
     */
    @Override
    public void setFormattedOutput(boolean shouldFormat) {
        super.setFormattedOutput(shouldFormat);
        if(null != transformer) {
            transformer.setFormattedOutput(shouldFormat);
        }
    }

    /**
     * PUBLIC:
     * Set if this should marshal to a fragment.  If true an XML header string is not written out.
     * @param fragment if this should marshal to a fragment or not
     */
    public void setFragment(boolean fragment) {
        this.fragment = fragment;
        if(null != transformer) {
            transformer.setFragment(fragment);
        }
    }

    /**
     * Determine if the {@code @XMLRootElement} should be marshalled when present.
     * Ignored marshalling XML.
     * @since 2.4
     */
    public void setIncludeRoot(boolean includeRoot) {
         this.includeRoot = includeRoot;
    }

    /**
     * Name of the property to determine if empty collections should be marshalled as []
     * Ignored marshalling XML.
     * @since 2.4
     */
    public void setMarshalEmptyCollections(Boolean marshalEmptyCollections) {
        this.marshalEmptyCollections = marshalEmptyCollections;
    }

    /**
     * Set the MediaType for this xmlMarshaller.
     * See org.eclipse.persistence.oxm.MediaType for the media types supported by EclipseLink MOXy
     */
    public void setMediaType(MEDIA_TYPE mediaType) {
        this.mediaType = mediaType;
    }

    /**
     * Set the namespace separator used during marshal operations.
     * If mediaType is application/json '.' is the default
     * Ignored marshalling XML.
     * @since 2.4
     */
    public void setNamespaceSeparator(char namespaceSeparator) {
        this.namespaceSeparator = namespaceSeparator;
    }

   /**
     * Set the no namespace schema location on this XMLMarshaller
     * @param newNoNamespaceSchemaLocation no namespace schema location to be seton this XMLMarshaller
     */
    public void setNoNamespaceSchemaLocation(String newNoNamespaceSchemaLocation) {
       noNamespaceSchemaLocation = newNoNamespaceSchemaLocation;
    }

    /**
     * Property to determine if size 1 any collections should be treated as collections
     * Ignored marshalling XML.
     */
    public void setReduceAnyArrays(boolean reduceAnyArrays) {
        this.reduceAnyArrays = reduceAnyArrays;
    }

    public void setSchema(Schema schema) {
        this.schema = schema;
    }

    /**
     * Set the schema location on this XMLMarshaller
     * @param newSchemaLocation the schema location to be seton this XMLMarshaller
     */
    public void setSchemaLocation(String newSchemaLocation) {
       schemaLocation = newSchemaLocation;
    }

    public void setWrapperAsCollectionName(boolean wrapperAsCollectionName) {
        this.wrapperAsCollectionName = wrapperAsCollectionName;
    }

    /**
     * Name of the property to marshal/unmarshal as a wrapper on the text() mappings
     * Ignored marshalling XML.
     * @since 2.4
     */
    public void setValueWrapper(String valueWrapper) {
        this.valueWrapper = valueWrapper;
    }

    /**
     * <p>
     * Set this Marshaller's XML Header.  This header string will appear after
     * the XML processing instruction (&lt;?xml ...&gt;), but before the start
     * of the document's data.
     * </p>
     *
     * <p>
     * This feature is only supported when marshalling to Stream, Writer,
     * or StreamResult.
     * </p>
     * @since 2.4
     */
    public void setXmlHeader(String xmlHeader) {
        this.xmlHeader = xmlHeader;
    }

    public void setMarshalAttributeGroup(Object group) {
        this.marshalAttributeGroup = group;

    }

    public Object getMarshalAttributeGroup() {
        return this.marshalAttributeGroup;
    }

    public Boolean isLogPayload() {
        return logPayload;
    }

    public void setLogPayload(Boolean logPayload) {
        this.logPayload = logPayload;
    }
}
