/*
 * 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.localization.JAXBLocalization;
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 streamWriterRecordClass = PrivilegedAccessHelper.getClassForName(XML_STREAM_WRITER_RECORD_CLASS_NAME);
            Class streamWriterClass = PrivilegedAccessHelper.getClassForName(XML_STREAM_WRITER_CLASS_NAME);
            xmlStreamWriterRecordConstructor = PrivilegedAccessHelper.getConstructorFor(streamWriterRecordClass, new Class[]{streamWriterClass}, true);

            Class eventWriterRecordClass = PrivilegedAccessHelper.getClassForName(XML_EVENT_WRITER_RECORD_CLASS_NAME);
            Class 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 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 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 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 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 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 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 || writer instanceof FileWriter) {
            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;
    }
}
