
/*
 * 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.proxy.doclitnonwrapped.sei;

import org.test.proxy.doclitnonwrapped.Invoke;
import org.test.proxy.doclitnonwrapped.ReturnType;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.ParameterStyle;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
import java.util.concurrent.Future;


/**
 * This class was generated by the JAXWS SI.
 * JAX-WS RI 2.0_01-b15-fcs
 * Generated source version: 2.0
 * 
 */
@WebService(name = "DocLitnonWrappedProxy", targetNamespace = "http://doclitnonwrapped.proxy.test.org")
@SOAPBinding(parameterStyle = ParameterStyle.BARE)
public interface DocLitnonWrappedProxy {
	/**
     * 
     * @param allByMyself
     * @return
     *     returns javax.xml.ws.Response<org.test.proxy.doclitnonwrapped.ReturnType>
     */
    @WebMethod(operationName = "invoke", action = "http://doclitnonwrapped.proxy.test.org/invokeReturn")
    public Response<ReturnType> invokeAsync(
        @WebParam(name = "invoke", targetNamespace = "http://doclitnonwrapped.proxy.test.org", partName = "allByMyself")
        Invoke allByMyself);

    /**
     * 
     * @param allByMyself
     * @param asyncHandler
     * @return
     *     returns java.util.concurrent.Future<? extends java.lang.Object>
     */
    @WebMethod(operationName = "invoke", action = "http://doclitnonwrapped.proxy.test.org/invokeReturn")
    public Future<?> invokeAsync(
        @WebParam(name = "invoke", targetNamespace = "http://doclitnonwrapped.proxy.test.org", partName = "allByMyself")
        Invoke allByMyself,
        @WebParam(name = "invokeResponse", targetNamespace = "", partName = "asyncHandler")
        AsyncHandler<ReturnType> asyncHandler);


    /**
     * 
     * @param allByMyself
     * @return
     *     returns org.test.proxy.doclitnonwrapped.ReturnType
     */
    @WebMethod(action = "http://doclitnonwrapped.proxy.test.org/invokeReturn")
    @WebResult(name = "ReturnType", targetNamespace = "http://doclitnonwrapped.proxy.test.org", partName = "allByMyself")
    public ReturnType invoke(
        @WebParam(name = "invoke", targetNamespace = "http://doclitnonwrapped.proxy.test.org", partName = "allByMyself")
        Invoke allByMyself);

}
