/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.scxml2.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLReporter;
import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.XMLEventAllocator;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.scxml2.PathResolver;
import org.apache.commons.scxml2.SCXMLConstants;
import org.apache.commons.scxml2.env.SimpleErrorHandler;
import org.apache.commons.scxml2.env.URLResolver;
import org.apache.commons.scxml2.model.Action;
import org.apache.commons.scxml2.model.ActionsContainer;
import org.apache.commons.scxml2.model.Assign;
import org.apache.commons.scxml2.model.Cancel;
import org.apache.commons.scxml2.model.Content;
import org.apache.commons.scxml2.model.ContentContainer;
import org.apache.commons.scxml2.model.CustomAction;
import org.apache.commons.scxml2.model.CustomActionWrapper;
import org.apache.commons.scxml2.model.Data;
import org.apache.commons.scxml2.model.Datamodel;
import org.apache.commons.scxml2.model.DoneData;
import org.apache.commons.scxml2.model.Else;
import org.apache.commons.scxml2.model.ElseIf;
import org.apache.commons.scxml2.model.EnterableState;
import org.apache.commons.scxml2.model.Executable;
import org.apache.commons.scxml2.model.JsonValue;
import org.apache.commons.scxml2.model.NodeListValue;
import org.apache.commons.scxml2.model.NodeValue;
import org.apache.commons.scxml2.model.ParsedValueContainer;
import org.apache.commons.scxml2.model.Final;
import org.apache.commons.scxml2.model.Finalize;
import org.apache.commons.scxml2.model.Foreach;
import org.apache.commons.scxml2.model.History;
import org.apache.commons.scxml2.model.If;
import org.apache.commons.scxml2.model.Initial;
import org.apache.commons.scxml2.model.Invoke;
import org.apache.commons.scxml2.model.Log;
import org.apache.commons.scxml2.model.ModelException;
import org.apache.commons.scxml2.model.OnEntry;
import org.apache.commons.scxml2.model.OnExit;
import org.apache.commons.scxml2.model.Parallel;
import org.apache.commons.scxml2.model.Param;
import org.apache.commons.scxml2.model.ParamsContainer;
import org.apache.commons.scxml2.model.Raise;
import org.apache.commons.scxml2.model.SCXML;
import org.apache.commons.scxml2.model.Script;
import org.apache.commons.scxml2.model.Send;
import org.apache.commons.scxml2.model.SimpleTransition;
import org.apache.commons.scxml2.model.State;
import org.apache.commons.scxml2.model.TextValue;
import org.apache.commons.scxml2.model.Transition;
import org.apache.commons.scxml2.model.TransitionType;
import org.apache.commons.scxml2.model.TransitionalState;
import org.apache.commons.scxml2.model.Var;
import org.apache.commons.scxml2.model.NodeTextValue;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * <p>The SCXMLReader provides the ability to read a SCXML document into
 * the Java object model provided in the model package.</p>
 *
 * <p>See latest version of the SCXML Working Draft for more details.</p>
 *
 * <p><b>NOTE:</b> The SCXMLReader assumes that the SCXML document to be
 * parsed is well-formed and correct. If that assumption does not hold,
 * any subsequent behavior is undefined.</p>
 *
 * @since 1.0
 */
public final class SCXMLReader {

    private static final org.apache.commons.logging.Log logger = LogFactory.getLog(SCXMLReader.class);

    /**
     * By default Sun/Oracle XMLStreamReader implementation doesn't report CDATA events.
     * This can be turned on (as needed by SCXMLReader) by setting this property TRUE
     */
    public final static String XMLInputFactory_JDK_PROP_REPORT_CDATA = "http://java.sun.com/xml/stream/properties/report-cdata-event";

    //---------------------- PRIVATE CONSTANTS ----------------------//
    /**
     * The version attribute value the SCXML element <em>must</em> have as stated by the spec: 3.2.1
     */
    private static final String SCXML_REQUIRED_VERSION = "1.0";
    /**
     * The default namespace for attributes.
     */
    private static final String XMLNS_DEFAULT = null;

    //---- ERROR MESSAGES ----//
    /**
     * Null URL passed as argument.
     */
    private static final String ERR_NULL_URL = "Cannot parse null URL";

    /**
     * Null path passed as argument.
     */
    private static final String ERR_NULL_PATH = "Cannot parse null path";

    /**
     * Null InputStream passed as argument.
     */
    private static final String ERR_NULL_ISTR = "Cannot parse null InputStream";

    /**
     * Null Reader passed as argument.
     */
    private static final String ERR_NULL_READ = "Cannot parse null Reader";

    /**
     * Null Source passed as argument.
     */
    private static final String ERR_NULL_SRC = "Cannot parse null Source";

    /**
     * Error message while attempting to define a custom action which does
     * not extend the Commons SCXML Action base class.
     */
    private static final String ERR_CUSTOM_ACTION_TYPE = "Custom actions list"
            + " contained unknown object, class not a Commons SCXML Action class subtype: ";

    /**
     * Parser configuration error while trying to parse stream to DOM node(s).
     */
    private static final String ERR_PARSER_CFG = "ParserConfigurationException while trying"
            + " to parse stream into DOM node(s).";

    /**
     * Error message when the URI in a &lt;state&gt;'s &quot;src&quot;
     * attribute does not point to a valid SCXML document, and thus cannot be
     * parsed.
     */
    private static final String ERR_STATE_SRC =
            "Source attribute in <state src=\"{0}\"> cannot be parsed";

    /**
     * Error message when the target of the URI fragment in a &lt;state&gt;'s
     * &quot;src&quot; attribute is not defined in the referenced document.
     */
    private static final String ERR_STATE_SRC_FRAGMENT = "URI Fragment in "
            + "<state src=\"{0}\"> is an unknown state in referenced document";

    /**
     * Error message when the target of the URI fragment in a &lt;state&gt;'s
     * &quot;src&quot; attribute is not a &lt;state&gt; or &lt;final&gt; in
     * the referenced document.
     */
    private static final String ERR_STATE_SRC_FRAGMENT_TARGET = "URI Fragment"
            + " in <state src=\"{0}\"> does not point to a <state> or <final>";

    /**
     * Error message when the target of the URI fragment in a &lt;state&gt;'s
     * &quot;src&quot; attribute is not a &lt;state&gt; or &lt;final&gt; in
     * the referenced document.
     */
    private static final String ERR_REQUIRED_ATTRIBUTE_MISSING = "<{0}> is missing"
            +" required attribute \"{1}\" value at {2}";

    /**
     * Error message when the target of the URI fragment in a &lt;state&gt;'s
     * &quot;src&quot; attribute is not a &lt;state&gt; or &lt;final&gt; in
     * the referenced document.
     */
    private static final String ERR_ATTRIBUTE_NOT_BOOLEAN = "Illegal value \"{0}\""
            + "for attribute \"{1}\" in element <{2}> at {3}."
            +" Only the value \"true\" or \"false\" is allowed.";

    /**
     * Error message when the element (state|parallel|final|history) uses an id value
     * with the reserved prefix {@link SCXML#GENERATED_TT_ID_PREFIX}.
     */
    private static final String ERR_RESERVED_ID_PREFIX = "Reserved id prefix \""
            +SCXML.GENERATED_TT_ID_PREFIX+"\" used for <{0} id=\"{1}\"> at {2}";

    /**
     * Error message when the target of the URI fragment in a &lt;state&gt;'s
     * &quot;src&quot; attribute is not defined in the referenced document.
     */
    private static final String ERR_UNSUPPORTED_TRANSITION_TYPE = "Unsupported transition type "
            + "for <transition type=\"{0}\"> at {1}.";

    /**
     * Error message when the target of the URI fragment in a &lt;state&gt;'s
     * &quot;src&quot; attribute is not a &lt;state&gt; or &lt;final&gt; in
     * the referenced document.
     */
    private static final String ERR_INVALID_VERSION = "The <scxml> element defines"
            +" an unsupported version \"{0}\", only version \"1.0\" is supported.";

    //------------------------- PUBLIC API METHODS -------------------------//
    /*
     * Public methods
     */
    /**
     * Parse the SCXML document at the supplied path.
     *
     * @param scxmlPath The real path to the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final String scxmlPath)
            throws IOException, ModelException, XMLStreamException {

        return read(scxmlPath, new Configuration());
    }

    /**
     * Parse the SCXML document at the supplied path with the given {@link Configuration}.
     *
     * @param scxmlPath The real path to the SCXML document.
     * @param configuration The {@link Configuration} to use when parsing the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final String scxmlPath, final Configuration configuration)
            throws IOException, ModelException, XMLStreamException {

        if (scxmlPath == null) {
            throw new IllegalArgumentException(ERR_NULL_PATH);
        }
        SCXML scxml = readInternal(configuration, null, scxmlPath, null, null, null);
        if (scxml != null) {
            ModelUpdater.updateSCXML(scxml);
        }
        return scxml;
    }

    /**
     * Parse the SCXML document at the supplied {@link URL}.
     *
     * @param scxmlURL The SCXML document {@link URL} to parse.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final URL scxmlURL)
            throws IOException, ModelException, XMLStreamException {

        return read(scxmlURL, new Configuration());
    }

    /**
     * Parse the SCXML document at the supplied {@link URL} with the given {@link Configuration}.
     *
     * @param scxmlURL The SCXML document {@link URL} to parse.
     * @param configuration The {@link Configuration} to use when parsing the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final URL scxmlURL, final Configuration configuration)
            throws IOException, ModelException, XMLStreamException {

        if (scxmlURL == null) {
            throw new IllegalArgumentException(ERR_NULL_URL);
        }
        SCXML scxml = readInternal(configuration, scxmlURL, null, null, null, null);
        if (scxml != null) {
            ModelUpdater.updateSCXML(scxml);
        }
        return scxml;
    }

    /**
     * Parse the SCXML document supplied by the given {@link InputStream}.
     *
     * @param scxmlStream The {@link InputStream} supplying the SCXML document to parse.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final InputStream scxmlStream)
            throws IOException, ModelException, XMLStreamException {

        return read(scxmlStream, new Configuration());
    }

    /**
     * Parse the SCXML document supplied by the given {@link InputStream} with the given {@link Configuration}.
     *
     * @param scxmlStream The {@link InputStream} supplying the SCXML document to parse.
     * @param configuration The {@link Configuration} to use when parsing the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final InputStream scxmlStream, final Configuration configuration)
            throws IOException, ModelException, XMLStreamException {

        if (scxmlStream == null) {
            throw new IllegalArgumentException(ERR_NULL_ISTR);
        }
        SCXML scxml = readInternal(configuration, null, null, scxmlStream, null, null);
        if (scxml != null) {
            ModelUpdater.updateSCXML(scxml);
        }
        return scxml;
    }

    /**
     * Parse the SCXML document supplied by the given {@link Reader}.
     *
     * @param scxmlReader The {@link Reader} supplying the SCXML document to parse.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final Reader scxmlReader)
            throws IOException, ModelException, XMLStreamException {

        return read(scxmlReader, new Configuration());
    }

    /**
     * Parse the SCXML document supplied by the given {@link Reader} with the given {@link Configuration}.
     *
     * @param scxmlReader The {@link Reader} supplying the SCXML document to parse.
     * @param configuration The {@link Configuration} to use when parsing the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final Reader scxmlReader, final Configuration configuration)
            throws IOException, ModelException, XMLStreamException {

        if (scxmlReader == null) {
            throw new IllegalArgumentException(ERR_NULL_READ);
        }
        SCXML scxml = readInternal(configuration, null, null, null, scxmlReader, null);
        if (scxml != null) {
            ModelUpdater.updateSCXML(scxml);
        }
        return scxml;
    }

    /**
     * Parse the SCXML document supplied by the given {@link Source}.
     *
     * @param scxmlSource The {@link Source} supplying the SCXML document to parse.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final Source scxmlSource)
            throws IOException, ModelException, XMLStreamException {

        return read(scxmlSource, new Configuration());
    }

    /**
     * Parse the SCXML document supplied by the given {@link Source} with the given {@link Configuration}.
     *
     * @param scxmlSource The {@link Source} supplying the SCXML document to parse.
     * @param configuration The {@link Configuration} to use when parsing the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    public static SCXML read(final Source scxmlSource, final Configuration configuration)
            throws IOException, ModelException, XMLStreamException {

        if (scxmlSource == null) {
            throw new IllegalArgumentException(ERR_NULL_SRC);
        }
        SCXML scxml = readInternal(configuration, null, null, null, null, scxmlSource);
        if (scxml != null) {
            ModelUpdater.updateSCXML(scxml);
        }
        return scxml;
    }

    //---------------------- PRIVATE UTILITY METHODS ----------------------//
    /**
     * Parse the SCXML document at the supplied {@link URL} using the supplied {@link Configuration}, but do not
     * wire up the object model to be usable just yet. Exactly one of the url, path, stream, reader or source
     * parameters must be provided.
     *
     * @param configuration The {@link Configuration} to use when parsing the SCXML document.
     * @param scxmlURL The optional SCXML document {@link URL} to parse.
     * @param scxmlPath The optional real path to the SCXML document as a string.
     * @param scxmlStream The optional {@link InputStream} providing the SCXML document.
     * @param scxmlReader The optional {@link Reader} providing the SCXML document.
     * @param scxmlSource The optional {@link Source} providing the SCXML document.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document
     *         (not wired up to be immediately usable).
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static SCXML readInternal(final Configuration configuration, final URL scxmlURL, final String scxmlPath,
                                      final InputStream scxmlStream, final Reader scxmlReader, final Source scxmlSource)
            throws IOException, ModelException, XMLStreamException {

        if (configuration.pathResolver == null) {
            if (scxmlURL != null) {
                configuration.pathResolver = new URLResolver(scxmlURL);
            } else if (scxmlPath != null) {
                configuration.pathResolver = new URLResolver(new URL(scxmlPath));
            }
        }

        XMLStreamReader reader = getReader(configuration, scxmlURL, scxmlPath, scxmlStream, scxmlReader, scxmlSource);

        return readDocument(reader, configuration);
    }

    /*
     * Private utility functions for reading the SCXML document.
     */
    /**
     * Read the SCXML document through the {@link XMLStreamReader}.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     *
     * @return The parsed output, the Commons SCXML object model corresponding to the SCXML document
     *         (not wired up to be immediately usable).
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static SCXML readDocument(final XMLStreamReader reader, final Configuration configuration)
            throws IOException, ModelException, XMLStreamException {

        SCXML scxml = new SCXML();
        scxml.setPathResolver(configuration.pathResolver);
        while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_SCXML.equals(name)) {
                            readSCXML(reader, configuration, scxml);
                        } else {
                            reportIgnoredElement(reader, configuration, "DOCUMENT_ROOT", nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, "DOCUMENT_ROOT", nsURI, name);
                    }
                    break;
                case XMLStreamConstants.NAMESPACE:
                    System.err.println(reader.getNamespaceCount());
                    break;
                default:
            }
        }
        return scxml;
    }

    /**
     * Read the contents of this &lt;scxml&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readSCXML(final XMLStreamReader reader, final Configuration configuration, final SCXML scxml)
            throws IOException, ModelException, XMLStreamException {

        scxml.setDatamodelName(readAV(reader, SCXMLConstants.ATTR_DATAMODEL));
        scxml.setExmode(readAV(reader, SCXMLConstants.ATTR_EXMODE));
        scxml.setInitial(readAV(reader, SCXMLConstants.ATTR_INITIAL));
        scxml.setName(readAV(reader, SCXMLConstants.ATTR_NAME));
        scxml.setProfile(readAV(reader, SCXMLConstants.ATTR_PROFILE));
        scxml.setVersion(readRequiredAV(reader, SCXMLConstants.ELEM_SCXML, SCXMLConstants.ATTR_VERSION));
        String binding = readAV(reader, SCXMLConstants.ATTR_BINDING);
        if (binding != null) {
            if (SCXMLConstants.ATTR_BINDING_LATE.equals(binding)) {
                scxml.setLateBinding(true);
            } else if (SCXMLConstants.ATTR_BINDING_EARLY.equals(binding)) {
                scxml.setLateBinding(false);
            } else {
                reportIgnoredAttribute(reader, configuration, SCXMLConstants.ELEM_SCXML, SCXMLConstants.ATTR_BINDING, binding);
            }
        }
        if (!SCXML_REQUIRED_VERSION.equals(scxml.getVersion())) {
            throw new ModelException(new MessageFormat(ERR_INVALID_VERSION).format(new Object[] {scxml.getVersion()}));
        }
        scxml.setNamespaces(readNamespaces(reader));

        boolean hasGlobalScript = false;

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_STATE.equals(name)) {
                            readState(reader, configuration, scxml, null);
                        } else if (SCXMLConstants.ELEM_PARALLEL.equals(name)) {
                            readParallel(reader, configuration, scxml, null);
                        } else if (SCXMLConstants.ELEM_FINAL.equals(name)) {
                            readFinal(reader, configuration, scxml, null);
                        } else if (SCXMLConstants.ELEM_DATAMODEL.equals(name)) {
                            readDatamodel(reader, configuration, scxml, null);
                        } else if (SCXMLConstants.ELEM_SCRIPT.equals(name) && !hasGlobalScript) {
                            readGlobalScript(reader, configuration, scxml);
                            hasGlobalScript = true;
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_SCXML, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_SCXML, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Read the contents of this &lt;state&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     * @param parent The parent {@link TransitionalState} for this state (null for top level state).
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readState(final XMLStreamReader reader, final Configuration configuration, final SCXML scxml,
                                  final TransitionalState parent)
            throws IOException, ModelException, XMLStreamException {

        State state = new State();
        state.setId(readOrGeneratedTransitionTargetId(reader, scxml, SCXMLConstants.ELEM_STATE));
        String initial = readAV(reader, SCXMLConstants.ATTR_INITIAL);
        if (initial != null) {
            state.setFirst(initial);
        }
        String src = readAV(reader, SCXMLConstants.ATTR_SRC);
        if (src != null) {
            String source = src;
            Configuration copy = new Configuration(configuration);
            if (copy.parent == null) {
                copy.parent = scxml;
            }
            if (configuration.pathResolver != null) {
                source = configuration.pathResolver.resolvePath(src);
                copy.pathResolver = configuration.pathResolver.getResolver(src);
            }
            readTransitionalStateSrc(copy, source, state);
        }

        if (parent == null) {
            scxml.addChild(state);
        } else if (parent instanceof State) {
            ((State)parent).addChild(state);
        }
        else {
            ((Parallel)parent).addChild(state);
        }
        scxml.addTarget(state);
        if (configuration.parent != null) {
            configuration.parent.addTarget(state);
        }

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_TRANSITION.equals(name)) {
                            state.addTransition(readTransition(reader, configuration));
                        } else if (SCXMLConstants.ELEM_STATE.equals(name)) {
                            readState(reader, configuration, scxml, state);
                        } else if (SCXMLConstants.ELEM_INITIAL.equals(name)) {
                            readInitial(reader, configuration, state);
                        } else if (SCXMLConstants.ELEM_FINAL.equals(name)) {
                            readFinal(reader, configuration, scxml, state);
                        } else if (SCXMLConstants.ELEM_ONENTRY.equals(name)) {
                            readOnEntry(reader, configuration, state);
                        } else if (SCXMLConstants.ELEM_ONEXIT.equals(name)) {
                            readOnExit(reader, configuration, state);
                        } else if (SCXMLConstants.ELEM_PARALLEL.equals(name)) {
                            readParallel(reader, configuration, scxml, state);
                        } else if (SCXMLConstants.ELEM_DATAMODEL.equals(name)) {
                            readDatamodel(reader, configuration, null, state);
                        } else if (SCXMLConstants.ELEM_INVOKE.equals(name)) {
                            readInvoke(reader, configuration, state);
                        } else if (SCXMLConstants.ELEM_HISTORY.equals(name)) {
                            readHistory(reader, configuration, scxml, state);
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_STATE, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_STATE, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Read the contents of this &lt;parallel&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     * @param parent The parent {@link TransitionalState} for this parallel (null for top level state).
     *
     * @throws IOException An IO error during parsing.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readParallel(final XMLStreamReader reader, final Configuration configuration, final SCXML scxml,
                                     final TransitionalState parent)
            throws IOException, ModelException, XMLStreamException {

        Parallel parallel = new Parallel();
        parallel.setId(readOrGeneratedTransitionTargetId(reader, scxml, SCXMLConstants.ELEM_PARALLEL));
        String src = readAV(reader, SCXMLConstants.ATTR_SRC);
        if (src != null) {
            String source = src;
            Configuration copy = new Configuration(configuration);
            if (copy.parent == null) {
                copy.parent = scxml;
            }
            if (configuration.pathResolver != null) {
                source = configuration.pathResolver.resolvePath(src);
                copy.pathResolver = configuration.pathResolver.getResolver(src);
            }
            readTransitionalStateSrc(copy, source, parallel);
        }

        if (parent == null) {
            scxml.addChild(parallel);
        } else if (parent instanceof State) {
            ((State)parent).addChild(parallel);
        }
        else {
            ((Parallel)parent).addChild(parallel);
        }
        scxml.addTarget(parallel);
        if (configuration.parent != null) {
            configuration.parent.addTarget(parallel);
        }

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_TRANSITION.equals(name)) {
                            parallel.addTransition(readTransition(reader, configuration));
                        } else if (SCXMLConstants.ELEM_STATE.equals(name)) {
                            readState(reader, configuration, scxml, parallel);
                        } else if (SCXMLConstants.ELEM_PARALLEL.equals(name)) {
                            readParallel(reader, configuration, scxml, parallel);
                        } else if (SCXMLConstants.ELEM_ONENTRY.equals(name)) {
                            readOnEntry(reader, configuration, parallel);
                        } else if (SCXMLConstants.ELEM_ONEXIT.equals(name)) {
                            readOnExit(reader, configuration, parallel);
                        } else if (SCXMLConstants.ELEM_DATAMODEL.equals(name)) {
                            readDatamodel(reader, configuration, null, parallel);
                        } else if (SCXMLConstants.ELEM_INVOKE.equals(name)) {
                            readInvoke(reader, configuration, parallel);
                        } else if (SCXMLConstants.ELEM_HISTORY.equals(name)) {
                            readHistory(reader, configuration, scxml, parallel);
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_PARALLEL, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_PARALLEL, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Read the contents of this &lt;final&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     * @param parent The parent {@link State} for this final (null for top level state).
     *
     * @throws IOException An IO error during parsing.
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readFinal(final XMLStreamReader reader, final Configuration configuration, final SCXML scxml,
                                  final State parent)
            throws XMLStreamException, ModelException, IOException {

        Final end = new Final();
        end.setId(readOrGeneratedTransitionTargetId(reader, scxml, SCXMLConstants.ELEM_FINAL));

        if (parent == null) {
            scxml.addChild(end);
        } else {
            parent.addChild(end);
        }

        scxml.addTarget(end);
        if (configuration.parent != null) {
            configuration.parent.addTarget(end);
        }

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_ONENTRY.equals(name)) {
                            readOnEntry(reader, configuration, end);
                        } else if (SCXMLConstants.ELEM_ONEXIT.equals(name)) {
                            readOnExit(reader, configuration, end);
                        } else if (SCXMLConstants.ELEM_DONEDATA.equals(name) && end.getDoneData() == null) {
                            readDoneData(reader, configuration, end);
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_FINAL, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_FINAL, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Read the contents of this &lt;donedata&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param parent The parent {@link State} for this final (null for top level state).
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readDoneData(final XMLStreamReader reader, final Configuration configuration, final Final parent)
            throws XMLStreamException, ModelException {

        DoneData doneData = new DoneData();
        parent.setDoneData(doneData);

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_PARAM.equals(name)) {
                            if (doneData.getContent() == null) {
                                readParam(reader, configuration, doneData);
                            }
                            else {
                                reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_DONEDATA, nsURI, name);
                            }
                        } else if (SCXMLConstants.ELEM_CONTENT.equals(name)) {
                            if (doneData.getParams().isEmpty()) {
                                readContent(reader, configuration, doneData);
                            }
                            else {
                                reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_DONEDATA, nsURI, name);
                            }
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_DONEDATA, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_DONEDATA, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Parse the contents of the SCXML document that this "src" attribute value of a &lt;state&gt; or &lt;parallel&gt;
     * element points to. Without a URL fragment, the entire state machine is imported as contents of the
     * &lt;state&gt; or &lt;parallel&gt;. If a URL fragment is present, the fragment must specify the id of the
     * corresponding &lt;state&gt; or &lt;parallel&gt; to import.
     *
     * @param configuration The {@link Configuration} to use while parsing.
     * @param src The "src" attribute value.
     * @param ts The parent {@link TransitionalState} that specifies this "src" attribute.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readTransitionalStateSrc(final Configuration configuration, final String src,
                                                 final TransitionalState ts)
            throws ModelException {

        // Check for URI fragment
        String[] fragments = src.split("#", 2);
        String location = fragments[0];
        String fragment = null;
        if (fragments.length > 1) {
            fragment = fragments[1];
        }

        // Parse external document
        SCXML externalSCXML;
        try {
            externalSCXML = SCXMLReader.readInternal(configuration, new URL(location), null, null, null, null);
        } catch (Exception e) {
            MessageFormat msgFormat = new MessageFormat(ERR_STATE_SRC);
            String errMsg = msgFormat.format(new Object[] {src});
            throw new ModelException(errMsg + " : " + e.getMessage(), e);
        }

        // Pull in the parts of the external document as needed
        if (fragment == null) {
            // All targets pulled in since its not a src fragment
            if (ts instanceof State) {
                State s = (State) ts;
                Initial ini = new Initial();
                SimpleTransition t = new SimpleTransition();
                t.setNext(externalSCXML.getInitial());
                ini.setTransition(t);
                s.setInitial(ini);
                for (EnterableState child : externalSCXML.getChildren()) {
                    s.addChild(child);
                }
                s.setDatamodel(externalSCXML.getDatamodel());
            } else if (ts instanceof Parallel) {
                // TODO src attribute for <parallel>
            }
        } else {
            // Need to pull in only descendent targets
            Object source = externalSCXML.getTargets().get(fragment);
            if (source == null) {
                MessageFormat msgFormat = new MessageFormat(ERR_STATE_SRC_FRAGMENT);
                String errMsg = msgFormat.format(new Object[] {src});
                throw new ModelException(errMsg);
            }
            if (source instanceof State && ts instanceof State) {
                State s = (State) ts;
                State include = (State) source;
                for (OnEntry onentry : include.getOnEntries()) {
                    s.addOnEntry(onentry);
                }
                for (OnExit onexit : include.getOnExits()) {
                    s.addOnExit(onexit);
                }
                s.setDatamodel(include.getDatamodel());
                List<History> histories = include.getHistory();
                for (History h : histories) {
                    s.addHistory(h);
                    configuration.parent.addTarget(h);
                }
                for (EnterableState child : include.getChildren()) {
                    s.addChild(child);
                    configuration.parent.addTarget(child);
                    readInExternalTargets(configuration.parent, child);
                }
                for (Invoke invoke : include.getInvokes()) {
                    s.addInvoke(invoke);
                }
                if (include.getInitial() != null) {
                    s.setInitial(include.getInitial());
                }
                List<Transition> transitions = include.getTransitionsList();
                for (Transition t : transitions) {
                    s.addTransition(t);
                }
            } else if (ts instanceof Parallel && source instanceof Parallel) {
                // TODO src attribute for <parallel>
            } else {
                MessageFormat msgFormat =
                        new MessageFormat(ERR_STATE_SRC_FRAGMENT_TARGET);
                String errMsg = msgFormat.format(new Object[] {src});
                throw new ModelException(errMsg);
            }
        }
    }

    /**
     * Add all the nested targets from given target to given parent state machine.
     *
     * @param parent The state machine
     * @param es The target to import
     */
    private static void readInExternalTargets(final SCXML parent, final EnterableState es) {
        if (es instanceof TransitionalState) {
            for (History h : ((TransitionalState)es).getHistory()) {
                parent.addTarget(h);
            }
            for (EnterableState child : ((TransitionalState) es).getChildren()) {
                parent.addTarget(child);
                readInExternalTargets(parent, child);
            }
        }
    }

    /**
     * Read the contents of this &lt;datamodel&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     * @param parent The parent {@link TransitionalState} for this datamodel (null for top level).
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readDatamodel(final XMLStreamReader reader, final Configuration configuration,
                                      final SCXML scxml, final TransitionalState parent)
            throws XMLStreamException, ModelException {

        Datamodel dm = new Datamodel();

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_DATA.equals(name)) {
                            readData(reader, configuration, dm);
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_DATAMODEL, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_DATAMODEL, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }

        if (parent == null) {
            scxml.setDatamodel(dm);
        } else {
            parent.setDatamodel(dm);
        }
    }

    /**
     * Read the contents of this &lt;data&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param dm The parent {@link Datamodel} for this data.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readData(final XMLStreamReader reader, final Configuration configuration, final Datamodel dm)
            throws XMLStreamException, ModelException {

        Data datum = new Data();
        datum.setId(readRequiredAV(reader, SCXMLConstants.ELEM_DATA, SCXMLConstants.ATTR_ID));
        final String expr = readAV(reader, SCXMLConstants.ATTR_EXPR);
        final String src = readAV(reader, SCXMLConstants.ATTR_SRC);

        if (expr != null) {
            if (src != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_DATA, SCXMLConstants.ATTR_EXPR, SCXMLConstants.ATTR_SRC);
            }
            datum.setExpr(expr);
            skipToEndElement(reader);
        } else if (src != null ) {
            datum.setSrc(src);
            skipToEndElement(reader);
        } else {
            readParsedValue(reader, configuration, datum, false);
        }
        dm.addData(datum);
    }

    /**
     * Read the contents of this &lt;invoke&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param parent The parent {@link TransitionalState} for this invoke.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readInvoke(final XMLStreamReader reader, final Configuration configuration,
                                   final TransitionalState parent)
            throws XMLStreamException, ModelException {

        Invoke invoke = new Invoke();
        invoke.setId(readAV(reader, SCXMLConstants.ATTR_ID));
        invoke.setIdlocation(readAV(reader, SCXMLConstants.ATTR_IDLOCATION));
        invoke.setSrc(readAV(reader, SCXMLConstants.ATTR_SRC));
        invoke.setSrcexpr(readAV(reader, SCXMLConstants.ATTR_SRCEXPR));
        invoke.setType(readAV(reader, SCXMLConstants.ATTR_TYPE));
        invoke.setAutoForward(readBooleanAV(reader, SCXMLConstants.ELEM_INVOKE, SCXMLConstants.ATTR_AUTOFORWARD));
        invoke.setNamelist(readAV(reader, SCXMLConstants.ATTR_NAMELIST));

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_PARAM.equals(name)) {
                            readParam(reader, configuration, invoke);
                        } else if (SCXMLConstants.ELEM_FINALIZE.equals(name)) {
                            readFinalize(reader, configuration, parent, invoke);
                        } else if (SCXMLConstants.ELEM_CONTENT.equals(name)) {
                            readContent(reader, configuration, invoke);
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_INVOKE, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_INVOKE, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }

        parent.addInvoke(invoke);
    }

    /**
     * Read the contents of this &lt;param&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param parent The parent {@link org.apache.commons.scxml2.model.ParamsContainer} for this param.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readParam(final XMLStreamReader reader, final Configuration configuration,
                                  final ParamsContainer parent)
            throws XMLStreamException, ModelException {

        Param param = new Param();
        param.setName(readRequiredAV(reader, SCXMLConstants.ELEM_PARAM, SCXMLConstants.ATTR_NAME));
        String location = readAV(reader, SCXMLConstants.ATTR_LOCATION);
        String expr = readAV(reader, SCXMLConstants.ATTR_EXPR);
        if (expr != null) {
            if (location != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_PARAM, SCXMLConstants.ATTR_LOCATION, SCXMLConstants.ATTR_EXPR);
            }
            else {
                param.setExpr(expr);
            }
        }
        else if (location == null) {
            // force error missing required location or expr: use location attr for this
            param.setLocation(readRequiredAV(reader, SCXMLConstants.ELEM_PARAM, SCXMLConstants.ATTR_LOCATION));
        }
        else {
            param.setLocation(location);
        }
        parent.getParams().add(param);
        skipToEndElement(reader);
    }

    /**
     * Read the contents of this &lt;finalize&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param state The {@link TransitionalState} which contains the parent {@link Invoke}.
     * @param invoke The parent {@link Invoke} for this finalize.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readFinalize(final XMLStreamReader reader, final Configuration configuration,
                                     final TransitionalState state, final Invoke invoke)
            throws XMLStreamException, ModelException {

        Finalize finalize = new Finalize();
        readExecutableContext(reader, configuration, finalize, null);
        invoke.setFinalize(finalize);
        finalize.setParent(state);
    }

    /**
     * Read the contents of this &lt;content&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param contentContainer The {@link ContentContainer} for this content.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readContent(final XMLStreamReader reader, final Configuration configuration,
                                    final ContentContainer contentContainer)
            throws XMLStreamException, ModelException {

        Content content = new Content();
        content.setExpr(readAV(reader, SCXMLConstants.ATTR_EXPR));
        if (content.getExpr() != null) {
            skipToEndElement(reader);
        }
        else {
            readParsedValue(reader, configuration, content, contentContainer instanceof Invoke);
        }
        contentContainer.setContent(content);
    }

    /**
     * Read the contents of this &lt;initial&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param state The parent composite {@link State} for this initial.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readInitial(final XMLStreamReader reader, final Configuration configuration,
                                    final State state)
            throws XMLStreamException, ModelException {

        Initial initial = new Initial();

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_TRANSITION.equals(name)) {
                            initial.setTransition(readSimpleTransition(reader, configuration));
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_INITIAL, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_INITIAL, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }

        state.setInitial(initial);
    }

    /**
     * Read the contents of this &lt;history&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     * @param ts The parent {@link org.apache.commons.scxml2.model.TransitionalState} for this history.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readHistory(final XMLStreamReader reader, final Configuration configuration,
                                    final SCXML scxml, final TransitionalState ts)
            throws XMLStreamException, ModelException {

        History history = new History();
        history.setId(readOrGeneratedTransitionTargetId(reader, scxml, SCXMLConstants.ELEM_HISTORY));
        history.setType(readAV(reader, SCXMLConstants.ATTR_TYPE));

        ts.addHistory(history);
        scxml.addTarget(history);

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_TRANSITION.equals(name)) {
                            history.setTransition(readTransition(reader, configuration));
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_HISTORY, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_HISTORY, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Read the contents of this &lt;onentry&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param es The parent {@link EnterableState} for this onentry.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readOnEntry(final XMLStreamReader reader, final Configuration configuration,
                                    final EnterableState es)
            throws XMLStreamException, ModelException {

        OnEntry onentry = new OnEntry();
        onentry.setRaiseEvent(readBooleanAV(reader, SCXMLConstants.ELEM_ONENTRY, SCXMLConstants.ATTR_EVENT));
        readExecutableContext(reader, configuration, onentry, null);
        es.addOnEntry(onentry);
    }

    /**
     * Read the contents of this &lt;onexit&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param es The parent {@link EnterableState} for this onexit.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readOnExit(final XMLStreamReader reader, final Configuration configuration,
                                   final EnterableState es)
            throws XMLStreamException, ModelException {

        OnExit onexit = new OnExit();
        onexit.setRaiseEvent(readBooleanAV(reader, SCXMLConstants.ELEM_ONEXIT, SCXMLConstants.ATTR_EVENT));
        readExecutableContext(reader, configuration, onexit, null);
        es.addOnExit(onexit);
    }

    /**
     * Read the contents of this simple &lt;transition&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static SimpleTransition readSimpleTransition(final XMLStreamReader reader, final Configuration configuration)
            throws XMLStreamException, ModelException {

        SimpleTransition transition = new SimpleTransition();
        transition.setNext(readAV(reader, SCXMLConstants.ATTR_TARGET));
        String type = readAV(reader, SCXMLConstants.ATTR_TYPE);
        if (type != null) {
            try {
                transition.setType(TransitionType.valueOf(type));
            }
            catch (IllegalArgumentException e) {
                MessageFormat msgFormat = new MessageFormat(ERR_UNSUPPORTED_TRANSITION_TYPE);
                String errMsg = msgFormat.format(new Object[] {type, reader.getLocation()});
                throw new ModelException(errMsg);
            }
        }

        readExecutableContext(reader, configuration, transition, null);

        return transition;
    }

    /**
     * Read the contents of this &lt;transition&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static Transition readTransition(final XMLStreamReader reader, final Configuration configuration)
            throws XMLStreamException, ModelException {

        Transition transition = new Transition();
        transition.setCond(readAV(reader, SCXMLConstants.ATTR_COND));
        transition.setEvent(readAV(reader, SCXMLConstants.ATTR_EVENT));
        transition.setNext(readAV(reader, SCXMLConstants.ATTR_TARGET));
        String type = readAV(reader, SCXMLConstants.ATTR_TYPE);
        if (type != null) {
            try {
                transition.setType(TransitionType.valueOf(type));
            }
            catch (IllegalArgumentException e) {
                MessageFormat msgFormat = new MessageFormat(ERR_UNSUPPORTED_TRANSITION_TYPE);
                String errMsg = msgFormat.format(new Object[] {type, reader.getLocation()});
                throw new ModelException(errMsg);
            }
        }

        readExecutableContext(reader, configuration, transition, null);

        return transition;
    }

    /**
     * Read this set of executable content elements.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} to which this content belongs.
     * @param parent The optional parent {@link ActionsContainer} if this is child content of an ActionsContainer action.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readExecutableContext(final XMLStreamReader reader, final Configuration configuration,
                                              final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        String end = "";
        if (parent != null) {
            end = parent instanceof If ? SCXMLConstants.ELEM_IF : SCXMLConstants.ELEM_FOREACH;
        } else if (executable instanceof SimpleTransition) {
            end = SCXMLConstants.ELEM_TRANSITION;
        } else if (executable instanceof OnEntry) {
            end = SCXMLConstants.ELEM_ONENTRY;
        } else if (executable instanceof OnExit) {
            end = SCXMLConstants.ELEM_ONEXIT;
        } else if (executable instanceof Finalize) {
            end = SCXMLConstants.ELEM_FINALIZE;
        }

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_RAISE.equals(name)) {
                            if (executable instanceof Finalize) {
                                reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_FINALIZE, nsURI, name);
                            } else {
                                readRaise(reader, configuration, executable, parent);
                            }
                        } else if (SCXMLConstants.ELEM_FOREACH.equals(name)) {
                            readForeach(reader, configuration, executable, parent);
                        } else if (SCXMLConstants.ELEM_IF.equals(name)) {
                            readIf(reader, configuration, executable, parent);
                        } else if (SCXMLConstants.ELEM_LOG.equals(name)) {
                            readLog(reader, executable, parent);
                        } else if (SCXMLConstants.ELEM_ASSIGN.equals(name)) {
                            readAssign(reader, configuration, executable, parent);
                        } else if (SCXMLConstants.ELEM_SEND.equals(name)) {
                            if (executable instanceof Finalize) {
                                reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_FINALIZE, nsURI, name);
                            } else {
                                readSend(reader, configuration, executable, parent);
                            }
                        } else if (SCXMLConstants.ELEM_CANCEL.equals(name)) {
                            readCancel(reader, configuration, executable, parent);
                        } else if (SCXMLConstants.ELEM_SCRIPT.equals(name)) {
                            readScript(reader, configuration, executable, parent);
                        } else if (SCXMLConstants.ELEM_IF.equals(end) && SCXMLConstants.ELEM_ELSEIF.equals(name)) {
                            readElseIf(reader, executable, (If) parent);
                        } else if (SCXMLConstants.ELEM_IF.equals(end) && SCXMLConstants.ELEM_ELSE.equals(name)) {
                            readElse(reader, executable, (If)parent);
                        } else {
                            reportIgnoredElement(reader, configuration, end, nsURI, name);
                        }
                    } else if (SCXMLConstants.XMLNS_COMMONS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_VAR.equals(name)) {
                            readCustomAction(reader, configuration, Var.CUSTOM_ACTION, executable, parent);
                        } else {
                            reportIgnoredElement(reader, configuration, end, nsURI, name);
                        }
                    } else { // custom action
                        CustomAction customAction = null;
                        if (!configuration.customActions.isEmpty()) {
                            for (CustomAction ca : configuration.customActions) {
                                if (ca.getNamespaceURI().equals(nsURI) && ca.getLocalName().equals(name)) {
                                    customAction = ca;
                                    break;
                                }
                            }
                        }
                        if (customAction != null) {
                            readCustomAction(reader, configuration, customAction, executable, parent);
                        } else {
                            reportIgnoredElement(reader, configuration, end, nsURI, name);
                        }
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }
    }

    /**
     * Read the contents of this &lt;raise&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readRaise(final XMLStreamReader reader, final Configuration configuration,
                                  final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        if (executable instanceof Finalize) {
            // https://www.w3.org/TR/2015/REC-scxml-20150901/#finalize
            // [...] the executable content inside <finalize> MUST NOT raise events or invoke external actions.
            // In particular, the <send> and <raise> elements MUST NOT occur.
            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_FINALIZE, SCXMLConstants.XMLNS_SCXML, SCXMLConstants.ELEM_RAISE);
        }
        else {
            Raise raise = new Raise();
            raise.setEvent(readAV(reader, SCXMLConstants.ATTR_EVENT));
            raise.setParent(executable);
            if (parent != null) {
                parent.addAction(raise);
            } else {
                executable.addAction(raise);
            }
            skipToEndElement(reader);
        }
    }

    /**
     * Read the contents of this &lt;if&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this &lt;if&gt; is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readIf(final XMLStreamReader reader, final Configuration configuration,
                               final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        If iff = new If();
        iff.setCond(readRequiredAV(reader, SCXMLConstants.ELEM_IF, SCXMLConstants.ATTR_COND));
        iff.setParent(executable);
        if (parent != null) {
            parent.addAction(iff);
        } else {
            executable.addAction(iff);
        }
        readExecutableContext(reader, configuration, executable, iff);
    }

    /**
     * Read the contents of this &lt;elseif&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param executable The parent {@link Executable} for this action.
     * @param iff The parent {@link If} for this &lt;elseif&gt;.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readElseIf(final XMLStreamReader reader, final Executable executable, final If iff)
            throws XMLStreamException, ModelException {

        ElseIf elseif = new ElseIf();
        elseif.setCond(readRequiredAV(reader, SCXMLConstants.ELEM_ELSEIF, SCXMLConstants.ATTR_COND));
        elseif.setParent(executable);
        iff.addAction(elseif);
        skipToEndElement(reader);
    }

    /**
     * Read the contents of this &lt;else&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param executable The parent {@link Executable} for this action.
     * @param iff The parent {@link If} for this &lt;else&gt;.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readElse(final XMLStreamReader reader, final Executable executable, final If iff)
            throws XMLStreamException {

        Else els = new Else();
        els.setParent(executable);
        iff.addAction(els);
        skipToEndElement(reader);
    }

    /**
     * Read the contents of this &lt;foreach&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this &lt;foreach&gt; is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readForeach(final XMLStreamReader reader, final Configuration configuration,
                                    final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        Foreach fe = new Foreach();
        fe.setArray(readRequiredAV(reader, SCXMLConstants.ELEM_FOREACH, SCXMLConstants.ATTR_ARRAY));
        fe.setItem(readRequiredAV(reader, SCXMLConstants.ELEM_FOREACH, SCXMLConstants.ATTR_ITEM));
        fe.setIndex(readAV(reader, SCXMLConstants.ATTR_INDEX));
        fe.setParent(executable);
        if (parent != null) {
            parent.addAction(fe);
        } else {
            executable.addAction(fe);
        }
        readExecutableContext(reader, configuration, executable, fe);
    }

    /**
     * Read the contents of this &lt;log&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readLog(final XMLStreamReader reader, final Executable executable, final ActionsContainer parent)
            throws XMLStreamException {

        Log log = new Log();
        log.setExpr(readAV(reader, SCXMLConstants.ATTR_EXPR));
        log.setLabel(readAV(reader, SCXMLConstants.ATTR_LABEL));
        log.setParent(executable);
        if (parent != null) {
            parent.addAction(log);
        } else {
            executable.addAction(log);
        }
        skipToEndElement(reader);
    }

    /**
     * Read the contents of this &lt;assign&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readAssign(final XMLStreamReader reader, final Configuration configuration,
                                   final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        Assign assign = new Assign();
        assign.setExpr(readAV(reader, SCXMLConstants.ATTR_EXPR));
        assign.setLocation(readRequiredAV(reader, SCXMLConstants.ELEM_ASSIGN, SCXMLConstants.ATTR_LOCATION));
        assign.setSrc(readAV(reader, SCXMLConstants.ATTR_SRC));
        if (assign.getExpr() != null && assign.getSrc() != null) {
            reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_ASSIGN, SCXMLConstants.ATTR_EXPR, SCXMLConstants.ATTR_SRC);
        }
        else if (assign.getExpr() != null) {
            skipToEndElement(reader);
        }
        else if (assign.getSrc() != null) {
            skipToEndElement(reader);
            String resolvedSrc = assign.getSrc();
            if (configuration.pathResolver != null) {
                resolvedSrc = configuration.pathResolver.resolvePath(resolvedSrc);
            }
            try {
                assign.setParsedValue(ContentParser.DEFAULT_PARSER.parseResource(resolvedSrc));
            } catch (IOException e) {
                throw new ModelException(e);
            }
        }
        else {
            Location location = reader.getLocation();
            readParsedValue(reader, configuration, assign, false);
            if (assign.getParsedValue() == null) {
                // report missing expression (as most common use-case)
                reportMissingAttribute(location, SCXMLConstants.ELEM_ASSIGN, SCXMLConstants.ATTR_EXPR);
            }
        }

        assign.setParent(executable);
        if (parent != null) {
            parent.addAction(assign);
        } else {
            executable.addAction(assign);
        }
    }

    /**
     * Read the contents of this &lt;send&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void readSend(final XMLStreamReader reader, final Configuration configuration,
                                 final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        if (executable instanceof Finalize) {
            // https://www.w3.org/TR/2015/REC-scxml-20150901/#finalize
            // [...] the executable content inside <finalize> MUST NOT raise events or invoke external actions.
            // In particular, the <send> and <raise> elements MUST NOT occur.
            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_FINALIZE, SCXMLConstants.XMLNS_SCXML, SCXMLConstants.ELEM_SEND);
            return;
        }

        Send send = new Send();
        send.setId(readAV(reader, SCXMLConstants.ATTR_ID));
        String attrValue = readAV(reader, SCXMLConstants.ATTR_IDLOCATION);
        if (attrValue != null) {
            if (send.getId() != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_SEND, SCXMLConstants.ATTR_ID, SCXMLConstants.ATTR_IDLOCATION);
            }
            else {
                send.setIdlocation(attrValue);
            }
        }
        send.setDelay(readAV(reader, SCXMLConstants.ATTR_DELAY));
        attrValue = readAV(reader, SCXMLConstants.ATTR_DELAYEXPR);
        if (attrValue != null) {
            if (send.getDelay() != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_SEND, SCXMLConstants.ATTR_DELAY, SCXMLConstants.ATTR_DELAYEXPR);
            }
            else {
                send.setDelayexpr(attrValue);
            }
        }
        send.setEvent(readAV(reader, SCXMLConstants.ATTR_EVENT));
        attrValue = readAV(reader, SCXMLConstants.ATTR_EVENTEXPR);
        if (attrValue != null) {
            if (send.getEvent() != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_SEND, SCXMLConstants.ATTR_EVENT, SCXMLConstants.ATTR_EVENTEXPR);
            }
            else {
                send.setEventexpr(attrValue);
            }
        }
        send.setHints(readAV(reader, SCXMLConstants.ATTR_HINTS));
        send.setNamelist(readAV(reader, SCXMLConstants.ATTR_NAMELIST));
        send.setTarget(readAV(reader, SCXMLConstants.ATTR_TARGET));
        attrValue = readAV(reader, SCXMLConstants.ATTR_TARGETEXPR);
        if (attrValue != null) {
            if (send.getTarget() != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_SEND, SCXMLConstants.ATTR_TARGET, SCXMLConstants.ATTR_TARGETEXPR);
            }
            else {
                send.setTargetexpr(attrValue);
            }
        }
        send.setType(readAV(reader, SCXMLConstants.ATTR_TYPE));
        attrValue = readAV(reader, SCXMLConstants.ATTR_TYPEEXPR);
        if (attrValue != null) {
            if (send.getType() != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_SEND, SCXMLConstants.ATTR_TYPE, SCXMLConstants.ATTR_TYPEEXPR);
            }
            else {
                send.setTypeexpr(attrValue);
            }
        }

        loop : while (reader.hasNext()) {
            String name, nsURI;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    nsURI = reader.getNamespaceURI();
                    name = reader.getLocalName();
                    if (SCXMLConstants.XMLNS_SCXML.equals(nsURI)) {
                        if (SCXMLConstants.ELEM_PARAM.equals(name)) {
                            if (send.getContent() == null) {
                                readParam(reader, configuration, send);
                            }
                            else {
                                reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_SEND, nsURI, name);
                            }
                        } else if (SCXMLConstants.ELEM_CONTENT.equals(name)) {
                            if (send.getNamelist() == null && send.getParams().isEmpty()) {
                                readContent(reader, configuration, send);
                            }
                            else {
                                reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_SEND, nsURI, name);
                            }
                        } else {
                            reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_SEND, nsURI, name);
                        }
                    } else {
                        reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_SEND, nsURI, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default:
            }
        }

        send.setParent(executable);
        if (parent != null) {
            parent.addAction(send);
        } else {
            executable.addAction(send);
        }
    }

    /**
     * Read the contents of this &lt;cancel&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readCancel(final XMLStreamReader reader, final Configuration configuration,
                                   final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        Cancel cancel = new Cancel();
        cancel.setSendid(readAV(reader, SCXMLConstants.ATTR_SENDID));
        String attrValue = readAV(reader, SCXMLConstants.ATTR_SENDIDEXPR);
        if (attrValue != null) {
            if (cancel.getSendid() != null) {
                reportConflictingAttribute(reader, configuration, SCXMLConstants.ELEM_CANCEL, SCXMLConstants.ATTR_SENDID, SCXMLConstants.ATTR_SENDIDEXPR);
            }
            else {
                cancel.setSendidexpr(attrValue);
            }
        }
        cancel.setParent(executable);
        if (parent != null) {
            parent.addAction(cancel);
        } else {
            executable.addAction(cancel);
        }
        skipToEndElement(reader);
    }

    /**
     * Read the contents of this &lt;script&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param executable The parent {@link Executable} for this action.
     * @param parent The optional parent {@link ActionsContainer} if this action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readScript(final XMLStreamReader reader, final Configuration configuration,
                                   final Executable executable, final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        Script script = readScript(reader, configuration);
        script.setParent(executable);
        if (parent != null) {
            parent.addAction(script);
        } else {
            executable.addAction(script);
        }
    }

    /**
     * Read the contents of the initial &lt;script&gt; element.
     * @see <a href="https://www.w3.org/TR/2015/REC-scxml-20150901/#scxml">
     *     https://www.w3.org/TR/2015/REC-scxml-20150901/#scxml<a> section 3.2.2
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param scxml The root of the object model being parsed.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readGlobalScript(final XMLStreamReader reader, final Configuration configuration,
                                         final SCXML scxml)
            throws XMLStreamException, ModelException {

        Script globalScript = readScript(reader, configuration);
        globalScript.setGlobalScript(true);
        scxml.setGlobalScript(globalScript);
    }

    /**
     * Read the contents of this &lt;script&gt; element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static Script readScript(final XMLStreamReader reader, final Configuration configuration)
            throws XMLStreamException, ModelException {

        Script script = new Script();
        script.setSrc(readAV(reader, SCXMLConstants.ATTR_SRC));
        if (script.getSrc() != null) {
            String resolvedSrc = script.getSrc();
            if (configuration.pathResolver != null) {
                resolvedSrc = configuration.pathResolver.resolvePath(resolvedSrc);
            }
            try (InputStream in = new URL(resolvedSrc).openStream()){
                script.setScript(IOUtils.toString(in, "UTF-8"));
            }
            catch (IOException e) {
                throw new ModelException(e);
            }
            skipToEndElement(reader);
        }
        else {
            script.setScript(readBody(reader));
        }
        return script;
    }

    /**
     * Read the contents of this custom action.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param customAction The {@link CustomAction} to read.
     * @param executable The parent {@link Executable} for this custom action.
     * @param parent The optional parent {@link ActionsContainer} if this custom action is a child of one.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readCustomAction(final XMLStreamReader reader, final Configuration configuration,
                                         final CustomAction customAction, final Executable executable,
                                         final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        // Instantiate custom action
        Object actionObject;
        String className = customAction.getActionClass().getName();
        ClassLoader cl = configuration.customActionClassLoader;
        if (configuration.useContextClassLoaderForCustomActions) {
            cl = Thread.currentThread().getContextClassLoader();
        }
        if (cl == null) {
            cl = SCXMLReader.class.getClassLoader();
        }
        Class<?> clazz;
        try {
            clazz = cl.loadClass(className);
            actionObject = clazz.newInstance();
        } catch (ClassNotFoundException cnfe) {
            throw new XMLStreamException("Cannot find custom action class:" + className, cnfe);
        } catch (IllegalAccessException iae) {
            throw new XMLStreamException("Cannot access custom action class:" + className, iae);
        } catch (InstantiationException ie) {
            throw new XMLStreamException("Cannot instantiate custom action class:" + className, ie);
        }
        if (!(actionObject instanceof Action)) {
            throw new IllegalArgumentException(ERR_CUSTOM_ACTION_TYPE + className);
        }

        // Set the attribute values as properties
        Action action = (Action) actionObject;

        CustomActionWrapper actionWrapper = new CustomActionWrapper();
        actionWrapper.setAction(action);
        actionWrapper.setPrefix(reader.getPrefix());
        actionWrapper.setLocalName(reader.getLocalName());
        Map<String, String> namespaces = readNamespaces(reader);
        if (namespaces != null) {
            actionWrapper.getNamespaces().putAll(namespaces);
        }

        Map<String, String> attributes = new HashMap<>();
        for (int i = 0; i < reader.getAttributeCount(); i++) {
            String name = reader.getAttributeLocalName(i);
            String qname = createQualifiedName(reader.getAttributePrefix(i), name);
            String value = reader.getAttributeValue(i);
            attributes.put(qname, value);
            String setter = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
            Method method;
            try {
                method = clazz.getMethod(setter, String.class);
                method.invoke(action, value);
            } catch (NoSuchMethodException nsme) {
                logger.warn("No method: " + setter + "(String) found in custom action class: " + className+ " for "
                        + qname + "=\"" + value + "\". Attribute ignored");
            } catch (InvocationTargetException ite) {
                throw new XMLStreamException("Exception calling method:" + setter + "(String) in custom action class:"
                        + className, ite);
            } catch (IllegalAccessException iae) {
                throw new XMLStreamException("Cannot access method: " + setter +"(String) in custom action class: "
                        + className, iae);
            }
        }
        if (!attributes.isEmpty()) {
            actionWrapper.setAttributes(attributes);
        }

        // Add any body content if necessary
        if (action instanceof ParsedValueContainer) {
            readParsedValue(reader, configuration, (ParsedValueContainer)action, false);
        }
        else {
            skipToEndElement(reader);
        }

        // Wire in the action and add to parent
        actionWrapper.setParent(executable);
        if (parent != null) {
            parent.addAction(actionWrapper);
        } else {
            executable.addAction(actionWrapper);
        }
    }

    /**
     * Read and parse the body of a {@link ParsedValueContainer} element.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param valueContainer The {@link ParsedValueContainer} element which body to read
     * @param invokeContent flag indicating if the valueContainer is a <invoke><content> element, which get special
     *                      treatment
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static void readParsedValue(final XMLStreamReader reader, final Configuration configuration,
                                        final ParsedValueContainer valueContainer, final boolean invokeContent)
            throws XMLStreamException, ModelException {
        Element element = readElement(reader);
        if (element.hasChildNodes()) {
            NodeList children = element.getChildNodes();
            Node child = children.item(0);
            boolean cdata = child.getNodeType() == Node.CDATA_SECTION_NODE;
            if (invokeContent) {
                // search or and only use first <scxml> element
                if (child.getNodeType() != Node.ELEMENT_NODE) {
                    for (int i = 1, size = children.getLength(); i < size; i++) {
                        child = children.item(i);
                        if (child.getNodeType() == Node.ELEMENT_NODE) {
                            break;
                        }
                    }
                }
                if (child.getNodeType() == Node.ELEMENT_NODE) {
                    if (SCXMLConstants.ELEM_SCXML.equals(child.getLocalName()) &&
                            SCXMLConstants.XMLNS_SCXML.equals(child.getNamespaceURI())) {
                        // transform <invoke><content><scxml> back to text
                        try {
                            valueContainer.setParsedValue(new NodeTextValue(ContentParser.DEFAULT_PARSER.toXml(child)));
                        } catch (IOException e) {
                            throw new XMLStreamException(e);
                        }
                    }
                }
                if (valueContainer.getParsedValue() == null) {
                    reportIgnoredElement(reader, configuration, SCXMLConstants.ELEM_INVOKE, SCXMLConstants.XMLNS_SCXML,
                            SCXMLConstants.ELEM_CONTENT);
                }
            }
            else if (children.getLength() == 1 && (cdata || child.getNodeType() == Node.TEXT_NODE )) {
                String text = ContentParser.trimContent(child.getNodeValue());
                if (ContentParser.hasJsonSignature(text)) {
                    try {
                        valueContainer.setParsedValue(new JsonValue(configuration.contentParser.parseJson(text), cdata));
                    } catch (IOException e) {
                        throw new ModelException(e);
                    }
                }
                else {
                    valueContainer.setParsedValue(new TextValue(ContentParser.spaceNormalizeContent(text),
                            cdata));
                }
            } else if (children.getLength() == 1) {
                valueContainer.setParsedValue(new NodeValue(child));
            } else {
                ArrayList<Node> nodeList = new ArrayList<>();
                for (int i = 0, size = children.getLength(); i < size; i++) {
                    nodeList.add(children.item(i));
                }
                valueContainer.setParsedValue(new NodeListValue(nodeList));
            }
        }
    }

    /**
     * Read the current element into a DOM {@link Element}.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     *
     * @return The parsed content as a DOM {@link Element}.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static Element readElement(final XMLStreamReader reader)
            throws XMLStreamException {

        // Create a document in which to build the DOM node
        Document document;
        try {
            document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        } catch (ParserConfigurationException pce) {
            throw new XMLStreamException(ERR_PARSER_CFG);
        }

        // This root element will be returned, add any attributes as specified
        Element root = document.createElementNS(reader.getNamespaceURI(), createQualifiedName(reader.getPrefix(), reader.getLocalName()));
        document.appendChild(root);

        boolean children = false, cdata = false;
        Node parent = root;

        // Convert stream to DOM node(s) while maintaining parent child relationships
        loop : while (reader.hasNext()) {
            Node child = null;
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    if (!children && root.hasChildNodes()) {
                        // remove any children
                        root.setTextContent(null);
                    }
                    children = true;
                    Element elem = document.createElementNS(reader.getNamespaceURI(),
                            createQualifiedName(reader.getPrefix(), reader.getLocalName()));
                    for (int i = 0; i < reader.getAttributeCount(); i++) {
                        Attr attr = document.createAttributeNS(reader.getAttributeNamespace(i),
                                createQualifiedName(reader.getAttributePrefix(i), reader.getAttributeLocalName(i)));
                        attr.setValue(reader.getAttributeValue(i));
                        elem.setAttributeNodeNS(attr);
                    }
                    parent.appendChild(elem);
                    parent = elem;
                    break;
                case XMLStreamConstants.SPACE:
                case XMLStreamConstants.CHARACTERS:
                case XMLStreamConstants.ENTITY_REFERENCE:
                    if (!children || parent != root) {
                        child = document.createTextNode(reader.getText());
                    }
                    break;
                case XMLStreamConstants.CDATA:
                    if (!children || parent != root) {
                        cdata = true;
                        child = document.createCDATASection(reader.getText());
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    parent = parent.getParentNode();
                    if (parent == document) {
                        break loop;
                    }
                    break;
                default: // rest is ignored
            }
            if (child != null) {
                parent.appendChild(child);
            }
        }
        if (!children && root.hasChildNodes() && root.getChildNodes().getLength() > 1) {
            String text = root.getTextContent().trim();
            if (!cdata) {
                root.setTextContent(text);
            } else {
                root.setTextContent(null);
                root.appendChild(document.createCDATASection(text));
            }
        }
        return root;
    }

    /**
     * Read the following body contents into a String.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     *
     * @return The body content read into a String.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     */
    private static String readBody(final XMLStreamReader reader)
            throws XMLStreamException {

        StringBuilder body = new StringBuilder();

        // Add all body content to StringBuilder
        loop : while (reader.hasNext()) {
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    logger.warn("Ignoring XML content in <script> element, encountered element: "
                            + createQualifiedName(reader.getPrefix(), reader.getLocalName()));
                    skipToEndElement(reader);
                    break;
                case XMLStreamConstants.SPACE:
                case XMLStreamConstants.CHARACTERS:
                case XMLStreamConstants.ENTITY_REFERENCE:
                case XMLStreamConstants.CDATA:
                    body.append(reader.getText());
                    break;
                case XMLStreamConstants.COMMENT:
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break loop;
                default: // rest is ignored
            }
        }
        return body.toString();
    }

    /**
     * @param prefix prefix
     * @param localName localName
     * @return a qualified name from a prefix and localName
     */
    private static String createQualifiedName(final String prefix, final String localName) {
        return (prefix != null && prefix.length() > 0 ? prefix + ":" : "") +localName;
    }

    /**
     * @param input input string to check if null or empty after trim
     * @return null if input is null or empty after trim()
     */
    private static String nullIfEmpty(String input) {
        return input == null || input.trim().length()==0 ? null : input.trim();
    }

    /**
     * Get the attribute value at the current reader location.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param attrLocalName The attribute name whose value is needed.
     *
     * @return The value of the attribute.
     */
    private static String readAV(final XMLStreamReader reader, final String attrLocalName) {
        return nullIfEmpty(reader.getAttributeValue(XMLNS_DEFAULT, attrLocalName));
    }

    /**
     * Get the Boolean attribute value at the current reader location.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param elementName The name of the element for which the attribute value is needed.
     * @param attrLocalName The attribute name whose value is needed.
     *
     * @return The Boolean value of the attribute.
     * @throws ModelException When the attribute value is not empty but neither "true" or "false".
     */
    private static Boolean readBooleanAV(final XMLStreamReader reader, final String elementName,
                                         final String attrLocalName)
            throws ModelException {
        String value = nullIfEmpty(reader.getAttributeValue(XMLNS_DEFAULT, attrLocalName));
        Boolean result = "true".equals(value) ? Boolean.TRUE : "false".equals(value) ? Boolean.FALSE : null;
        if (result == null && value != null) {
            MessageFormat msgFormat = new MessageFormat(ERR_ATTRIBUTE_NOT_BOOLEAN);
            String errMsg = msgFormat.format(new Object[] {value, attrLocalName, elementName, reader.getLocation()});
            throw new ModelException(errMsg);
        }
        return result;
    }

    /**
     * Get a required attribute value at the current reader location,
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param elementName The name of the element for which the attribute value is needed.
     * @param attrLocalName The attribute name whose value is needed.
     *
     * @return The value of the attribute.
     * @throws ModelException When the required attribute is missing or empty.
     */
    private static String readRequiredAV(final XMLStreamReader reader, final String elementName, final String attrLocalName)
            throws ModelException {
        String value = nullIfEmpty(reader.getAttributeValue(XMLNS_DEFAULT, attrLocalName));
        if (value == null) {
            reportMissingAttribute(reader.getLocation(), elementName, attrLocalName);
        }
        return value;
    }

    private static String readOrGeneratedTransitionTargetId(final XMLStreamReader reader, final SCXML scxml,
                                                            final String elementName)
            throws ModelException {
        String id = readAV(reader, SCXMLConstants.ATTR_ID);
        if (id == null) {
            id = scxml.generateTransitionTargetId();
        }
        else if (id.startsWith(SCXML.GENERATED_TT_ID_PREFIX)) {
            MessageFormat msgFormat = new MessageFormat(ERR_RESERVED_ID_PREFIX);
            String errMsg = msgFormat.format(new Object[] {elementName, id, reader.getLocation()});
            throw new ModelException(errMsg);
        }
        return id;
    }

    /**
     * Read the current active namespace declarations.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @return the map of active namespace declarations, null if none defined
     */
    private static Map<String, String> readNamespaces(final XMLStreamReader reader) {
        Map<String, String> namespaces = null;
        if (reader.getNamespaceCount() > 0) {
            namespaces = new LinkedHashMap<>();
            for (int i = 0; i < reader.getNamespaceCount(); i++) {
                namespaces.put(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
            }
        }
        return namespaces;
    }

    /**
     * Report a missing required attribute value at the current reader location,
     *
     * @param location The (approximate) {@link Location} where the attribute is expected.
     * @param elementName The name of the element for which the attribute value is needed.
     * @param attrLocalName The attribute name whose value is needed.
     *
     * @throws ModelException The required attribute is missing or empty.
     */
    private static void reportMissingAttribute(final Location location, final String elementName, final String attrLocalName)
            throws ModelException {
        MessageFormat msgFormat = new MessageFormat(ERR_REQUIRED_ATTRIBUTE_MISSING);
        String errMsg = msgFormat.format(new Object[] {elementName, attrLocalName, location});
        throw new ModelException(errMsg);
    }

    /**
     * Report an ignored element via the {@link XMLReporter} if available and the class
     * {@link org.apache.commons.logging.Log}.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param parent The parent element local name in the SCXML namespace.
     * @param nsURI The namespace URI of the ignored element.
     * @param name The local name of the ignored element.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void reportIgnoredElement(final XMLStreamReader reader, final Configuration configuration,
                                             final String parent, final String nsURI, final String name)
            throws XMLStreamException, ModelException {

        StringBuilder sb = new StringBuilder();
        sb.append("Ignoring unknown or invalid element <").append(name)
                .append("> in namespace \"").append(nsURI)
                .append("\" as child of <").append(parent)
                .append("> at ").append(reader.getLocation());
        if (!configuration.isSilent() && logger.isWarnEnabled()) {
            logger.warn(sb.toString());
        }
        if (configuration.isStrict()) {
            throw new ModelException(sb.toString());
        }
        XMLReporter reporter = configuration.reporter;
        if (reporter != null) {
            reporter.report(sb.toString(), "COMMONS_SCXML", null, reader.getLocation());
        }
        skipToEndElement(reader);
    }

    /**
     * Advances the XMLStreamReader until after the end of the current element: all children will be skipped as well
     * @param reader the reader
     * @throws XMLStreamException
     */
    private static void skipToEndElement(final XMLStreamReader reader) throws XMLStreamException {
        int elementsToSkip = 1;
        while (elementsToSkip > 0 && reader.hasNext()) {
            int next = reader.next();
            if (next == XMLStreamConstants.START_ELEMENT) {
                elementsToSkip++;
            }
            else if (next == XMLStreamConstants.END_ELEMENT) {
                elementsToSkip--;
            }
        }
    }

    /**
     * Report an ignored attribute via the {@link XMLReporter} if available and
     * {@link org.apache.commons.logging.Log}.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param element The element name.
     * @param attr The attribute which is ignored.
     * @param value The value of the attribute which is ignored.
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void reportIgnoredAttribute(final XMLStreamReader reader, final Configuration configuration,
                                               final String element, final String attr, final String value)
            throws XMLStreamException, ModelException {

        StringBuilder sb = new StringBuilder();
        sb.append("Ignoring unknown or invalid <").append(element).append("> attribute ").append(attr)
                .append("=\"").append(value).append("\" at ").append(reader.getLocation());
        if (!configuration.isSilent() && logger.isWarnEnabled()) {
            logger.warn(sb.toString());
        }
        if (configuration.isStrict()) {
            throw new ModelException(sb.toString());
        }
        XMLReporter reporter = configuration.reporter;
        if (reporter != null) {
            reporter.report(sb.toString(), "COMMONS_SCXML", null, reader.getLocation());
        }
    }

    /**
     * Report a conflicting attribute via the {@link XMLReporter} if available and
     * {@link org.apache.commons.logging.Log}.
     *
     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
     * @param configuration The {@link Configuration} to use while parsing.
     * @param element The element name.
     * @param attr The attribute with which a conflict is detected.
     * @param conflictingAttr The conflicting attribute
     *
     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent (includes
     *                        errors in the SCXML document that may not be identified by the schema).
     */
    private static void reportConflictingAttribute(final XMLStreamReader reader, final Configuration configuration,
                                             final String element, final String attr, final String conflictingAttr)
            throws XMLStreamException, ModelException {

        StringBuilder sb = new StringBuilder();
        sb.append("Ignoring <").append(element).append("> attribute \"").append(conflictingAttr)
                .append("\" which conflicts with already defined attribute \"").append(attr)
                .append("\" at ").append(reader.getLocation());
        if (!configuration.isSilent() && logger.isWarnEnabled()) {
            logger.warn(sb.toString());
        }
        if (configuration.isStrict()) {
            throw new ModelException(sb.toString());
        }
        XMLReporter reporter = configuration.reporter;
        if (reporter != null) {
            reporter.report(sb.toString(), "COMMONS_SCXML", null, reader.getLocation());
        }
    }

    /**
     * Use the supplied {@link Configuration} to create an appropriate {@link XMLStreamReader} for this
     * {@link SCXMLReader}. Exactly one of the url, path, stream, reader or source parameters must be provided.
     *
     * @param configuration The {@link Configuration} to be used.
     * @param url The {@link URL} to the SCXML document to read.
     * @param path The optional real path to the SCXML document as a string.
     * @param stream The optional {@link InputStream} providing the SCXML document.
     * @param reader The optional {@link Reader} providing the SCXML document.
     * @param source The optional {@link Source} providing the SCXML document.
     *
     * @return The appropriately configured {@link XMLStreamReader}.
     *
     * @throws IOException Exception with the URL IO.
     * @throws XMLStreamException A problem with the XML stream creation or an wrapped {@link SAXException}
     *                            thrown in trying to validate the document against the XML Schema for SCXML.
     */
    private static XMLStreamReader getReader(final Configuration configuration, final URL url, final String path,
                                             final InputStream stream, final Reader reader, final Source source)
            throws IOException, XMLStreamException {

        // Instantiate the XMLInputFactory
        XMLInputFactory factory = XMLInputFactory.newInstance();
        if (configuration.factoryId != null && configuration.factoryClassLoader != null) {
            factory = XMLInputFactory.newFactory(configuration.factoryId, configuration.factoryClassLoader);
        }
        factory.setEventAllocator(configuration.allocator);
        if (factory.isPropertySupported(XMLInputFactory_JDK_PROP_REPORT_CDATA)) {
            factory.setProperty(XMLInputFactory_JDK_PROP_REPORT_CDATA, Boolean.TRUE);
        }
        for (Map.Entry<String, Object> property : configuration.properties.entrySet()) {
            if (factory.isPropertySupported(property.getKey())) {
                factory.setProperty(property.getKey(), property.getValue());
            }
        }
        factory.setXMLReporter(configuration.reporter);
        factory.setXMLResolver(configuration.resolver);

        // Consolidate InputStream options
        InputStream urlStream = null;
        if (url != null || path != null) {
            URL scxml = (url != null ? url : new URL(path));
            URLConnection conn = scxml.openConnection();
            conn.setUseCaches(false);
            urlStream = conn.getInputStream();
        } else if (stream != null) {
            urlStream = stream;
        }

        // Create the XMLStreamReader
        XMLStreamReader xsr = null;

        if (configuration.validate) {
            // Validation requires us to use a Source

            URL scxmlSchema = new URL("TODO"); // TODO, point to appropriate location
            SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
            Schema schema;
            try {
                schema = schemaFactory.newSchema(scxmlSchema);
            } catch (SAXException se) {
                throw new XMLStreamException("Failed to create SCXML Schema for validation", se);
            }

            Validator validator = schema.newValidator();
            validator.setErrorHandler(new SimpleErrorHandler());

            Source src = null;
            if (urlStream != null) {
                // configuration.encoding is ignored
                if (configuration.systemId != null) {
                    src = new StreamSource(urlStream, configuration.systemId);
                } else {
                    src = new StreamSource(urlStream);
                }
            } else if (reader != null) {
                if (configuration.systemId != null) {
                    src = new StreamSource(reader, configuration.systemId);
                } else {
                    src = new StreamSource(reader);
                }
            } else if (source != null) {
                src = source;
            }
            xsr = factory.createXMLStreamReader(src);
            try {
                validator.validate(src);
            } catch (SAXException se) {
                throw new XMLStreamException("Failed to create apply SCXML Validator", se);
            }

        } else {
            // We can use the more direct XMLInputFactory API if validation isn't needed

            if (urlStream != null) {
                // systemId gets preference, then encoding if either are present
                if (configuration.systemId != null) {
                    xsr = factory.createXMLStreamReader(configuration.systemId, urlStream);
                } else if (configuration.encoding != null) {
                    xsr = factory.createXMLStreamReader(urlStream, configuration.encoding);
                } else {
                    xsr = factory.createXMLStreamReader(urlStream);
                }
            } else if (reader != null) {
                if (configuration.systemId != null) {
                    xsr = factory.createXMLStreamReader(configuration.systemId, reader);
                } else {
                    xsr = factory.createXMLStreamReader(reader);
                }
            } else if (source != null) {
                xsr = factory.createXMLStreamReader(source);
            }

        }

        return xsr;
    }

    /**
     * Discourage instantiation since this is a utility class.
     */
    private SCXMLReader() {
    }

    //------------------------- CONFIGURATION CLASS -------------------------//
    /**
     * <p>
     * Configuration for the {@link SCXMLReader}. The configuration properties necessary for the following are
     * covered:
     * </p>
     *
     * <ul>
     *   <li>{@link XMLInputFactory} configuration properties such as {@link XMLReporter}, {@link XMLResolver} and
     *   {@link XMLEventAllocator}</li>
     *   <li>{@link XMLStreamReader} configuration properties such as <code>systemId</code> and <code>encoding</code>
     *   </li>
     *   <li>Commons SCXML object model configuration properties such as the list of custom actions and the
     *   {@link PathResolver} to use.</li>
     * </ul>
     */
    public static class Configuration {

        /*
         * Configuration properties for this {@link SCXMLReader}.
         */
        // XMLInputFactory configuration properties.
        /**
         * The <code>factoryId</code> to use for the {@link XMLInputFactory}.
         */
        final String factoryId;

        /**
         * The {@link ClassLoader} to use for the {@link XMLInputFactory} instance to create.
         */
        final ClassLoader factoryClassLoader;

        /**
         * The {@link XMLEventAllocator} for the {@link XMLInputFactory}.
         */
        final XMLEventAllocator allocator;

        /**
         * The map of properties (keys are property name strings, values are object property values) for the
         * {@link XMLInputFactory}.
         */
        final Map<String, Object> properties;

        /**
         * The {@link XMLResolver} for the {@link XMLInputFactory}.
         */
        final XMLResolver resolver;

        /**
         * The {@link XMLReporter} for the {@link XMLInputFactory}.
         */
        final XMLReporter reporter;

        // XMLStreamReader configuration properties.
        /**
         * The <code>encoding</code> to use for the {@link XMLStreamReader}.
         */
        final String encoding;

        /**
         * The <code>systemId</code> to use for the {@link XMLStreamReader}.
         */
        final String systemId;

        /**
         * Whether to validate the input with the XML Schema for SCXML.
         */
        final boolean validate;

        // Commons SCXML object model configuration properties.
        /**
         * The list of Commons SCXML custom actions that will be available for this document.
         */
        final List<CustomAction> customActions;

        /**
         * The {@link ClassLoader} to use for loading the {@link CustomAction} instances to create.
         */
        final ClassLoader customActionClassLoader;

        /**
         * Whether to use the thread context {@link ClassLoader} for loading any {@link CustomAction} classes.
         */
        final boolean useContextClassLoaderForCustomActions;

        // Mutable Commons SCXML object model configuration properties.
        /**
         * The parent SCXML document if this document is src'ed in via the &lt;state&gt; or &lt;parallel&gt; element's
         * "src" attribute.
         */
        SCXML parent;

        /**
         * The Commons SCXML {@link PathResolver} to use for this document.
         */
        PathResolver pathResolver;

        /**
         * Whether to silently ignore any unknown or invalid elements
         * or to leave warning logs for those.
         */
        boolean silent;

        /**
         * Whether to strictly throw a model exception when there are any unknown or invalid elements
         * or to leniently allow to read the model even with those.
         */
        boolean strict;

        final ContentParser contentParser;

        /*
         * Public constructors
         */
        /**
         * Default constructor.
         */
        public Configuration() {
            this(null, null);
        }

        /**
         * Minimal convenience constructor.
         *
         * @param reporter The {@link XMLReporter} to use for this reading.
         * @param pathResolver The Commons SCXML {@link PathResolver} to use for this reading.
         */
        public Configuration(final XMLReporter reporter, final PathResolver pathResolver) {
            this(null, null, null, null, null, reporter, null, null, false, pathResolver, null, null, null, false);
        }

        /**
         * Convenience constructor.
         *
         * @param reporter The {@link XMLReporter} to use for this reading.
         * @param pathResolver The Commons SCXML {@link PathResolver} to use for this reading.
         * @param customActions The list of Commons SCXML custom actions that will be available for this document.
         */
        public Configuration(final XMLReporter reporter, final PathResolver pathResolver,
                             final List<CustomAction> customActions) {
            this(null, null, null, null, null, reporter, null, null, false, pathResolver, null, customActions, null,
                    false);
        }

        /**
         * All purpose constructor. Any of the parameters passed in can be <code>null</code> (booleans should default
         * to <code>false</code>).
         *
         * @param factoryId The <code>factoryId</code> to use.
         * @param classLoader The {@link ClassLoader} to use for the {@link XMLInputFactory} instance to create.
         * @param allocator The {@link XMLEventAllocator} for the {@link XMLInputFactory}.
         * @param properties The map of properties (keys are property name strings, values are object property values)
         *                   for the {@link XMLInputFactory}.
         * @param resolver The {@link XMLResolver} for the {@link XMLInputFactory}.
         * @param reporter The {@link XMLReporter} for the {@link XMLInputFactory}.
         * @param encoding The <code>encoding</code> to use for the {@link XMLStreamReader}
         * @param systemId The <code>systemId</code> to use for the {@link XMLStreamReader}
         * @param validate Whether to validate the input with the XML Schema for SCXML.
         * @param pathResolver The Commons SCXML {@link PathResolver} to use for this document.
         * @param customActions The list of Commons SCXML custom actions that will be available for this document.
         * @param customActionClassLoader The {@link ClassLoader} to use for the {@link CustomAction} instances to
         *                                create.
         * @param useContextClassLoaderForCustomActions Whether to use the thread context {@link ClassLoader} for the
         *                                             {@link CustomAction} instances to create.
         */
        public Configuration(final String factoryId, final ClassLoader classLoader, final XMLEventAllocator allocator,
                             final Map<String, Object> properties, final XMLResolver resolver, final XMLReporter reporter,
                             final String encoding, final String systemId, final boolean validate, final PathResolver pathResolver,
                             final List<CustomAction> customActions, final ClassLoader customActionClassLoader,
                             final boolean useContextClassLoaderForCustomActions) {
            this(factoryId, classLoader, allocator, properties, resolver, reporter, encoding, systemId, validate,
                    pathResolver, null, customActions, customActionClassLoader,
                    useContextClassLoaderForCustomActions);
        }

        /*
         * Package access constructors
         */
        /**
         * Convenience package access constructor.
         *
         * @param reporter The {@link XMLReporter} for the {@link XMLInputFactory}.
         * @param pathResolver The Commons SCXML {@link PathResolver} to use for this document.
         * @param parent The parent SCXML document if this document is src'ed in via the &lt;state&gt; or
         *               &lt;parallel&gt; element's "src" attribute.
         */
        Configuration(final XMLReporter reporter, final PathResolver pathResolver, final SCXML parent) {
            this(null, null, null, null, null, reporter, null, null, false, pathResolver, parent, null, null, false);
        }

        /**
         * Package access copy constructor.
         *
         * @param source The source {@link Configuration} to replicate.
         */
        Configuration(final Configuration source) {
            this(source.factoryId, source.factoryClassLoader, source.allocator, source.properties, source.resolver,
                    source.reporter, source.encoding, source.systemId, source.validate, source.pathResolver,
                    source.parent, source.customActions, source.customActionClassLoader,
                    source.useContextClassLoaderForCustomActions, source.silent, source.strict);
        }

        /**
         * All-purpose package access constructor.
         *
         * @param factoryId The <code>factoryId</code> to use.
         * @param factoryClassLoader The {@link ClassLoader} to use for the {@link XMLInputFactory} instance to
         *                           create.
         * @param allocator The {@link XMLEventAllocator} for the {@link XMLInputFactory}.
         * @param properties The map of properties (keys are property name strings, values are object property values)
         *                   for the {@link XMLInputFactory}.
         * @param resolver The {@link XMLResolver} for the {@link XMLInputFactory}.
         * @param reporter The {@link XMLReporter} for the {@link XMLInputFactory}.
         * @param encoding The <code>encoding</code> to use for the {@link XMLStreamReader}
         * @param systemId The <code>systemId</code> to use for the {@link XMLStreamReader}
         * @param validate Whether to validate the input with the XML Schema for SCXML.
         * @param pathResolver The Commons SCXML {@link PathResolver} to use for this document.
         * @param parent The parent SCXML document if this document is src'ed in via the &lt;state&gt; or
         *               &lt;parallel&gt; element's "src" attribute.
         * @param customActions The list of Commons SCXML custom actions that will be available for this document.
         * @param customActionClassLoader The {@link ClassLoader} to use for the {@link CustomAction} instances to
         *                                create.
         * @param useContextClassLoaderForCustomActions Whether to use the thread context {@link ClassLoader} for the
         *                                             {@link CustomAction} instances to create.
         */
        Configuration(final String factoryId, final ClassLoader factoryClassLoader, final XMLEventAllocator allocator,
                      final Map<String, Object> properties, final XMLResolver resolver, final XMLReporter reporter,
                      final String encoding, final String systemId, final boolean validate, final PathResolver pathResolver,
                      final SCXML parent, final List<CustomAction> customActions, final ClassLoader customActionClassLoader,
                      final boolean useContextClassLoaderForCustomActions) {
            this(factoryId, factoryClassLoader, allocator, properties, resolver, reporter, encoding, systemId,
                    validate, pathResolver, parent, customActions, customActionClassLoader,
                    useContextClassLoaderForCustomActions, false, false);
        }

        /**
         * All-purpose package access constructor.
         *
         * @param factoryId The <code>factoryId</code> to use.
         * @param factoryClassLoader The {@link ClassLoader} to use for the {@link XMLInputFactory} instance to
         *                           create.
         * @param allocator The {@link XMLEventAllocator} for the {@link XMLInputFactory}.
         * @param properties The map of properties (keys are property name strings, values are object property values)
         *                   for the {@link XMLInputFactory}.
         * @param resolver The {@link XMLResolver} for the {@link XMLInputFactory}.
         * @param reporter The {@link XMLReporter} for the {@link XMLInputFactory}.
         * @param encoding The <code>encoding</code> to use for the {@link XMLStreamReader}
         * @param systemId The <code>systemId</code> to use for the {@link XMLStreamReader}
         * @param validate Whether to validate the input with the XML Schema for SCXML.
         * @param pathResolver The Commons SCXML {@link PathResolver} to use for this document.
         * @param parent The parent SCXML document if this document is src'ed in via the &lt;state&gt; or
         *               &lt;parallel&gt; element's "src" attribute.
         * @param customActions The list of Commons SCXML custom actions that will be available for this document.
         * @param customActionClassLoader The {@link ClassLoader} to use for the {@link CustomAction} instances to
         *                                create.
         * @param useContextClassLoaderForCustomActions Whether to use the thread context {@link ClassLoader} for the
         *                                             {@link CustomAction} instances to create.
         * @param silent Whether to silently ignore any unknown or invalid elements or to leave warning logs for those.
         * @param strict Whether to strictly throw a model exception when there are any unknown or invalid elements
         *               or to leniently allow to read the model even with those.
         */
        Configuration(final String factoryId, final ClassLoader factoryClassLoader, final XMLEventAllocator allocator,
                      final Map<String, Object> properties, final XMLResolver resolver, final XMLReporter reporter,
                      final String encoding, final String systemId, final boolean validate, final PathResolver pathResolver,
                      final SCXML parent, final List<CustomAction> customActions, final ClassLoader customActionClassLoader,
                      final boolean useContextClassLoaderForCustomActions, final boolean silent, final boolean strict) {
            this.factoryId = factoryId;
            this.factoryClassLoader = factoryClassLoader;
            this.allocator = allocator;
            this.properties = (properties == null ? new HashMap<>() : properties);
            this.resolver = resolver;
            this.reporter = reporter;
            this.encoding = encoding;
            this.systemId = systemId;
            this.validate = validate;
            this.pathResolver = pathResolver;
            this.parent = parent;
            this.customActions = (customActions == null ? new ArrayList<>() : customActions);
            this.customActionClassLoader = customActionClassLoader;
            this.useContextClassLoaderForCustomActions = useContextClassLoaderForCustomActions;
            this.silent = silent;
            this.strict = strict;
            this.contentParser = new ContentParser();
        }

        /*
         * Package access convenience methods
         */

        /**
         * Returns true if it is set to read models silently without any model error warning logs.
         * @return true if it is set to read models silently without any model error warning logs
         * @see #silent
         */
        public boolean isSilent() {
            return silent;
        }

        /**
         * Turn on/off silent mode (whether to read models silently without any model error warning logs)
         * @param silent silent mode (whether to read models silently without any model error warning logs)
         * @see #silent
         */
        public void setSilent(boolean silent) {
            this.silent = silent;
        }

        /**
         * Returns true if it is set to check model strictly with throwing exceptions on any model error.
         * @return true if it is set to check model strictly with throwing exceptions on any model error
         * @see #strict
         */
        public boolean isStrict() {
            return strict;
        }

        /**
         * Turn on/off strict model (whether to check model strictly with throwing exception on any model error)
         * @param strict strict model (whether to check model strictly with throwing exception on any model error)
         * @see #strict
         */
        public void setStrict(boolean strict) {
            this.strict = strict;
        }
    }
}
