/*
 * 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.axis2.jaxws.description.echo;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;


/**
 * This object contains factory methods for each Java content interface and Java element interface
 * generated in the org.apache.ws.axis2.tests package. <p>An ObjectFactory allows you to
 * programatically construct new instances of the Java representation for XML content. The Java
 * representation of XML content can consist of schema derived interfaces and classes representing
 * the binding of schema type definitions, element declarations and model groups.  Factory methods
 * for each of these are provided in this class.
 */
@XmlRegistry
public class ObjectFactory {

    private final static QName _EchoResponse_QNAME =
            new QName("http://ws.apache.org/axis2/tests", "EchoResponse");
    private final static QName _Echo_QNAME = new QName("http://ws.apache.org/axis2/tests", "Echo");

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes
     * for package: org.apache.ws.axis2.tests
     */
    public ObjectFactory() {
    }

    /** Create an instance of {@link EchoResponse } */
    public EchoResponse createEchoResponse() {
        return new EchoResponse();
    }

    /** Create an instance of {@link Echo } */
    public Echo createEcho() {
        return new Echo();
    }

    /** Create an instance of {@link JAXBElement }{@code <}{@link EchoResponse }{@code >}} */
    @XmlElementDecl(namespace = "http://ws.apache.org/axis2/tests", name = "EchoResponse")
    public JAXBElement<EchoResponse> createEchoResponse(EchoResponse value) {
        return new JAXBElement<EchoResponse>(_EchoResponse_QNAME, EchoResponse.class, null, value);
    }

    /** Create an instance of {@link JAXBElement }{@code <}{@link Echo }{@code >}} */
    @XmlElementDecl(namespace = "http://ws.apache.org/axis2/tests", name = "Echo")
    public JAXBElement<Echo> createEcho(Echo value) {
        return new JAXBElement<Echo>(_Echo_QNAME, Echo.class, null, value);
    }

}
