/*
 * 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.openejb.jee;

import org.metatype.sxc.jaxb.JAXBObject;
import org.metatype.sxc.jaxb.RuntimeContext;
import org.metatype.sxc.util.Attribute;
import org.metatype.sxc.util.XoXMLStreamReader;
import org.metatype.sxc.util.XoXMLStreamWriter;

import javax.xml.XMLConstants;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.List;

import static org.apache.openejb.jee.AbsoluteOrdering$JAXB.readAbsoluteOrdering;
import static org.apache.openejb.jee.AbsoluteOrdering$JAXB.writeAbsoluteOrdering;
import static org.apache.openejb.jee.DataSource$JAXB.readDataSource;
import static org.apache.openejb.jee.DataSource$JAXB.writeDataSource;
import static org.apache.openejb.jee.EjbLocalRef$JAXB.readEjbLocalRef;
import static org.apache.openejb.jee.EjbLocalRef$JAXB.writeEjbLocalRef;
import static org.apache.openejb.jee.EjbRef$JAXB.readEjbRef;
import static org.apache.openejb.jee.EjbRef$JAXB.writeEjbRef;
import static org.apache.openejb.jee.Empty$JAXB.readEmpty;
import static org.apache.openejb.jee.Empty$JAXB.writeEmpty;
import static org.apache.openejb.jee.EnvEntry$JAXB.readEnvEntry;
import static org.apache.openejb.jee.EnvEntry$JAXB.writeEnvEntry;
import static org.apache.openejb.jee.ErrorPage$JAXB.readErrorPage;
import static org.apache.openejb.jee.ErrorPage$JAXB.writeErrorPage;
import static org.apache.openejb.jee.Filter$JAXB.readFilter;
import static org.apache.openejb.jee.Filter$JAXB.writeFilter;
import static org.apache.openejb.jee.FilterMapping$JAXB.readFilterMapping;
import static org.apache.openejb.jee.FilterMapping$JAXB.writeFilterMapping;
import static org.apache.openejb.jee.Icon$JAXB.readIcon;
import static org.apache.openejb.jee.Icon$JAXB.writeIcon;
import static org.apache.openejb.jee.JMSConnectionFactory$JAXB.readJMSConnectionFactory;
import static org.apache.openejb.jee.JspConfig$JAXB.readJspConfig;
import static org.apache.openejb.jee.JspConfig$JAXB.writeJspConfig;
import static org.apache.openejb.jee.LifecycleCallback$JAXB.readLifecycleCallback;
import static org.apache.openejb.jee.LifecycleCallback$JAXB.writeLifecycleCallback;
import static org.apache.openejb.jee.Listener$JAXB.readListener;
import static org.apache.openejb.jee.Listener$JAXB.writeListener;
import static org.apache.openejb.jee.LocaleEncodingMappingList$JAXB.readLocaleEncodingMappingList;
import static org.apache.openejb.jee.LocaleEncodingMappingList$JAXB.writeLocaleEncodingMappingList;
import static org.apache.openejb.jee.LoginConfig$JAXB.readLoginConfig;
import static org.apache.openejb.jee.LoginConfig$JAXB.writeLoginConfig;
import static org.apache.openejb.jee.MessageDestination$JAXB.readMessageDestination;
import static org.apache.openejb.jee.MessageDestination$JAXB.writeMessageDestination;
import static org.apache.openejb.jee.MessageDestinationRef$JAXB.readMessageDestinationRef;
import static org.apache.openejb.jee.MessageDestinationRef$JAXB.writeMessageDestinationRef;
import static org.apache.openejb.jee.MimeMapping$JAXB.readMimeMapping;
import static org.apache.openejb.jee.MimeMapping$JAXB.writeMimeMapping;
import static org.apache.openejb.jee.ParamValue$JAXB.readParamValue;
import static org.apache.openejb.jee.ParamValue$JAXB.writeParamValue;
import static org.apache.openejb.jee.PersistenceContextRef$JAXB.readPersistenceContextRef;
import static org.apache.openejb.jee.PersistenceContextRef$JAXB.writePersistenceContextRef;
import static org.apache.openejb.jee.PersistenceUnitRef$JAXB.readPersistenceUnitRef;
import static org.apache.openejb.jee.PersistenceUnitRef$JAXB.writePersistenceUnitRef;
import static org.apache.openejb.jee.ResourceEnvRef$JAXB.readResourceEnvRef;
import static org.apache.openejb.jee.ResourceEnvRef$JAXB.writeResourceEnvRef;
import static org.apache.openejb.jee.ResourceRef$JAXB.readResourceRef;
import static org.apache.openejb.jee.ResourceRef$JAXB.writeResourceRef;
import static org.apache.openejb.jee.SecurityConstraint$JAXB.readSecurityConstraint;
import static org.apache.openejb.jee.SecurityConstraint$JAXB.writeSecurityConstraint;
import static org.apache.openejb.jee.SecurityRole$JAXB.readSecurityRole;
import static org.apache.openejb.jee.SecurityRole$JAXB.writeSecurityRole;
import static org.apache.openejb.jee.ServiceRef$JAXB.readServiceRef;
import static org.apache.openejb.jee.ServiceRef$JAXB.writeServiceRef;
import static org.apache.openejb.jee.Servlet$JAXB.readServlet;
import static org.apache.openejb.jee.Servlet$JAXB.writeServlet;
import static org.apache.openejb.jee.ServletMapping$JAXB.readServletMapping;
import static org.apache.openejb.jee.ServletMapping$JAXB.writeServletMapping;
import static org.apache.openejb.jee.SessionConfig$JAXB.readSessionConfig;
import static org.apache.openejb.jee.SessionConfig$JAXB.writeSessionConfig;
import static org.apache.openejb.jee.Taglib$JAXB.readTaglib;
import static org.apache.openejb.jee.Taglib$JAXB.writeTaglib;
import static org.apache.openejb.jee.Text$JAXB.readText;
import static org.apache.openejb.jee.Text$JAXB.writeText;
import static org.apache.openejb.jee.WelcomeFileList$JAXB.readWelcomeFileList;
import static org.apache.openejb.jee.WelcomeFileList$JAXB.writeWelcomeFileList;

@SuppressWarnings({
    "StringEquality"
})
public class WebApp$JAXB
    extends JAXBObject<WebApp> {


    public WebApp$JAXB() {
        super(WebApp.class, new QName("http://java.sun.com/xml/ns/javaee".intern(), "web-app".intern()), new QName("http://java.sun.com/xml/ns/javaee".intern(), "web-appType".intern()), Text$JAXB.class, Icon$JAXB.class, Empty$JAXB.class, ParamValue$JAXB.class, Filter$JAXB.class, FilterMapping$JAXB.class, Listener$JAXB.class, Servlet$JAXB.class, ServletMapping$JAXB.class, SessionConfig$JAXB.class, MimeMapping$JAXB.class, WelcomeFileList$JAXB.class, ErrorPage$JAXB.class, Taglib$JAXB.class, JspConfig$JAXB.class, SecurityConstraint$JAXB.class, LoginConfig$JAXB.class, SecurityRole$JAXB.class, LocaleEncodingMappingList$JAXB.class, EnvEntry$JAXB.class, EjbRef$JAXB.class, EjbLocalRef$JAXB.class, ServiceRef$JAXB.class, ResourceRef$JAXB.class, ResourceEnvRef$JAXB.class, MessageDestinationRef$JAXB.class, PersistenceContextRef$JAXB.class, PersistenceUnitRef$JAXB.class, LifecycleCallback$JAXB.class, MessageDestination$JAXB.class, AbsoluteOrdering$JAXB.class, DataSource$JAXB.class);
    }

    public static WebApp readWebApp(final XoXMLStreamReader reader, final RuntimeContext context)
        throws Exception {
        return _read(reader, context);
    }

    public static void writeWebApp(final XoXMLStreamWriter writer, final WebApp webApp, final RuntimeContext context)
        throws Exception {
        _write(writer, webApp, context);
    }

    public void write(final XoXMLStreamWriter writer, final WebApp webApp, final RuntimeContext context)
        throws Exception {
        _write(writer, webApp, context);
    }

    public final static WebApp _read(final XoXMLStreamReader reader, RuntimeContext context)
        throws Exception {

        // Check for xsi:nil
        if (reader.isXsiNil()) {
            return null;
        }

        if (context == null) {
            context = new RuntimeContext();
        }

        final WebApp webApp = new WebApp();
        context.beforeUnmarshal(webApp, org.metatype.sxc.jaxb.LifecycleCallback.NONE);

        ArrayList<Text> descriptions = null;
        ArrayList<Text> displayNames = null;
        LocalCollection<Icon> icon = null;
        List<Empty> distributable = null;
        List<ParamValue> contextParam = null;
        List<Filter> filter = null;
        List<FilterMapping> filterMapping = null;
        List<Listener> listener = null;
        List<Servlet> servlet = null;
        List<ServletMapping> servletMapping = null;
        List<SessionConfig> sessionConfig = null;
        List<MimeMapping> mimeMapping = null;
        List<WelcomeFileList> welcomeFileList = null;
        List<ErrorPage> errorPage = null;
        List<JspConfig> jspConfig = null;
        List<SecurityConstraint> securityConstraint = null;
        List<LoginConfig> loginConfig = null;
        List<SecurityRole> securityRole = null;
        List<LocaleEncodingMappingList> localeEncodingMappingList = null;
        KeyedCollection<String, EnvEntry> envEntry = null;
        KeyedCollection<String, EjbRef> ejbRef = null;
        KeyedCollection<String, EjbLocalRef> ejbLocalRef = null;
        KeyedCollection<String, ServiceRef> serviceRef = null;
        KeyedCollection<String, ResourceRef> resourceRef = null;
        KeyedCollection<String, ResourceEnvRef> resourceEnvRef = null;
        KeyedCollection<String, MessageDestinationRef> messageDestinationRef = null;
        KeyedCollection<String, PersistenceContextRef> persistenceContextRef = null;
        KeyedCollection<String, PersistenceUnitRef> persistenceUnitRef = null;
        List<org.apache.openejb.jee.LifecycleCallback> postConstruct = null;
        List<org.apache.openejb.jee.LifecycleCallback> preDestroy = null;
        List<MessageDestination> messageDestination = null;
        KeyedCollection<String, DataSource> dataSource = null;
        KeyedCollection<String, JMSConnectionFactory> jmsConnectionFactories = null;

        // Check xsi:type
        final QName xsiType = reader.getXsiType();
        if (xsiType != null) {
            if (("web-appType" != xsiType.getLocalPart()) || ("http://java.sun.com/xml/ns/javaee" != xsiType.getNamespaceURI())) {
                return context.unexpectedXsiType(reader, WebApp.class);
            }
        }

        // Read attributes
        for (final Attribute attribute : reader.getAttributes()) {
            if (("id" == attribute.getLocalName()) && (("" == attribute.getNamespace()) || (attribute.getNamespace() == null))) {
                // ATTRIBUTE: id
                final String id = Adapters.collapsedStringAdapterAdapter.unmarshal(attribute.getValue());
                context.addXmlId(reader, id, webApp);
                webApp.id = id;
            } else if (("metadata-complete" == attribute.getLocalName()) && (("" == attribute.getNamespace()) || (attribute.getNamespace() == null))) {
                // ATTRIBUTE: metadataComplete
                final Boolean metadataComplete = ("1".equals(attribute.getValue()) || "true".equals(attribute.getValue()));
                webApp.metadataComplete = metadataComplete;
            } else if (("version" == attribute.getLocalName()) && (("" == attribute.getNamespace()) || (attribute.getNamespace() == null))) {
                // ATTRIBUTE: version
                webApp.version = Adapters.collapsedStringAdapterAdapter.unmarshal(attribute.getValue());
            } else if (XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI != attribute.getNamespace()) {
                context.unexpectedAttribute(attribute, new QName("", "id"), new QName("", "metadata-complete"), new QName("", "version"));
            }
        }

        // Read elements
        for (final XoXMLStreamReader elementReader : reader.getChildElements()) {
            if (("description" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: descriptions
                final Text descriptionsItem = readText(elementReader, context);
                if (descriptions == null) {
                    descriptions = new ArrayList<Text>();
                }
                descriptions.add(descriptionsItem);
            } else if (("display-name" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: displayNames
                final Text displayNamesItem = readText(elementReader, context);
                if (displayNames == null) {
                    displayNames = new ArrayList<Text>();
                }
                displayNames.add(displayNamesItem);
            } else if (("icon" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: icon
                final Icon iconItem = readIcon(elementReader, context);
                if (icon == null) {
                    icon = webApp.icon;
                    if (icon != null) {
                        icon.clear();
                    } else {
                        icon = new LocalCollection<Icon>();
                    }
                }
                icon.add(iconItem);
            } else if (("distributable" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: distributable
                final Empty distributableItem = readEmpty(elementReader, context);
                if (distributable == null) {
                    distributable = webApp.distributable;
                    if (distributable != null) {
                        distributable.clear();
                    } else {
                        distributable = new ArrayList<Empty>();
                    }
                }
                distributable.add(distributableItem);
            } else if (("context-param" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: contextParam
                final ParamValue contextParamItem = readParamValue(elementReader, context);
                if (contextParam == null) {
                    contextParam = webApp.contextParam;
                    if (contextParam != null) {
                        contextParam.clear();
                    } else {
                        contextParam = new ArrayList<ParamValue>();
                    }
                }
                contextParam.add(contextParamItem);
            } else if (("filter" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: filter
                final Filter filterItem = readFilter(elementReader, context);
                if (filter == null) {
                    filter = webApp.filter;
                    if (filter != null) {
                        filter.clear();
                    } else {
                        filter = new ArrayList<Filter>();
                    }
                }
                filter.add(filterItem);
            } else if (("filter-mapping" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: filterMapping
                final FilterMapping filterMappingItem = readFilterMapping(elementReader, context);
                if (filterMapping == null) {
                    filterMapping = webApp.filterMapping;
                    if (filterMapping != null) {
                        filterMapping.clear();
                    } else {
                        filterMapping = new ArrayList<FilterMapping>();
                    }
                }
                filterMapping.add(filterMappingItem);
            } else if (("listener" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: listener
                final Listener listenerItem = readListener(elementReader, context);
                if (listener == null) {
                    listener = webApp.listener;
                    if (listener != null) {
                        listener.clear();
                    } else {
                        listener = new ArrayList<Listener>();
                    }
                }
                listener.add(listenerItem);
            } else if (("servlet" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: servlet
                final Servlet servletItem = readServlet(elementReader, context);
                if (servlet == null) {
                    servlet = webApp.servlet;
                    if (servlet != null) {
                        servlet.clear();
                    } else {
                        servlet = new ArrayList<Servlet>();
                    }
                }
                servlet.add(servletItem);
            } else if (("servlet-mapping" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: servletMapping
                final ServletMapping servletMappingItem = readServletMapping(elementReader, context);
                if (servletMapping == null) {
                    servletMapping = webApp.servletMapping;
                    if (servletMapping != null) {
                        servletMapping.clear();
                    } else {
                        servletMapping = new ArrayList<ServletMapping>();
                    }
                }
                servletMapping.add(servletMappingItem);
            } else if (("session-config" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: sessionConfig
                final SessionConfig sessionConfigItem = readSessionConfig(elementReader, context);
                if (sessionConfig == null) {
                    sessionConfig = webApp.sessionConfig;
                    if (sessionConfig != null) {
                        sessionConfig.clear();
                    } else {
                        sessionConfig = new ArrayList<SessionConfig>();
                    }
                }
                sessionConfig.add(sessionConfigItem);
            } else if (("mime-mapping" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: mimeMapping
                final MimeMapping mimeMappingItem = readMimeMapping(elementReader, context);
                if (mimeMapping == null) {
                    mimeMapping = webApp.mimeMapping;
                    if (mimeMapping != null) {
                        mimeMapping.clear();
                    } else {
                        mimeMapping = new ArrayList<MimeMapping>();
                    }
                }
                mimeMapping.add(mimeMappingItem);
            } else if (("welcome-file-list" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: welcomeFileList
                final WelcomeFileList welcomeFileListItem = readWelcomeFileList(elementReader, context);
                if (welcomeFileList == null) {
                    welcomeFileList = webApp.welcomeFileList;
                    if (welcomeFileList != null) {
                        welcomeFileList.clear();
                    } else {
                        welcomeFileList = new ArrayList<WelcomeFileList>();
                    }
                }
                welcomeFileList.add(welcomeFileListItem);
            } else if (("error-page" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: errorPage
                final ErrorPage errorPageItem = readErrorPage(elementReader, context);
                if (errorPage == null) {
                    errorPage = webApp.errorPage;
                    if (errorPage != null) {
                        errorPage.clear();
                    } else {
                        errorPage = new ArrayList<ErrorPage>();
                    }
                }
                errorPage.add(errorPageItem);
            } else if (("taglib" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: taglib
                final Taglib taglib = readTaglib(elementReader, context);
                try {
                    webApp.setTaglib(taglib);
                } catch (final Exception e) {
                    context.setterError(reader, WebApp.class, "setTaglib", Taglib.class, e);
                }
            } else if (("jsp-config" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: jspConfig
                final JspConfig jspConfigItem = readJspConfig(elementReader, context);
                if (jspConfig == null) {
                    jspConfig = webApp.jspConfig;
                    if (jspConfig != null) {
                        jspConfig.clear();
                    } else {
                        jspConfig = new ArrayList<JspConfig>();
                    }
                }
                jspConfig.add(jspConfigItem);
            } else if (("security-constraint" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: securityConstraint
                final SecurityConstraint securityConstraintItem = readSecurityConstraint(elementReader, context);
                if (securityConstraint == null) {
                    securityConstraint = webApp.securityConstraint;
                    if (securityConstraint != null) {
                        securityConstraint.clear();
                    } else {
                        securityConstraint = new ArrayList<SecurityConstraint>();
                    }
                }
                securityConstraint.add(securityConstraintItem);
            } else if (("login-config" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: loginConfig
                final LoginConfig loginConfigItem = readLoginConfig(elementReader, context);
                if (loginConfig == null) {
                    loginConfig = webApp.loginConfig;
                    if (loginConfig != null) {
                        loginConfig.clear();
                    } else {
                        loginConfig = new ArrayList<LoginConfig>();
                    }
                }
                loginConfig.add(loginConfigItem);
            } else if (("security-role" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: securityRole
                final SecurityRole securityRoleItem = readSecurityRole(elementReader, context);
                if (securityRole == null) {
                    securityRole = webApp.securityRole;
                    if (securityRole != null) {
                        securityRole.clear();
                    } else {
                        securityRole = new ArrayList<SecurityRole>();
                    }
                }
                securityRole.add(securityRoleItem);
            } else if (("locale-encoding-mapping-list" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: localeEncodingMappingList
                final LocaleEncodingMappingList localeEncodingMappingListItem = readLocaleEncodingMappingList(elementReader, context);
                if (localeEncodingMappingList == null) {
                    localeEncodingMappingList = webApp.localeEncodingMappingList;
                    if (localeEncodingMappingList != null) {
                        localeEncodingMappingList.clear();
                    } else {
                        localeEncodingMappingList = new ArrayList<LocaleEncodingMappingList>();
                    }
                }
                localeEncodingMappingList.add(localeEncodingMappingListItem);
            } else if (("env-entry" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: envEntry
                final EnvEntry envEntryItem = readEnvEntry(elementReader, context);
                if (envEntry == null) {
                    envEntry = webApp.envEntry;
                    if (envEntry != null) {
                        envEntry.clear();
                    } else {
                        envEntry = new KeyedCollection<String, EnvEntry>();
                    }
                }
                envEntry.add(envEntryItem);
            } else if (("ejb-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: ejbRef
                final EjbRef ejbRefItem = readEjbRef(elementReader, context);
                if (ejbRef == null) {
                    ejbRef = webApp.ejbRef;
                    if (ejbRef != null) {
                        ejbRef.clear();
                    } else {
                        ejbRef = new KeyedCollection<String, EjbRef>();
                    }
                }
                ejbRef.add(ejbRefItem);
            } else if (("ejb-local-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: ejbLocalRef
                final EjbLocalRef ejbLocalRefItem = readEjbLocalRef(elementReader, context);
                if (ejbLocalRef == null) {
                    ejbLocalRef = webApp.ejbLocalRef;
                    if (ejbLocalRef != null) {
                        ejbLocalRef.clear();
                    } else {
                        ejbLocalRef = new KeyedCollection<String, EjbLocalRef>();
                    }
                }
                ejbLocalRef.add(ejbLocalRefItem);
            } else if (("service-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: serviceRef
                final ServiceRef serviceRefItem = readServiceRef(elementReader, context);
                if (serviceRef == null) {
                    serviceRef = webApp.serviceRef;
                    if (serviceRef != null) {
                        serviceRef.clear();
                    } else {
                        serviceRef = new KeyedCollection<String, ServiceRef>();
                    }
                }
                serviceRef.add(serviceRefItem);
            } else if (("resource-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: resourceRef
                final ResourceRef resourceRefItem = readResourceRef(elementReader, context);
                if (resourceRef == null) {
                    resourceRef = webApp.resourceRef;
                    if (resourceRef != null) {
                        resourceRef.clear();
                    } else {
                        resourceRef = new KeyedCollection<String, ResourceRef>();
                    }
                }
                resourceRef.add(resourceRefItem);
            } else if (("resource-env-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: resourceEnvRef
                final ResourceEnvRef resourceEnvRefItem = readResourceEnvRef(elementReader, context);
                if (resourceEnvRef == null) {
                    resourceEnvRef = webApp.resourceEnvRef;
                    if (resourceEnvRef != null) {
                        resourceEnvRef.clear();
                    } else {
                        resourceEnvRef = new KeyedCollection<String, ResourceEnvRef>();
                    }
                }
                resourceEnvRef.add(resourceEnvRefItem);
            } else if (("message-destination-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: messageDestinationRef
                final MessageDestinationRef messageDestinationRefItem = readMessageDestinationRef(elementReader, context);
                if (messageDestinationRef == null) {
                    messageDestinationRef = webApp.messageDestinationRef;
                    if (messageDestinationRef != null) {
                        messageDestinationRef.clear();
                    } else {
                        messageDestinationRef = new KeyedCollection<String, MessageDestinationRef>();
                    }
                }
                messageDestinationRef.add(messageDestinationRefItem);
            } else if (("persistence-context-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: persistenceContextRef
                final PersistenceContextRef persistenceContextRefItem = readPersistenceContextRef(elementReader, context);
                if (persistenceContextRef == null) {
                    persistenceContextRef = webApp.persistenceContextRef;
                    if (persistenceContextRef != null) {
                        persistenceContextRef.clear();
                    } else {
                        persistenceContextRef = new KeyedCollection<String, PersistenceContextRef>();
                    }
                }
                persistenceContextRef.add(persistenceContextRefItem);
            } else if (("persistence-unit-ref" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: persistenceUnitRef
                final PersistenceUnitRef persistenceUnitRefItem = readPersistenceUnitRef(elementReader, context);
                if (persistenceUnitRef == null) {
                    persistenceUnitRef = webApp.persistenceUnitRef;
                    if (persistenceUnitRef != null) {
                        persistenceUnitRef.clear();
                    } else {
                        persistenceUnitRef = new KeyedCollection<String, PersistenceUnitRef>();
                    }
                }
                persistenceUnitRef.add(persistenceUnitRefItem);
            } else if (("post-construct" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: postConstruct
                final org.apache.openejb.jee.LifecycleCallback postConstructItem = readLifecycleCallback(elementReader, context);
                if (postConstruct == null) {
                    postConstruct = webApp.postConstruct;
                    if (postConstruct != null) {
                        postConstruct.clear();
                    } else {
                        postConstruct = new ArrayList<org.apache.openejb.jee.LifecycleCallback>();
                    }
                }
                postConstruct.add(postConstructItem);
            } else if (("pre-destroy" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: preDestroy
                final org.apache.openejb.jee.LifecycleCallback preDestroyItem = readLifecycleCallback(elementReader, context);
                if (preDestroy == null) {
                    preDestroy = webApp.preDestroy;
                    if (preDestroy != null) {
                        preDestroy.clear();
                    } else {
                        preDestroy = new ArrayList<org.apache.openejb.jee.LifecycleCallback>();
                    }
                }
                preDestroy.add(preDestroyItem);
            } else if (("message-destination" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: messageDestination
                final MessageDestination messageDestinationItem = readMessageDestination(elementReader, context);
                if (messageDestination == null) {
                    messageDestination = webApp.messageDestination;
                    if (messageDestination != null) {
                        messageDestination.clear();
                    } else {
                        messageDestination = new ArrayList<MessageDestination>();
                    }
                }
                messageDestination.add(messageDestinationItem);
            } else if (("absolute-ordering" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: absoluteOrdering
                final AbsoluteOrdering absoluteOrdering = readAbsoluteOrdering(elementReader, context);
                webApp.absoluteOrdering = absoluteOrdering;
            } else if (("data-source" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: dataSource
                final DataSource dataSourceItem = readDataSource(elementReader, context);
                if (dataSource == null) {
                    dataSource = webApp.dataSource;
                    if (dataSource != null) {
                        dataSource.clear();
                    } else {
                        dataSource = new KeyedCollection<String, DataSource>();
                    }
                }
                dataSource.add(dataSourceItem);
            } else if (("jms-connection-factory" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: dataSource
                final JMSConnectionFactory connectionFactory = readJMSConnectionFactory(elementReader, context);
                if (jmsConnectionFactories == null) {
                    jmsConnectionFactories = webApp.jmsConnectionFactories;
                    if (jmsConnectionFactories != null) {
                        jmsConnectionFactories.clear();
                    } else {
                        jmsConnectionFactories = new KeyedCollection<>();
                    }
                }
                jmsConnectionFactories.add(connectionFactory);
            } else if (("module-name" == elementReader.getLocalName()) && ("http://java.sun.com/xml/ns/javaee" == elementReader.getNamespaceURI())) {
                // ELEMENT: moduleName
                final String moduleNameRaw = elementReader.getElementAsString();

                final String moduleName;
                try {
                    moduleName = Adapters.collapsedStringAdapterAdapter.unmarshal(moduleNameRaw);
                } catch (final Exception e) {
                    context.xmlAdapterError(elementReader, CollapsedStringAdapter.class, String.class, String.class, e);
                    continue;
                }

                webApp.moduleName = moduleName;
            } /*
            else not yet used so ignored, here will come servlet 3.1 elements we don't parse cause don't need yet
            */
        }
        if (descriptions != null) {
            try {
                webApp.setDescriptions(descriptions.toArray(new Text[descriptions.size()]));
            } catch (final Exception e) {
                context.setterError(reader, WebApp.class, "setDescriptions", Text[].class, e);
            }
        }
        if (displayNames != null) {
            try {
                webApp.setDisplayNames(displayNames.toArray(new Text[displayNames.size()]));
            } catch (final Exception e) {
                context.setterError(reader, WebApp.class, "setDisplayNames", Text[].class, e);
            }
        }
        if (icon != null) {
            webApp.icon = icon;
        }
        if (distributable != null) {
            webApp.distributable = distributable;
        }
        if (contextParam != null) {
            webApp.contextParam = contextParam;
        }
        if (filter != null) {
            webApp.filter = filter;
        }
        if (filterMapping != null) {
            webApp.filterMapping = filterMapping;
        }
        if (listener != null) {
            webApp.listener = listener;
        }
        if (servlet != null) {
            webApp.servlet = servlet;
        }
        if (servletMapping != null) {
            webApp.servletMapping = servletMapping;
        }
        if (sessionConfig != null) {
            webApp.sessionConfig = sessionConfig;
        }
        if (mimeMapping != null) {
            webApp.mimeMapping = mimeMapping;
        }
        if (welcomeFileList != null) {
            webApp.welcomeFileList = welcomeFileList;
        }
        if (errorPage != null) {
            webApp.errorPage = errorPage;
        }
        if (jspConfig != null) {
            webApp.jspConfig = jspConfig;
        }
        if (securityConstraint != null) {
            webApp.securityConstraint = securityConstraint;
        }
        if (loginConfig != null) {
            webApp.loginConfig = loginConfig;
        }
        if (securityRole != null) {
            webApp.securityRole = securityRole;
        }
        if (localeEncodingMappingList != null) {
            webApp.localeEncodingMappingList = localeEncodingMappingList;
        }
        if (envEntry != null) {
            webApp.envEntry = envEntry;
        }
        if (ejbRef != null) {
            webApp.ejbRef = ejbRef;
        }
        if (ejbLocalRef != null) {
            webApp.ejbLocalRef = ejbLocalRef;
        }
        if (serviceRef != null) {
            webApp.serviceRef = serviceRef;
        }
        if (resourceRef != null) {
            webApp.resourceRef = resourceRef;
        }
        if (resourceEnvRef != null) {
            webApp.resourceEnvRef = resourceEnvRef;
        }
        if (messageDestinationRef != null) {
            webApp.messageDestinationRef = messageDestinationRef;
        }
        if (persistenceContextRef != null) {
            webApp.persistenceContextRef = persistenceContextRef;
        }
        if (persistenceUnitRef != null) {
            webApp.persistenceUnitRef = persistenceUnitRef;
        }
        if (postConstruct != null) {
            webApp.postConstruct = postConstruct;
        }
        if (preDestroy != null) {
            webApp.preDestroy = preDestroy;
        }
        if (messageDestination != null) {
            webApp.messageDestination = messageDestination;
        }
        if (dataSource != null) {
            webApp.dataSource = dataSource;
        }

        context.afterUnmarshal(webApp, org.metatype.sxc.jaxb.LifecycleCallback.NONE);

        return webApp;
    }

    public final WebApp read(final XoXMLStreamReader reader, final RuntimeContext context)
        throws Exception {
        return _read(reader, context);
    }

    public final static void _write(final XoXMLStreamWriter writer, final WebApp webApp, RuntimeContext context)
        throws Exception {
        if (webApp == null) {
            writer.writeXsiNil();
            return;
        }

        if (context == null) {
            context = new RuntimeContext();
        }

        final String prefix = writer.getUniquePrefix("http://java.sun.com/xml/ns/javaee");
        if (WebApp.class != webApp.getClass()) {
            context.unexpectedSubclass(writer, webApp, WebApp.class);
            return;
        }

        context.beforeMarshal(webApp, org.metatype.sxc.jaxb.LifecycleCallback.NONE);


        // ATTRIBUTE: id
        final String idRaw = webApp.id;
        if (idRaw != null) {
            String id = null;
            try {
                id = Adapters.collapsedStringAdapterAdapter.marshal(idRaw);
            } catch (final Exception e) {
                context.xmlAdapterError(webApp, "id", CollapsedStringAdapter.class, String.class, String.class, e);
            }
            writer.writeAttribute("", "", "id", id);
        }

        // ATTRIBUTE: metadataComplete
        final Boolean metadataComplete = webApp.metadataComplete;
        if (metadataComplete != null) {
            writer.writeAttribute("", "", "metadata-complete", Boolean.toString(metadataComplete));
        }

        // ATTRIBUTE: version
        final String versionRaw = webApp.version;
        if (versionRaw != null) {
            String version = null;
            try {
                version = Adapters.collapsedStringAdapterAdapter.marshal(versionRaw);
            } catch (final Exception e) {
                context.xmlAdapterError(webApp, "version", CollapsedStringAdapter.class, String.class, String.class, e);
            }
            writer.writeAttribute("", "", "version", version);
        }

        // ELEMENT: descriptions
        Text[] descriptions = null;
        try {
            descriptions = webApp.getDescriptions();
        } catch (final Exception e) {
            context.getterError(webApp, "descriptions", WebApp.class, "getDescriptions", e);
        }
        if (descriptions != null) {
            for (final Text descriptionsItem : descriptions) {
                if (descriptionsItem != null) {
                    writer.writeStartElement(prefix, "description", "http://java.sun.com/xml/ns/javaee");
                    writeText(writer, descriptionsItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "descriptions");
                }
            }
        }

        // ELEMENT: displayNames
        Text[] displayNames = null;
        try {
            displayNames = webApp.getDisplayNames();
        } catch (final Exception e) {
            context.getterError(webApp, "displayNames", WebApp.class, "getDisplayNames", e);
        }
        if (displayNames != null) {
            for (final Text displayNamesItem : displayNames) {
                if (displayNamesItem != null) {
                    writer.writeStartElement(prefix, "display-name", "http://java.sun.com/xml/ns/javaee");
                    writeText(writer, displayNamesItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "displayNames");
                }
            }
        }

        // ELEMENT: icon
        final LocalCollection<Icon> icon = webApp.icon;
        if (icon != null) {
            for (final Icon iconItem : icon) {
                if (iconItem != null) {
                    writer.writeStartElement(prefix, "icon", "http://java.sun.com/xml/ns/javaee");
                    writeIcon(writer, iconItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "icon");
                }
            }
        }

        // ELEMENT: distributable
        final List<Empty> distributable = webApp.distributable;
        if (distributable != null) {
            for (final Empty distributableItem : distributable) {
                writer.writeStartElement(prefix, "distributable", "http://java.sun.com/xml/ns/javaee");
                if (distributableItem != null) {
                    writeEmpty(writer, distributableItem, context);
                } else {
                    writer.writeXsiNil();
                }
                writer.writeEndElement();
            }
        }

        // ELEMENT: contextParam
        final List<ParamValue> contextParam = webApp.contextParam;
        if (contextParam != null) {
            for (final ParamValue contextParamItem : contextParam) {
                if (contextParamItem != null) {
                    writer.writeStartElement(prefix, "context-param", "http://java.sun.com/xml/ns/javaee");
                    writeParamValue(writer, contextParamItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: filter
        final List<Filter> filter = webApp.filter;
        if (filter != null) {
            for (final Filter filterItem : filter) {
                writer.writeStartElement(prefix, "filter", "http://java.sun.com/xml/ns/javaee");
                if (filterItem != null) {
                    writeFilter(writer, filterItem, context);
                } else {
                    writer.writeXsiNil();
                }
                writer.writeEndElement();
            }
        }

        // ELEMENT: filterMapping
        final List<FilterMapping> filterMapping = webApp.filterMapping;
        if (filterMapping != null) {
            for (final FilterMapping filterMappingItem : filterMapping) {
                if (filterMappingItem != null) {
                    writer.writeStartElement(prefix, "filter-mapping", "http://java.sun.com/xml/ns/javaee");
                    writeFilterMapping(writer, filterMappingItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: listener
        final List<Listener> listener = webApp.listener;
        if (listener != null) {
            for (final Listener listenerItem : listener) {
                writer.writeStartElement(prefix, "listener", "http://java.sun.com/xml/ns/javaee");
                if (listenerItem != null) {
                    writeListener(writer, listenerItem, context);
                } else {
                    writer.writeXsiNil();
                }
                writer.writeEndElement();
            }
        }

        // ELEMENT: servlet
        final List<Servlet> servlet = webApp.servlet;
        if (servlet != null) {
            for (final Servlet servletItem : servlet) {
                writer.writeStartElement(prefix, "servlet", "http://java.sun.com/xml/ns/javaee");
                if (servletItem != null) {
                    writeServlet(writer, servletItem, context);
                } else {
                    writer.writeXsiNil();
                }
                writer.writeEndElement();
            }
        }

        // ELEMENT: servletMapping
        final List<ServletMapping> servletMapping = webApp.servletMapping;
        if (servletMapping != null) {
            for (final ServletMapping servletMappingItem : servletMapping) {
                if (servletMappingItem != null) {
                    writer.writeStartElement(prefix, "servlet-mapping", "http://java.sun.com/xml/ns/javaee");
                    writeServletMapping(writer, servletMappingItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: sessionConfig
        final List<SessionConfig> sessionConfig = webApp.sessionConfig;
        if (sessionConfig != null) {
            for (final SessionConfig sessionConfigItem : sessionConfig) {
                if (sessionConfigItem != null) {
                    writer.writeStartElement(prefix, "session-config", "http://java.sun.com/xml/ns/javaee");
                    writeSessionConfig(writer, sessionConfigItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: mimeMapping
        final List<MimeMapping> mimeMapping = webApp.mimeMapping;
        if (mimeMapping != null) {
            for (final MimeMapping mimeMappingItem : mimeMapping) {
                if (mimeMappingItem != null) {
                    writer.writeStartElement(prefix, "mime-mapping", "http://java.sun.com/xml/ns/javaee");
                    writeMimeMapping(writer, mimeMappingItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: welcomeFileList
        final List<WelcomeFileList> welcomeFileList = webApp.welcomeFileList;
        if (welcomeFileList != null) {
            for (final WelcomeFileList welcomeFileListItem : welcomeFileList) {
                if (welcomeFileListItem != null) {
                    writer.writeStartElement(prefix, "welcome-file-list", "http://java.sun.com/xml/ns/javaee");
                    writeWelcomeFileList(writer, welcomeFileListItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: errorPage
        final List<ErrorPage> errorPage = webApp.errorPage;
        if (errorPage != null) {
            for (final ErrorPage errorPageItem : errorPage) {
                if (errorPageItem != null) {
                    writer.writeStartElement(prefix, "error-page", "http://java.sun.com/xml/ns/javaee");
                    writeErrorPage(writer, errorPageItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: taglib
        Taglib taglib = null;
        try {
            taglib = webApp.getTaglib();
        } catch (final Exception e) {
            context.getterError(webApp, "taglib", WebApp.class, "getTaglib", e);
        }
        if (taglib != null) {
            writer.writeStartElement(prefix, "taglib", "http://java.sun.com/xml/ns/javaee");
            writeTaglib(writer, taglib, context);
            writer.writeEndElement();
        }

        // ELEMENT: jspConfig
        final List<JspConfig> jspConfig = webApp.jspConfig;
        if (jspConfig != null) {
            for (final JspConfig jspConfigItem : jspConfig) {
                if (jspConfigItem != null) {
                    writer.writeStartElement(prefix, "jsp-config", "http://java.sun.com/xml/ns/javaee");
                    writeJspConfig(writer, jspConfigItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: securityConstraint
        final List<SecurityConstraint> securityConstraint = webApp.securityConstraint;
        if (securityConstraint != null) {
            for (final SecurityConstraint securityConstraintItem : securityConstraint) {
                if (securityConstraintItem != null) {
                    writer.writeStartElement(prefix, "security-constraint", "http://java.sun.com/xml/ns/javaee");
                    writeSecurityConstraint(writer, securityConstraintItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: loginConfig
        final List<LoginConfig> loginConfig = webApp.loginConfig;
        if (loginConfig != null) {
            for (final LoginConfig loginConfigItem : loginConfig) {
                if (loginConfigItem != null) {
                    writer.writeStartElement(prefix, "login-config", "http://java.sun.com/xml/ns/javaee");
                    writeLoginConfig(writer, loginConfigItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: securityRole
        final List<SecurityRole> securityRole = webApp.securityRole;
        if (securityRole != null) {
            for (final SecurityRole securityRoleItem : securityRole) {
                if (securityRoleItem != null) {
                    writer.writeStartElement(prefix, "security-role", "http://java.sun.com/xml/ns/javaee");
                    writeSecurityRole(writer, securityRoleItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: localeEncodingMappingList
        final List<LocaleEncodingMappingList> localeEncodingMappingList = webApp.localeEncodingMappingList;
        if (localeEncodingMappingList != null) {
            for (final LocaleEncodingMappingList localeEncodingMappingListItem : localeEncodingMappingList) {
                if (localeEncodingMappingListItem != null) {
                    writer.writeStartElement(prefix, "locale-encoding-mapping-list", "http://java.sun.com/xml/ns/javaee");
                    writeLocaleEncodingMappingList(writer, localeEncodingMappingListItem, context);
                    writer.writeEndElement();
                }
            }
        }

        // ELEMENT: envEntry
        final KeyedCollection<String, EnvEntry> envEntry = webApp.envEntry;
        if (envEntry != null) {
            for (final EnvEntry envEntryItem : envEntry) {
                if (envEntryItem != null) {
                    writer.writeStartElement(prefix, "env-entry", "http://java.sun.com/xml/ns/javaee");
                    writeEnvEntry(writer, envEntryItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "envEntry");
                }
            }
        }

        // ELEMENT: ejbRef
        final KeyedCollection<String, EjbRef> ejbRef = webApp.ejbRef;
        if (ejbRef != null) {
            for (final EjbRef ejbRefItem : ejbRef) {
                if (ejbRefItem != null) {
                    writer.writeStartElement(prefix, "ejb-ref", "http://java.sun.com/xml/ns/javaee");
                    writeEjbRef(writer, ejbRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "ejbRef");
                }
            }
        }

        // ELEMENT: ejbLocalRef
        final KeyedCollection<String, EjbLocalRef> ejbLocalRef = webApp.ejbLocalRef;
        if (ejbLocalRef != null) {
            for (final EjbLocalRef ejbLocalRefItem : ejbLocalRef) {
                if (ejbLocalRefItem != null) {
                    writer.writeStartElement(prefix, "ejb-local-ref", "http://java.sun.com/xml/ns/javaee");
                    writeEjbLocalRef(writer, ejbLocalRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "ejbLocalRef");
                }
            }
        }

        // ELEMENT: serviceRef
        final KeyedCollection<String, ServiceRef> serviceRef = webApp.serviceRef;
        if (serviceRef != null) {
            for (final ServiceRef serviceRefItem : serviceRef) {
                if (serviceRefItem != null) {
                    writer.writeStartElement(prefix, "service-ref", "http://java.sun.com/xml/ns/javaee");
                    writeServiceRef(writer, serviceRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "serviceRef");
                }
            }
        }

        // ELEMENT: resourceRef
        final KeyedCollection<String, ResourceRef> resourceRef = webApp.resourceRef;
        if (resourceRef != null) {
            for (final ResourceRef resourceRefItem : resourceRef) {
                if (resourceRefItem != null) {
                    writer.writeStartElement(prefix, "resource-ref", "http://java.sun.com/xml/ns/javaee");
                    writeResourceRef(writer, resourceRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "resourceRef");
                }
            }
        }

        // ELEMENT: resourceEnvRef
        final KeyedCollection<String, ResourceEnvRef> resourceEnvRef = webApp.resourceEnvRef;
        if (resourceEnvRef != null) {
            for (final ResourceEnvRef resourceEnvRefItem : resourceEnvRef) {
                if (resourceEnvRefItem != null) {
                    writer.writeStartElement(prefix, "resource-env-ref", "http://java.sun.com/xml/ns/javaee");
                    writeResourceEnvRef(writer, resourceEnvRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "resourceEnvRef");
                }
            }
        }

        // ELEMENT: messageDestinationRef
        final KeyedCollection<String, MessageDestinationRef> messageDestinationRef = webApp.messageDestinationRef;
        if (messageDestinationRef != null) {
            for (final MessageDestinationRef messageDestinationRefItem : messageDestinationRef) {
                if (messageDestinationRefItem != null) {
                    writer.writeStartElement(prefix, "message-destination-ref", "http://java.sun.com/xml/ns/javaee");
                    writeMessageDestinationRef(writer, messageDestinationRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "messageDestinationRef");
                }
            }
        }

        // ELEMENT: persistenceContextRef
        final KeyedCollection<String, PersistenceContextRef> persistenceContextRef = webApp.persistenceContextRef;
        if (persistenceContextRef != null) {
            for (final PersistenceContextRef persistenceContextRefItem : persistenceContextRef) {
                if (persistenceContextRefItem != null) {
                    writer.writeStartElement(prefix, "persistence-context-ref", "http://java.sun.com/xml/ns/javaee");
                    writePersistenceContextRef(writer, persistenceContextRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "persistenceContextRef");
                }
            }
        }

        // ELEMENT: persistenceUnitRef
        final KeyedCollection<String, PersistenceUnitRef> persistenceUnitRef = webApp.persistenceUnitRef;
        if (persistenceUnitRef != null) {
            for (final PersistenceUnitRef persistenceUnitRefItem : persistenceUnitRef) {
                if (persistenceUnitRefItem != null) {
                    writer.writeStartElement(prefix, "persistence-unit-ref", "http://java.sun.com/xml/ns/javaee");
                    writePersistenceUnitRef(writer, persistenceUnitRefItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "persistenceUnitRef");
                }
            }
        }

        // ELEMENT: postConstruct
        final List<org.apache.openejb.jee.LifecycleCallback> postConstruct = webApp.postConstruct;
        if (postConstruct != null) {
            for (final org.apache.openejb.jee.LifecycleCallback postConstructItem : postConstruct) {
                if (postConstructItem != null) {
                    writer.writeStartElement(prefix, "post-construct", "http://java.sun.com/xml/ns/javaee");
                    writeLifecycleCallback(writer, postConstructItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "postConstruct");
                }
            }
        }

        // ELEMENT: preDestroy
        final List<org.apache.openejb.jee.LifecycleCallback> preDestroy = webApp.preDestroy;
        if (preDestroy != null) {
            for (final org.apache.openejb.jee.LifecycleCallback preDestroyItem : preDestroy) {
                if (preDestroyItem != null) {
                    writer.writeStartElement(prefix, "pre-destroy", "http://java.sun.com/xml/ns/javaee");
                    writeLifecycleCallback(writer, preDestroyItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "preDestroy");
                }
            }
        }

        // ELEMENT: messageDestination
        final List<MessageDestination> messageDestination = webApp.messageDestination;
        if (messageDestination != null) {
            for (final MessageDestination messageDestinationItem : messageDestination) {
                if (messageDestinationItem != null) {
                    writer.writeStartElement(prefix, "message-destination", "http://java.sun.com/xml/ns/javaee");
                    writeMessageDestination(writer, messageDestinationItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "messageDestination");
                }
            }
        }

        // ELEMENT: absoluteOrdering
        final AbsoluteOrdering absoluteOrdering = webApp.absoluteOrdering;
        if (absoluteOrdering != null) {
            writer.writeStartElement(prefix, "absolute-ordering", "http://java.sun.com/xml/ns/javaee");
            writeAbsoluteOrdering(writer, absoluteOrdering, context);
            writer.writeEndElement();
        }

        // ELEMENT: dataSource
        final KeyedCollection<String, DataSource> dataSource = webApp.dataSource;
        if (dataSource != null) {
            for (final DataSource dataSourceItem : dataSource) {
                if (dataSourceItem != null) {
                    writer.writeStartElement(prefix, "data-source", "http://java.sun.com/xml/ns/javaee");
                    writeDataSource(writer, dataSourceItem, context);
                    writer.writeEndElement();
                } else {
                    context.unexpectedNullValue(webApp, "dataSource");
                }
            }
        }

        // ELEMENT: moduleName
        final String moduleNameRaw = webApp.moduleName;
        String moduleName = null;
        try {
            moduleName = Adapters.collapsedStringAdapterAdapter.marshal(moduleNameRaw);
        } catch (final Exception e) {
            context.xmlAdapterError(webApp, "moduleName", CollapsedStringAdapter.class, String.class, String.class, e);
        }
        if (moduleName != null) {
            writer.writeStartElement(prefix, "module-name", "http://java.sun.com/xml/ns/javaee");
            writer.writeCharacters(moduleName);
            writer.writeEndElement();
        }

        context.afterMarshal(webApp, org.metatype.sxc.jaxb.LifecycleCallback.NONE);
    }

}
