/*
 * 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.
 */

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18047
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;

// 
// This source code was auto-generated by wsdl, Version=4.0.30319.17929.
// 
namespace org.uddi.apiv3
{


    /// <remarks/>
  
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_Inquiry_SoapBinding", Namespace = "urn:uddi-org:api_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_Inquiry_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback find_bindingOperationCompleted;

        private System.Threading.SendOrPostCallback find_businessOperationCompleted;

        private System.Threading.SendOrPostCallback find_relatedBusinessesOperationCompleted;

        private System.Threading.SendOrPostCallback find_serviceOperationCompleted;

        private System.Threading.SendOrPostCallback find_tModelOperationCompleted;

        private System.Threading.SendOrPostCallback get_bindingDetailOperationCompleted;

        private System.Threading.SendOrPostCallback get_businessDetailOperationCompleted;

        private System.Threading.SendOrPostCallback get_operationalInfoOperationCompleted;

        private System.Threading.SendOrPostCallback get_serviceDetailOperationCompleted;

        private System.Threading.SendOrPostCallback get_tModelDetailOperationCompleted;

        /// <remarks/>
        public UDDI_Inquiry_SoapBinding()
        {
            this.Url = "http://localhost/uddi/inquire/";
        }

        /// <remarks/>
        public event find_bindingCompletedEventHandler find_bindingCompleted;

        /// <remarks/>
        public event find_businessCompletedEventHandler find_businessCompleted;

        /// <remarks/>
        public event find_relatedBusinessesCompletedEventHandler find_relatedBusinessesCompleted;

        /// <remarks/>
        public event find_serviceCompletedEventHandler find_serviceCompleted;

        /// <remarks/>
        public event find_tModelCompletedEventHandler find_tModelCompleted;

        /// <remarks/>
        public event get_bindingDetailCompletedEventHandler get_bindingDetailCompleted;

        /// <remarks/>
        public event get_businessDetailCompletedEventHandler get_businessDetailCompleted;

        /// <remarks/>
        public event get_operationalInfoCompletedEventHandler get_operationalInfoCompleted;

        /// <remarks/>
        public event get_serviceDetailCompletedEventHandler get_serviceDetailCompleted;

        /// <remarks/>
        public event get_tModelDetailCompletedEventHandler get_tModelDetailCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("find_binding", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("bindingDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual bindingDetail find_binding([System.Xml.Serialization.XmlElementAttribute("find_binding", Namespace = "urn:uddi-org:api_v3")] find_binding find_binding1)
        {
            object[] results = this.Invoke("find_binding", new object[] {
                    find_binding1});
            return ((bindingDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginfind_binding(find_binding find_binding1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("find_binding", new object[] {
                    find_binding1}, callback, asyncState);
        }

        /// <remarks/>
        public bindingDetail Endfind_binding(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((bindingDetail)(results[0]));
        }

        /// <remarks/>
        public void find_bindingAsync(find_binding find_binding1)
        {
            this.find_bindingAsync(find_binding1, null);
        }

        /// <remarks/>
        public void find_bindingAsync(find_binding find_binding1, object userState)
        {
            if ((this.find_bindingOperationCompleted == null))
            {
                this.find_bindingOperationCompleted = new System.Threading.SendOrPostCallback(this.Onfind_bindingOperationCompleted);
            }
            this.InvokeAsync("find_binding", new object[] {
                    find_binding1}, this.find_bindingOperationCompleted, userState);
        }

        private void Onfind_bindingOperationCompleted(object arg)
        {
            if ((this.find_bindingCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.find_bindingCompleted(this, new find_bindingCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("find_business", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("businessList", Namespace = "urn:uddi-org:api_v3")]
        public virtual businessList find_business([System.Xml.Serialization.XmlElementAttribute("find_business", Namespace = "urn:uddi-org:api_v3")] find_business find_business1)
        {
            object[] results = this.Invoke("find_business", new object[] {
                    find_business1});
            return ((businessList)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginfind_business(find_business find_business1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("find_business", new object[] {
                    find_business1}, callback, asyncState);
        }

        /// <remarks/>
        public businessList Endfind_business(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((businessList)(results[0]));
        }

        /// <remarks/>
        public void find_businessAsync(find_business find_business1)
        {
            this.find_businessAsync(find_business1, null);
        }

        /// <remarks/>
        public void find_businessAsync(find_business find_business1, object userState)
        {
            if ((this.find_businessOperationCompleted == null))
            {
                this.find_businessOperationCompleted = new System.Threading.SendOrPostCallback(this.Onfind_businessOperationCompleted);
            }
            this.InvokeAsync("find_business", new object[] {
                    find_business1}, this.find_businessOperationCompleted, userState);
        }

        private void Onfind_businessOperationCompleted(object arg)
        {
            if ((this.find_businessCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.find_businessCompleted(this, new find_businessCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("find_relatedBusinesses", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("relatedBusinessesList", Namespace = "urn:uddi-org:api_v3")]
        public virtual relatedBusinessesList find_relatedBusinesses([System.Xml.Serialization.XmlElementAttribute("find_relatedBusinesses", Namespace = "urn:uddi-org:api_v3")] find_relatedBusinesses find_relatedBusinesses1)
        {
            object[] results = this.Invoke("find_relatedBusinesses", new object[] {
                    find_relatedBusinesses1});
            return ((relatedBusinessesList)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginfind_relatedBusinesses(find_relatedBusinesses find_relatedBusinesses1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("find_relatedBusinesses", new object[] {
                    find_relatedBusinesses1}, callback, asyncState);
        }

        /// <remarks/>
        public relatedBusinessesList Endfind_relatedBusinesses(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((relatedBusinessesList)(results[0]));
        }

        /// <remarks/>
        public void find_relatedBusinessesAsync(find_relatedBusinesses find_relatedBusinesses1)
        {
            this.find_relatedBusinessesAsync(find_relatedBusinesses1, null);
        }

        /// <remarks/>
        public void find_relatedBusinessesAsync(find_relatedBusinesses find_relatedBusinesses1, object userState)
        {
            if ((this.find_relatedBusinessesOperationCompleted == null))
            {
                this.find_relatedBusinessesOperationCompleted = new System.Threading.SendOrPostCallback(this.Onfind_relatedBusinessesOperationCompleted);
            }
            this.InvokeAsync("find_relatedBusinesses", new object[] {
                    find_relatedBusinesses1}, this.find_relatedBusinessesOperationCompleted, userState);
        }

        private void Onfind_relatedBusinessesOperationCompleted(object arg)
        {
            if ((this.find_relatedBusinessesCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.find_relatedBusinessesCompleted(this, new find_relatedBusinessesCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("find_service", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("serviceList", Namespace = "urn:uddi-org:api_v3")]
        public virtual serviceList find_service([System.Xml.Serialization.XmlElementAttribute("find_service", Namespace = "urn:uddi-org:api_v3")] find_service find_service1)
        {
            object[] results = this.Invoke("find_service", new object[] {
                    find_service1});
            return ((serviceList)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginfind_service(find_service find_service1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("find_service", new object[] {
                    find_service1}, callback, asyncState);
        }

        /// <remarks/>
        public serviceList Endfind_service(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((serviceList)(results[0]));
        }

        /// <remarks/>
        public void find_serviceAsync(find_service find_service1)
        {
            this.find_serviceAsync(find_service1, null);
        }

        /// <remarks/>
        public void find_serviceAsync(find_service find_service1, object userState)
        {
            if ((this.find_serviceOperationCompleted == null))
            {
                this.find_serviceOperationCompleted = new System.Threading.SendOrPostCallback(this.Onfind_serviceOperationCompleted);
            }
            this.InvokeAsync("find_service", new object[] {
                    find_service1}, this.find_serviceOperationCompleted, userState);
        }

        private void Onfind_serviceOperationCompleted(object arg)
        {
            if ((this.find_serviceCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.find_serviceCompleted(this, new find_serviceCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("find_tModel", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("tModelList", Namespace = "urn:uddi-org:api_v3")]
        public virtual tModelList find_tModel([System.Xml.Serialization.XmlElementAttribute("find_tModel", Namespace = "urn:uddi-org:api_v3")] find_tModel find_tModel1)
        {
            object[] results = this.Invoke("find_tModel", new object[] {
                    find_tModel1});
            return ((tModelList)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginfind_tModel(find_tModel find_tModel1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("find_tModel", new object[] {
                    find_tModel1}, callback, asyncState);
        }

        /// <remarks/>
        public tModelList Endfind_tModel(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((tModelList)(results[0]));
        }

        /// <remarks/>
        public void find_tModelAsync(find_tModel find_tModel1)
        {
            this.find_tModelAsync(find_tModel1, null);
        }

        /// <remarks/>
        public void find_tModelAsync(find_tModel find_tModel1, object userState)
        {
            if ((this.find_tModelOperationCompleted == null))
            {
                this.find_tModelOperationCompleted = new System.Threading.SendOrPostCallback(this.Onfind_tModelOperationCompleted);
            }
            this.InvokeAsync("find_tModel", new object[] {
                    find_tModel1}, this.find_tModelOperationCompleted, userState);
        }

        private void Onfind_tModelOperationCompleted(object arg)
        {
            if ((this.find_tModelCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.find_tModelCompleted(this, new find_tModelCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_bindingDetail", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("bindingDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual bindingDetail get_bindingDetail([System.Xml.Serialization.XmlElementAttribute("get_bindingDetail", Namespace = "urn:uddi-org:api_v3")] get_bindingDetail get_bindingDetail1)
        {
            object[] results = this.Invoke("get_bindingDetail", new object[] {
                    get_bindingDetail1});
            return ((bindingDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_bindingDetail(get_bindingDetail get_bindingDetail1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_bindingDetail", new object[] {
                    get_bindingDetail1}, callback, asyncState);
        }

        /// <remarks/>
        public bindingDetail Endget_bindingDetail(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((bindingDetail)(results[0]));
        }

        /// <remarks/>
        public void get_bindingDetailAsync(get_bindingDetail get_bindingDetail1)
        {
            this.get_bindingDetailAsync(get_bindingDetail1, null);
        }

        /// <remarks/>
        public void get_bindingDetailAsync(get_bindingDetail get_bindingDetail1, object userState)
        {
            if ((this.get_bindingDetailOperationCompleted == null))
            {
                this.get_bindingDetailOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_bindingDetailOperationCompleted);
            }
            this.InvokeAsync("get_bindingDetail", new object[] {
                    get_bindingDetail1}, this.get_bindingDetailOperationCompleted, userState);
        }

        private void Onget_bindingDetailOperationCompleted(object arg)
        {
            if ((this.get_bindingDetailCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_bindingDetailCompleted(this, new get_bindingDetailCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_businessDetail", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("businessDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual businessDetail get_businessDetail([System.Xml.Serialization.XmlElementAttribute("get_businessDetail", Namespace = "urn:uddi-org:api_v3")] get_businessDetail get_businessDetail1)
        {
            object[] results = this.Invoke("get_businessDetail", new object[] {
                    get_businessDetail1});
            return ((businessDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_businessDetail(get_businessDetail get_businessDetail1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_businessDetail", new object[] {
                    get_businessDetail1}, callback, asyncState);
        }

        /// <remarks/>
        public businessDetail Endget_businessDetail(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((businessDetail)(results[0]));
        }

        /// <remarks/>
        public void get_businessDetailAsync(get_businessDetail get_businessDetail1)
        {
            this.get_businessDetailAsync(get_businessDetail1, null);
        }

        /// <remarks/>
        public void get_businessDetailAsync(get_businessDetail get_businessDetail1, object userState)
        {
            if ((this.get_businessDetailOperationCompleted == null))
            {
                this.get_businessDetailOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_businessDetailOperationCompleted);
            }
            this.InvokeAsync("get_businessDetail", new object[] {
                    get_businessDetail1}, this.get_businessDetailOperationCompleted, userState);
        }

        private void Onget_businessDetailOperationCompleted(object arg)
        {
            if ((this.get_businessDetailCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_businessDetailCompleted(this, new get_businessDetailCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_operationalInfo", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("operationalInfos", Namespace = "urn:uddi-org:api_v3")]
        public virtual operationalInfos get_operationalInfo([System.Xml.Serialization.XmlElementAttribute("get_operationalInfo", Namespace = "urn:uddi-org:api_v3")] get_operationalInfo get_operationalInfo1)
        {
            object[] results = this.Invoke("get_operationalInfo", new object[] {
                    get_operationalInfo1});
            return ((operationalInfos)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_operationalInfo(get_operationalInfo get_operationalInfo1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_operationalInfo", new object[] {
                    get_operationalInfo1}, callback, asyncState);
        }

        /// <remarks/>
        public operationalInfos Endget_operationalInfo(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((operationalInfos)(results[0]));
        }

        /// <remarks/>
        public void get_operationalInfoAsync(get_operationalInfo get_operationalInfo1)
        {
            this.get_operationalInfoAsync(get_operationalInfo1, null);
        }

        /// <remarks/>
        public void get_operationalInfoAsync(get_operationalInfo get_operationalInfo1, object userState)
        {
            if ((this.get_operationalInfoOperationCompleted == null))
            {
                this.get_operationalInfoOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_operationalInfoOperationCompleted);
            }
            this.InvokeAsync("get_operationalInfo", new object[] {
                    get_operationalInfo1}, this.get_operationalInfoOperationCompleted, userState);
        }

        private void Onget_operationalInfoOperationCompleted(object arg)
        {
            if ((this.get_operationalInfoCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_operationalInfoCompleted(this, new get_operationalInfoCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_serviceDetail", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("serviceDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual serviceDetail get_serviceDetail([System.Xml.Serialization.XmlElementAttribute("get_serviceDetail", Namespace = "urn:uddi-org:api_v3")] get_serviceDetail get_serviceDetail1)
        {
            object[] results = this.Invoke("get_serviceDetail", new object[] {
                    get_serviceDetail1});
            return ((serviceDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_serviceDetail(get_serviceDetail get_serviceDetail1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_serviceDetail", new object[] {
                    get_serviceDetail1}, callback, asyncState);
        }

        /// <remarks/>
        public serviceDetail Endget_serviceDetail(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((serviceDetail)(results[0]));
        }

        /// <remarks/>
        public void get_serviceDetailAsync(get_serviceDetail get_serviceDetail1)
        {
            this.get_serviceDetailAsync(get_serviceDetail1, null);
        }

        /// <remarks/>
        public void get_serviceDetailAsync(get_serviceDetail get_serviceDetail1, object userState)
        {
            if ((this.get_serviceDetailOperationCompleted == null))
            {
                this.get_serviceDetailOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_serviceDetailOperationCompleted);
            }
            this.InvokeAsync("get_serviceDetail", new object[] {
                    get_serviceDetail1}, this.get_serviceDetailOperationCompleted, userState);
        }

        private void Onget_serviceDetailOperationCompleted(object arg)
        {
            if ((this.get_serviceDetailCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_serviceDetailCompleted(this, new get_serviceDetailCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_tModelDetail", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("tModelDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual tModelDetail get_tModelDetail([System.Xml.Serialization.XmlElementAttribute("get_tModelDetail", Namespace = "urn:uddi-org:api_v3")] get_tModelDetail get_tModelDetail1)
        {
            object[] results = this.Invoke("get_tModelDetail", new object[] {
                    get_tModelDetail1});
            return ((tModelDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_tModelDetail(get_tModelDetail get_tModelDetail1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_tModelDetail", new object[] {
                    get_tModelDetail1}, callback, asyncState);
        }

        /// <remarks/>
        public tModelDetail Endget_tModelDetail(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((tModelDetail)(results[0]));
        }

        /// <remarks/>
        public void get_tModelDetailAsync(get_tModelDetail get_tModelDetail1)
        {
            this.get_tModelDetailAsync(get_tModelDetail1, null);
        }

        /// <remarks/>
        public void get_tModelDetailAsync(get_tModelDetail get_tModelDetail1, object userState)
        {
            if ((this.get_tModelDetailOperationCompleted == null))
            {
                this.get_tModelDetailOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_tModelDetailOperationCompleted);
            }
            this.InvokeAsync("get_tModelDetail", new object[] {
                    get_tModelDetail1}, this.get_tModelDetailOperationCompleted, userState);
        }

        private void Onget_tModelDetailOperationCompleted(object arg)
        {
            if ((this.get_tModelDetailCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_tModelDetailCompleted(this, new get_tModelDetailCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_Publication_SoapBinding", Namespace = "urn:uddi-org:api_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_Publication_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback add_publisherAssertionsOperationCompleted;

        private System.Threading.SendOrPostCallback delete_bindingOperationCompleted;

        private System.Threading.SendOrPostCallback delete_businessOperationCompleted;

        private System.Threading.SendOrPostCallback delete_publisherAssertionsOperationCompleted;

        private System.Threading.SendOrPostCallback delete_serviceOperationCompleted;

        private System.Threading.SendOrPostCallback delete_tModelOperationCompleted;

        private System.Threading.SendOrPostCallback get_assertionStatusReportOperationCompleted;

        private System.Threading.SendOrPostCallback get_publisherAssertionsOperationCompleted;

        private System.Threading.SendOrPostCallback get_registeredInfoOperationCompleted;

        private System.Threading.SendOrPostCallback save_bindingOperationCompleted;

        private System.Threading.SendOrPostCallback save_businessOperationCompleted;

        private System.Threading.SendOrPostCallback save_serviceOperationCompleted;

        private System.Threading.SendOrPostCallback save_tModelOperationCompleted;

        private System.Threading.SendOrPostCallback set_publisherAssertionsOperationCompleted;

        /// <remarks/>
        public UDDI_Publication_SoapBinding()
        {
            this.Url = "http://localhost/uddi/publish/";
        }

        /// <remarks/>
        public event add_publisherAssertionsCompletedEventHandler add_publisherAssertionsCompleted;

        /// <remarks/>
        public event delete_bindingCompletedEventHandler delete_bindingCompleted;

        /// <remarks/>
        public event delete_businessCompletedEventHandler delete_businessCompleted;

        /// <remarks/>
        public event delete_publisherAssertionsCompletedEventHandler delete_publisherAssertionsCompleted;

        /// <remarks/>
        public event delete_serviceCompletedEventHandler delete_serviceCompleted;

        /// <remarks/>
        public event delete_tModelCompletedEventHandler delete_tModelCompleted;

        /// <remarks/>
        public event get_assertionStatusReportCompletedEventHandler get_assertionStatusReportCompleted;

        /// <remarks/>
        public event get_publisherAssertionsCompletedEventHandler get_publisherAssertionsCompleted;

        /// <remarks/>
        public event get_registeredInfoCompletedEventHandler get_registeredInfoCompleted;

        /// <remarks/>
        public event save_bindingCompletedEventHandler save_bindingCompleted;

        /// <remarks/>
        public event save_businessCompletedEventHandler save_businessCompleted;

        /// <remarks/>
        public event save_serviceCompletedEventHandler save_serviceCompleted;

        /// <remarks/>
        public event save_tModelCompletedEventHandler save_tModelCompleted;

        /// <remarks/>
        public event set_publisherAssertionsCompletedEventHandler set_publisherAssertionsCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("add_publisherAssertions", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void add_publisherAssertions([System.Xml.Serialization.XmlElementAttribute("add_publisherAssertions", Namespace = "urn:uddi-org:api_v3")] add_publisherAssertions add_publisherAssertions1)
        {
            this.Invoke("add_publisherAssertions", new object[] {
                    add_publisherAssertions1});
        }

        /// <remarks/>
        public System.IAsyncResult Beginadd_publisherAssertions(add_publisherAssertions add_publisherAssertions1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("add_publisherAssertions", new object[] {
                    add_publisherAssertions1}, callback, asyncState);
        }

        /// <remarks/>
        public void Endadd_publisherAssertions(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void add_publisherAssertionsAsync(add_publisherAssertions add_publisherAssertions1)
        {
            this.add_publisherAssertionsAsync(add_publisherAssertions1, null);
        }

        /// <remarks/>
        public void add_publisherAssertionsAsync(add_publisherAssertions add_publisherAssertions1, object userState)
        {
            if ((this.add_publisherAssertionsOperationCompleted == null))
            {
                this.add_publisherAssertionsOperationCompleted = new System.Threading.SendOrPostCallback(this.Onadd_publisherAssertionsOperationCompleted);
            }
            this.InvokeAsync("add_publisherAssertions", new object[] {
                    add_publisherAssertions1}, this.add_publisherAssertionsOperationCompleted, userState);
        }

        private void Onadd_publisherAssertionsOperationCompleted(object arg)
        {
            if ((this.add_publisherAssertionsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.add_publisherAssertionsCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("delete_binding", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void delete_binding([System.Xml.Serialization.XmlElementAttribute("delete_binding", Namespace = "urn:uddi-org:api_v3")] delete_binding delete_binding1)
        {
            this.Invoke("delete_binding", new object[] {
                    delete_binding1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindelete_binding(delete_binding delete_binding1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("delete_binding", new object[] {
                    delete_binding1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddelete_binding(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void delete_bindingAsync(delete_binding delete_binding1)
        {
            this.delete_bindingAsync(delete_binding1, null);
        }

        /// <remarks/>
        public void delete_bindingAsync(delete_binding delete_binding1, object userState)
        {
            if ((this.delete_bindingOperationCompleted == null))
            {
                this.delete_bindingOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondelete_bindingOperationCompleted);
            }
            this.InvokeAsync("delete_binding", new object[] {
                    delete_binding1}, this.delete_bindingOperationCompleted, userState);
        }

        private void Ondelete_bindingOperationCompleted(object arg)
        {
            if ((this.delete_bindingCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.delete_bindingCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("delete_business", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public virtual void delete_business([System.Xml.Serialization.XmlElementAttribute("delete_business", Namespace = "urn:uddi-org:api_v3")] delete_business delete_business1)
        {
            this.Invoke("delete_business", new object[] {
                    delete_business1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindelete_business(delete_business delete_business1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("delete_business", new object[] {
                    delete_business1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddelete_business(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void delete_businessAsync(delete_business delete_business1)
        {
            this.delete_businessAsync(delete_business1, null);
        }

        /// <remarks/>
        public void delete_businessAsync(delete_business delete_business1, object userState)
        {
            if ((this.delete_businessOperationCompleted == null))
            {
                this.delete_businessOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondelete_businessOperationCompleted);
            }
            this.InvokeAsync("delete_business", new object[] {
                    delete_business1}, this.delete_businessOperationCompleted, userState);
        }

        private void Ondelete_businessOperationCompleted(object arg)
        {
            if ((this.delete_businessCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.delete_businessCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("delete_publisherAssertions", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public virtual void delete_publisherAssertions([System.Xml.Serialization.XmlElementAttribute("delete_publisherAssertions", Namespace = "urn:uddi-org:api_v3")] delete_publisherAssertions delete_publisherAssertions1)
        {
            this.Invoke("delete_publisherAssertions", new object[] {
                    delete_publisherAssertions1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindelete_publisherAssertions(delete_publisherAssertions delete_publisherAssertions1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("delete_publisherAssertions", new object[] {
                    delete_publisherAssertions1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddelete_publisherAssertions(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void delete_publisherAssertionsAsync(delete_publisherAssertions delete_publisherAssertions1)
        {
            this.delete_publisherAssertionsAsync(delete_publisherAssertions1, null);
        }

        /// <remarks/>
        public void delete_publisherAssertionsAsync(delete_publisherAssertions delete_publisherAssertions1, object userState)
        {
            if ((this.delete_publisherAssertionsOperationCompleted == null))
            {
                this.delete_publisherAssertionsOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondelete_publisherAssertionsOperationCompleted);
            }
            this.InvokeAsync("delete_publisherAssertions", new object[] {
                    delete_publisherAssertions1}, this.delete_publisherAssertionsOperationCompleted, userState);
        }

        private void Ondelete_publisherAssertionsOperationCompleted(object arg)
        {
            if ((this.delete_publisherAssertionsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.delete_publisherAssertionsCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("delete_service", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public virtual void delete_service([System.Xml.Serialization.XmlElementAttribute("delete_service", Namespace = "urn:uddi-org:api_v3")] delete_service delete_service1)
        {
            this.Invoke("delete_service", new object[] {
                    delete_service1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindelete_service(delete_service delete_service1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("delete_service", new object[] {
                    delete_service1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddelete_service(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void delete_serviceAsync(delete_service delete_service1)
        {
            this.delete_serviceAsync(delete_service1, null);
        }

        /// <remarks/>
        public void delete_serviceAsync(delete_service delete_service1, object userState)
        {
            if ((this.delete_serviceOperationCompleted == null))
            {
                this.delete_serviceOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondelete_serviceOperationCompleted);
            }
            this.InvokeAsync("delete_service", new object[] {
                    delete_service1}, this.delete_serviceOperationCompleted, userState);
        }

        private void Ondelete_serviceOperationCompleted(object arg)
        {
            if ((this.delete_serviceCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.delete_serviceCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("delete_tModel", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public virtual void delete_tModel([System.Xml.Serialization.XmlElementAttribute("delete_tModel", Namespace = "urn:uddi-org:api_v3")] delete_tModel delete_tModel1)
        {
            this.Invoke("delete_tModel", new object[] {
                    delete_tModel1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindelete_tModel(delete_tModel delete_tModel1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("delete_tModel", new object[] {
                    delete_tModel1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddelete_tModel(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void delete_tModelAsync(delete_tModel delete_tModel1)
        {
            this.delete_tModelAsync(delete_tModel1, null);
        }

        /// <remarks/>
        public void delete_tModelAsync(delete_tModel delete_tModel1, object userState)
        {
            if ((this.delete_tModelOperationCompleted == null))
            {
                this.delete_tModelOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondelete_tModelOperationCompleted);
            }
            this.InvokeAsync("delete_tModel", new object[] {
                    delete_tModel1}, this.delete_tModelOperationCompleted, userState);
        }

        private void Ondelete_tModelOperationCompleted(object arg)
        {
            if ((this.delete_tModelCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.delete_tModelCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_assertionStatusReport", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("assertionStatusReport", Namespace = "urn:uddi-org:api_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = false)]
        public virtual assertionStatusItem[] get_assertionStatusReport([System.Xml.Serialization.XmlElementAttribute("get_assertionStatusReport", Namespace = "urn:uddi-org:api_v3")] get_assertionStatusReport get_assertionStatusReport1)
        {
            object[] results = this.Invoke("get_assertionStatusReport", new object[] {
                    get_assertionStatusReport1});
            return ((assertionStatusItem[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_assertionStatusReport(get_assertionStatusReport get_assertionStatusReport1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_assertionStatusReport", new object[] {
                    get_assertionStatusReport1}, callback, asyncState);
        }

        /// <remarks/>
        public assertionStatusItem[] Endget_assertionStatusReport(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((assertionStatusItem[])(results[0]));
        }

        /// <remarks/>
        public void get_assertionStatusReportAsync(get_assertionStatusReport get_assertionStatusReport1)
        {
            this.get_assertionStatusReportAsync(get_assertionStatusReport1, null);
        }

        /// <remarks/>
        public void get_assertionStatusReportAsync(get_assertionStatusReport get_assertionStatusReport1, object userState)
        {
            if ((this.get_assertionStatusReportOperationCompleted == null))
            {
                this.get_assertionStatusReportOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_assertionStatusReportOperationCompleted);
            }
            this.InvokeAsync("get_assertionStatusReport", new object[] {
                    get_assertionStatusReport1}, this.get_assertionStatusReportOperationCompleted, userState);
        }

        private void Onget_assertionStatusReportOperationCompleted(object arg)
        {
            if ((this.get_assertionStatusReportCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_assertionStatusReportCompleted(this, new get_assertionStatusReportCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_publisherAssertions", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("publisherAssertionsResponse", Namespace = "urn:uddi-org:api_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = false)]
        public virtual publisherAssertion[] get_publisherAssertions([System.Xml.Serialization.XmlElementAttribute("get_publisherAssertions", Namespace = "urn:uddi-org:api_v3")] get_publisherAssertions get_publisherAssertions1)
        {
            object[] results = this.Invoke("get_publisherAssertions", new object[] {
                    get_publisherAssertions1});
            return ((publisherAssertion[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_publisherAssertions(get_publisherAssertions get_publisherAssertions1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_publisherAssertions", new object[] {
                    get_publisherAssertions1}, callback, asyncState);
        }

        /// <remarks/>
        public publisherAssertion[] Endget_publisherAssertions(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((publisherAssertion[])(results[0]));
        }

        /// <remarks/>
        public void get_publisherAssertionsAsync(get_publisherAssertions get_publisherAssertions1)
        {
            this.get_publisherAssertionsAsync(get_publisherAssertions1, null);
        }

        /// <remarks/>
        public void get_publisherAssertionsAsync(get_publisherAssertions get_publisherAssertions1, object userState)
        {
            if ((this.get_publisherAssertionsOperationCompleted == null))
            {
                this.get_publisherAssertionsOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_publisherAssertionsOperationCompleted);
            }
            this.InvokeAsync("get_publisherAssertions", new object[] {
                    get_publisherAssertions1}, this.get_publisherAssertionsOperationCompleted, userState);
        }

        private void Onget_publisherAssertionsOperationCompleted(object arg)
        {
            if ((this.get_publisherAssertionsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_publisherAssertionsCompleted(this, new get_publisherAssertionsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_registeredInfo", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("registeredInfo", Namespace = "urn:uddi-org:api_v3")]
        public virtual registeredInfo get_registeredInfo([System.Xml.Serialization.XmlElementAttribute("get_registeredInfo", Namespace = "urn:uddi-org:api_v3")] get_registeredInfo get_registeredInfo1)
        {
            object[] results = this.Invoke("get_registeredInfo", new object[] {
                    get_registeredInfo1});
            return ((registeredInfo)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_registeredInfo(get_registeredInfo get_registeredInfo1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_registeredInfo", new object[] {
                    get_registeredInfo1}, callback, asyncState);
        }

        /// <remarks/>
        public registeredInfo Endget_registeredInfo(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((registeredInfo)(results[0]));
        }

        /// <remarks/>
        public void get_registeredInfoAsync(get_registeredInfo get_registeredInfo1)
        {
            this.get_registeredInfoAsync(get_registeredInfo1, null);
        }

        /// <remarks/>
        public void get_registeredInfoAsync(get_registeredInfo get_registeredInfo1, object userState)
        {
            if ((this.get_registeredInfoOperationCompleted == null))
            {
                this.get_registeredInfoOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_registeredInfoOperationCompleted);
            }
            this.InvokeAsync("get_registeredInfo", new object[] {
                    get_registeredInfo1}, this.get_registeredInfoOperationCompleted, userState);
        }

        private void Onget_registeredInfoOperationCompleted(object arg)
        {
            if ((this.get_registeredInfoCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_registeredInfoCompleted(this, new get_registeredInfoCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("save_binding", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("bindingDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual bindingDetail save_binding([System.Xml.Serialization.XmlElementAttribute("save_binding", Namespace = "urn:uddi-org:api_v3")] save_binding save_binding1)
        {
            object[] results = this.Invoke("save_binding", new object[] {
                    save_binding1});
            return ((bindingDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginsave_binding(save_binding save_binding1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("save_binding", new object[] {
                    save_binding1}, callback, asyncState);
        }

        /// <remarks/>
        public bindingDetail Endsave_binding(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((bindingDetail)(results[0]));
        }

        /// <remarks/>
        public void save_bindingAsync(save_binding save_binding1)
        {
            this.save_bindingAsync(save_binding1, null);
        }

        /// <remarks/>
        public void save_bindingAsync(save_binding save_binding1, object userState)
        {
            if ((this.save_bindingOperationCompleted == null))
            {
                this.save_bindingOperationCompleted = new System.Threading.SendOrPostCallback(this.Onsave_bindingOperationCompleted);
            }
            this.InvokeAsync("save_binding", new object[] {
                    save_binding1}, this.save_bindingOperationCompleted, userState);
        }

        private void Onsave_bindingOperationCompleted(object arg)
        {
            if ((this.save_bindingCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.save_bindingCompleted(this, new save_bindingCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("save_business", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("businessDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual businessDetail save_business([System.Xml.Serialization.XmlElementAttribute("save_business", Namespace = "urn:uddi-org:api_v3")] save_business save_business1)
        {
            object[] results = this.Invoke("save_business", new object[] {
                    save_business1});
            return ((businessDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginsave_business(save_business save_business1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("save_business", new object[] {
                    save_business1}, callback, asyncState);
        }

        /// <remarks/>
        public businessDetail Endsave_business(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((businessDetail)(results[0]));
        }

        /// <remarks/>
        public void save_businessAsync(save_business save_business1)
        {
            this.save_businessAsync(save_business1, null);
        }

        /// <remarks/>
        public void save_businessAsync(save_business save_business1, object userState)
        {
            if ((this.save_businessOperationCompleted == null))
            {
                this.save_businessOperationCompleted = new System.Threading.SendOrPostCallback(this.Onsave_businessOperationCompleted);
            }
            this.InvokeAsync("save_business", new object[] {
                    save_business1}, this.save_businessOperationCompleted, userState);
        }

        private void Onsave_businessOperationCompleted(object arg)
        {
            if ((this.save_businessCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.save_businessCompleted(this, new save_businessCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("save_service", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("serviceDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual serviceDetail save_service([System.Xml.Serialization.XmlElementAttribute("save_service", Namespace = "urn:uddi-org:api_v3")] save_service save_service1)
        {
            object[] results = this.Invoke("save_service", new object[] {
                    save_service1});
            return ((serviceDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginsave_service(save_service save_service1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("save_service", new object[] {
                    save_service1}, callback, asyncState);
        }

        /// <remarks/>
        public serviceDetail Endsave_service(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((serviceDetail)(results[0]));
        }

        /// <remarks/>
        public void save_serviceAsync(save_service save_service1)
        {
            this.save_serviceAsync(save_service1, null);
        }

        /// <remarks/>
        public void save_serviceAsync(save_service save_service1, object userState)
        {
            if ((this.save_serviceOperationCompleted == null))
            {
                this.save_serviceOperationCompleted = new System.Threading.SendOrPostCallback(this.Onsave_serviceOperationCompleted);
            }
            this.InvokeAsync("save_service", new object[] {
                    save_service1}, this.save_serviceOperationCompleted, userState);
        }

        private void Onsave_serviceOperationCompleted(object arg)
        {
            if ((this.save_serviceCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.save_serviceCompleted(this, new save_serviceCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("save_tModel", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("tModelDetail", Namespace = "urn:uddi-org:api_v3")]
        public virtual tModelDetail save_tModel([System.Xml.Serialization.XmlElementAttribute("save_tModel", Namespace = "urn:uddi-org:api_v3")] save_tModel save_tModel1)
        {
            object[] results = this.Invoke("save_tModel", new object[] {
                    save_tModel1});
            return ((tModelDetail)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginsave_tModel(save_tModel save_tModel1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("save_tModel", new object[] {
                    save_tModel1}, callback, asyncState);
        }

        /// <remarks/>
        public tModelDetail Endsave_tModel(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((tModelDetail)(results[0]));
        }

        /// <remarks/>
        public void save_tModelAsync(save_tModel save_tModel1)
        {
            this.save_tModelAsync(save_tModel1, null);
        }

        /// <remarks/>
        public void save_tModelAsync(save_tModel save_tModel1, object userState)
        {
            if ((this.save_tModelOperationCompleted == null))
            {
                this.save_tModelOperationCompleted = new System.Threading.SendOrPostCallback(this.Onsave_tModelOperationCompleted);
            }
            this.InvokeAsync("save_tModel", new object[] {
                    save_tModel1}, this.save_tModelOperationCompleted, userState);
        }

        private void Onsave_tModelOperationCompleted(object arg)
        {
            if ((this.save_tModelCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.save_tModelCompleted(this, new save_tModelCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("set_publisherAssertions", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("publisherAssertions", Namespace = "urn:uddi-org:api_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = false)]
        public virtual publisherAssertion[] set_publisherAssertions([System.Xml.Serialization.XmlElementAttribute("set_publisherAssertions", Namespace = "urn:uddi-org:api_v3")] set_publisherAssertions set_publisherAssertions1)
        {
            object[] results = this.Invoke("set_publisherAssertions", new object[] {
                    set_publisherAssertions1});
            return ((publisherAssertion[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginset_publisherAssertions(set_publisherAssertions set_publisherAssertions1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("set_publisherAssertions", new object[] {
                    set_publisherAssertions1}, callback, asyncState);
        }

        /// <remarks/>
        public publisherAssertion[] Endset_publisherAssertions(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((publisherAssertion[])(results[0]));
        }

        /// <remarks/>
        public void set_publisherAssertionsAsync(set_publisherAssertions set_publisherAssertions1)
        {
            this.set_publisherAssertionsAsync(set_publisherAssertions1, null);
        }

        /// <remarks/>
        public void set_publisherAssertionsAsync(set_publisherAssertions set_publisherAssertions1, object userState)
        {
            if ((this.set_publisherAssertionsOperationCompleted == null))
            {
                this.set_publisherAssertionsOperationCompleted = new System.Threading.SendOrPostCallback(this.Onset_publisherAssertionsOperationCompleted);
            }
            this.InvokeAsync("set_publisherAssertions", new object[] {
                    set_publisherAssertions1}, this.set_publisherAssertionsOperationCompleted, userState);
        }

        private void Onset_publisherAssertionsOperationCompleted(object arg)
        {
            if ((this.set_publisherAssertionsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.set_publisherAssertionsCompleted(this, new set_publisherAssertionsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_Security_SoapBinding", Namespace = "urn:uddi-org:api_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_Security_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback discard_authTokenOperationCompleted;

        private System.Threading.SendOrPostCallback get_authTokenOperationCompleted;

        /// <remarks/>
        public UDDI_Security_SoapBinding()
        {
            this.Url = "http://localhost/uddi/security/";
        }

        /// <remarks/>
        public event discard_authTokenCompletedEventHandler discard_authTokenCompleted;

        /// <remarks/>
        public event get_authTokenCompletedEventHandler get_authTokenCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("discard_authToken", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public virtual void discard_authToken([System.Xml.Serialization.XmlElementAttribute("discard_authToken", Namespace = "urn:uddi-org:api_v3")] discard_authToken discard_authToken1)
        {
            this.Invoke("discard_authToken", new object[] {
                    discard_authToken1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindiscard_authToken(discard_authToken discard_authToken1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("discard_authToken", new object[] {
                    discard_authToken1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddiscard_authToken(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void discard_authTokenAsync(discard_authToken discard_authToken1)
        {
            this.discard_authTokenAsync(discard_authToken1, null);
        }

        /// <remarks/>
        public void discard_authTokenAsync(discard_authToken discard_authToken1, object userState)
        {
            if ((this.discard_authTokenOperationCompleted == null))
            {
                this.discard_authTokenOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondiscard_authTokenOperationCompleted);
            }
            this.InvokeAsync("discard_authToken", new object[] {
                    discard_authToken1}, this.discard_authTokenOperationCompleted, userState);
        }

        private void Ondiscard_authTokenOperationCompleted(object arg)
        {
            if ((this.discard_authTokenCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.discard_authTokenCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_authToken", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("authToken", Namespace = "urn:uddi-org:api_v3")]
        public virtual authToken get_authToken([System.Xml.Serialization.XmlElementAttribute("get_authToken", Namespace = "urn:uddi-org:api_v3")] get_authToken get_authToken1)
        {
            object[] results = this.Invoke("get_authToken", new object[] {
                    get_authToken1});
            return ((authToken)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_authToken(get_authToken get_authToken1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_authToken", new object[] {
                    get_authToken1}, callback, asyncState);
        }

        /// <remarks/>
        public authToken Endget_authToken(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((authToken)(results[0]));
        }

        /// <remarks/>
        public void get_authTokenAsync(get_authToken get_authToken1)
        {
            this.get_authTokenAsync(get_authToken1, null);
        }

        /// <remarks/>
        public void get_authTokenAsync(get_authToken get_authToken1, object userState)
        {
            if ((this.get_authTokenOperationCompleted == null))
            {
                this.get_authTokenOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_authTokenOperationCompleted);
            }
            this.InvokeAsync("get_authToken", new object[] {
                    get_authToken1}, this.get_authTokenOperationCompleted, userState);
        }

        private void Onget_authTokenOperationCompleted(object arg)
        {
            if ((this.get_authTokenCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_authTokenCompleted(this, new get_authTokenCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_CustodyTransfer_SoapBinding", Namespace = "urn:uddi-org:custody_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_CustodyTransfer_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback discard_transferTokenOperationCompleted;

        private System.Threading.SendOrPostCallback get_transferTokenOperationCompleted;

        private System.Threading.SendOrPostCallback transfer_entitiesOperationCompleted;

        /// <remarks/>
        public UDDI_CustodyTransfer_SoapBinding()
        {
            this.Url = "http://localhost/uddi/custody/";
        }

        /// <remarks/>
        public event discard_transferTokenCompletedEventHandler discard_transferTokenCompleted;

        /// <remarks/>
        public event get_transferTokenCompletedEventHandler get_transferTokenCompleted;

        /// <remarks/>
        public event transfer_entitiesCompletedEventHandler transfer_entitiesCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("discard_transferToken", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void discard_transferToken([System.Xml.Serialization.XmlElementAttribute("discard_transferToken", Namespace = "urn:uddi-org:custody_v3")] discard_transferToken discard_transferToken1)
        {
            this.Invoke("discard_transferToken", new object[] {
                    discard_transferToken1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindiscard_transferToken(discard_transferToken discard_transferToken1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("discard_transferToken", new object[] {
                    discard_transferToken1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddiscard_transferToken(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void discard_transferTokenAsync(discard_transferToken discard_transferToken1)
        {
            this.discard_transferTokenAsync(discard_transferToken1, null);
        }

        /// <remarks/>
        public void discard_transferTokenAsync(discard_transferToken discard_transferToken1, object userState)
        {
            if ((this.discard_transferTokenOperationCompleted == null))
            {
                this.discard_transferTokenOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondiscard_transferTokenOperationCompleted);
            }
            this.InvokeAsync("discard_transferToken", new object[] {
                    discard_transferToken1}, this.discard_transferTokenOperationCompleted, userState);
        }

        private void Ondiscard_transferTokenOperationCompleted(object arg)
        {
            if ((this.discard_transferTokenCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.discard_transferTokenCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_transferToken", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("transferToken", Namespace = "urn:uddi-org:custody_v3")]
        public transferToken get_transferToken([System.Xml.Serialization.XmlElementAttribute("get_transferToken", Namespace = "urn:uddi-org:custody_v3")] get_transferToken get_transferToken1)
        {
            object[] results = this.Invoke("get_transferToken", new object[] {
                    get_transferToken1});
            return ((transferToken)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_transferToken(get_transferToken get_transferToken1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_transferToken", new object[] {
                    get_transferToken1}, callback, asyncState);
        }

        /// <remarks/>
        public transferToken Endget_transferToken(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((transferToken)(results[0]));
        }

        /// <remarks/>
        public void get_transferTokenAsync(get_transferToken get_transferToken1)
        {
            this.get_transferTokenAsync(get_transferToken1, null);
        }

        /// <remarks/>
        public void get_transferTokenAsync(get_transferToken get_transferToken1, object userState)
        {
            if ((this.get_transferTokenOperationCompleted == null))
            {
                this.get_transferTokenOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_transferTokenOperationCompleted);
            }
            this.InvokeAsync("get_transferToken", new object[] {
                    get_transferToken1}, this.get_transferTokenOperationCompleted, userState);
        }

        private void Onget_transferTokenOperationCompleted(object arg)
        {
            if ((this.get_transferTokenCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_transferTokenCompleted(this, new get_transferTokenCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("transfer_entities", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void transfer_entities([System.Xml.Serialization.XmlElementAttribute("transfer_entities", Namespace = "urn:uddi-org:custody_v3")] transfer_entities transfer_entities1)
        {
            this.Invoke("transfer_entities", new object[] {
                    transfer_entities1});
        }

        /// <remarks/>
        public System.IAsyncResult Begintransfer_entities(transfer_entities transfer_entities1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("transfer_entities", new object[] {
                    transfer_entities1}, callback, asyncState);
        }

        /// <remarks/>
        public void Endtransfer_entities(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void transfer_entitiesAsync(transfer_entities transfer_entities1)
        {
            this.transfer_entitiesAsync(transfer_entities1, null);
        }

        /// <remarks/>
        public void transfer_entitiesAsync(transfer_entities transfer_entities1, object userState)
        {
            if ((this.transfer_entitiesOperationCompleted == null))
            {
                this.transfer_entitiesOperationCompleted = new System.Threading.SendOrPostCallback(this.Ontransfer_entitiesOperationCompleted);
            }
            this.InvokeAsync("transfer_entities", new object[] {
                    transfer_entities1}, this.transfer_entitiesOperationCompleted, userState);
        }

        private void Ontransfer_entitiesOperationCompleted(object arg)
        {
            if ((this.transfer_entitiesCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.transfer_entitiesCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_Replication_SoapBinding", Namespace = "urn:uddi-org:repl_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_Replication_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback get_changeRecordsOperationCompleted;

        private System.Threading.SendOrPostCallback notify_changeRecordsAvailableOperationCompleted;

        private System.Threading.SendOrPostCallback do_pingOperationCompleted;

        private System.Threading.SendOrPostCallback get_highWaterMarksOperationCompleted;

        private System.Threading.SendOrPostCallback transfer_custodyOperationCompleted;

        /// <remarks/>
        public UDDI_Replication_SoapBinding()
        {
            this.Url = "http://localhost/uddi/replication/";
        }

        /// <remarks/>
        public event get_changeRecordsCompletedEventHandler get_changeRecordsCompleted;

        /// <remarks/>
        public event notify_changeRecordsAvailableCompletedEventHandler notify_changeRecordsAvailableCompleted;

        /// <remarks/>
        public event do_pingCompletedEventHandler do_pingCompleted;

        /// <remarks/>
        public event get_highWaterMarksCompletedEventHandler get_highWaterMarksCompleted;

        /// <remarks/>
        public event transfer_custodyCompletedEventHandler transfer_custodyCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_changeRecords", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("changeRecords", Namespace = "urn:uddi-org:repl_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute("changeRecord", IsNullable = false)]
        public changeRecord[] get_changeRecords([System.Xml.Serialization.XmlElementAttribute("get_changeRecords", Namespace = "urn:uddi-org:repl_v3")] get_changeRecords get_changeRecords1)
        {
            object[] results = this.Invoke("get_changeRecords", new object[] {
                    get_changeRecords1});
            return ((changeRecord[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_changeRecords(get_changeRecords get_changeRecords1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_changeRecords", new object[] {
                    get_changeRecords1}, callback, asyncState);
        }

        /// <remarks/>
        public changeRecord[] Endget_changeRecords(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((changeRecord[])(results[0]));
        }

        /// <remarks/>
        public void get_changeRecordsAsync(get_changeRecords get_changeRecords1)
        {
            this.get_changeRecordsAsync(get_changeRecords1, null);
        }

        /// <remarks/>
        public void get_changeRecordsAsync(get_changeRecords get_changeRecords1, object userState)
        {
            if ((this.get_changeRecordsOperationCompleted == null))
            {
                this.get_changeRecordsOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_changeRecordsOperationCompleted);
            }
            this.InvokeAsync("get_changeRecords", new object[] {
                    get_changeRecords1}, this.get_changeRecordsOperationCompleted, userState);
        }

        private void Onget_changeRecordsOperationCompleted(object arg)
        {
            if ((this.get_changeRecordsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_changeRecordsCompleted(this, new get_changeRecordsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("notify_changeRecordsAvailable", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void notify_changeRecordsAvailable([System.Xml.Serialization.XmlElementAttribute("notify_changeRecordsAvailable", Namespace = "urn:uddi-org:repl_v3")] notify_changeRecordsAvailable notify_changeRecordsAvailable1)
        {
            this.Invoke("notify_changeRecordsAvailable", new object[] {
                    notify_changeRecordsAvailable1});
        }

        /// <remarks/>
        public System.IAsyncResult Beginnotify_changeRecordsAvailable(notify_changeRecordsAvailable notify_changeRecordsAvailable1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("notify_changeRecordsAvailable", new object[] {
                    notify_changeRecordsAvailable1}, callback, asyncState);
        }

        /// <remarks/>
        public void Endnotify_changeRecordsAvailable(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void notify_changeRecordsAvailableAsync(notify_changeRecordsAvailable notify_changeRecordsAvailable1)
        {
            this.notify_changeRecordsAvailableAsync(notify_changeRecordsAvailable1, null);
        }

        /// <remarks/>
        public void notify_changeRecordsAvailableAsync(notify_changeRecordsAvailable notify_changeRecordsAvailable1, object userState)
        {
            if ((this.notify_changeRecordsAvailableOperationCompleted == null))
            {
                this.notify_changeRecordsAvailableOperationCompleted = new System.Threading.SendOrPostCallback(this.Onnotify_changeRecordsAvailableOperationCompleted);
            }
            this.InvokeAsync("notify_changeRecordsAvailable", new object[] {
                    notify_changeRecordsAvailable1}, this.notify_changeRecordsAvailableOperationCompleted, userState);
        }

        private void Onnotify_changeRecordsAvailableOperationCompleted(object arg)
        {
            if ((this.notify_changeRecordsAvailableCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.notify_changeRecordsAvailableCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("do_ping", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("operatorNodeID", Namespace = "urn:uddi-org:repl_v3", DataType = "anyURI")]
        public string do_ping([System.Xml.Serialization.XmlElementAttribute("do_ping", Namespace = "urn:uddi-org:repl_v3")] do_ping do_ping1)
        {
            object[] results = this.Invoke("do_ping", new object[] {
                    do_ping1});
            return ((string)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Begindo_ping(do_ping do_ping1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("do_ping", new object[] {
                    do_ping1}, callback, asyncState);
        }

        /// <remarks/>
        public string Enddo_ping(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((string)(results[0]));
        }

        /// <remarks/>
        public void do_pingAsync(do_ping do_ping1)
        {
            this.do_pingAsync(do_ping1, null);
        }

        /// <remarks/>
        public void do_pingAsync(do_ping do_ping1, object userState)
        {
            if ((this.do_pingOperationCompleted == null))
            {
                this.do_pingOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondo_pingOperationCompleted);
            }
            this.InvokeAsync("do_ping", new object[] {
                    do_ping1}, this.do_pingOperationCompleted, userState);
        }

        private void Ondo_pingOperationCompleted(object arg)
        {
            if ((this.do_pingCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.do_pingCompleted(this, new do_pingCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_highWaterMarks", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("highWaterMarks", Namespace = "urn:uddi-org:repl_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute("highWaterMark", IsNullable = false)]
        public changeRecordID_type[] get_highWaterMarks([System.Xml.Serialization.XmlElementAttribute("get_highWaterMarks", Namespace = "urn:uddi-org:repl_v3")] get_highWaterMarks get_highWaterMarks1)
        {
            object[] results = this.Invoke("get_highWaterMarks", new object[] {
                    get_highWaterMarks1});
            return ((changeRecordID_type[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_highWaterMarks(get_highWaterMarks get_highWaterMarks1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_highWaterMarks", new object[] {
                    get_highWaterMarks1}, callback, asyncState);
        }

        /// <remarks/>
        public changeRecordID_type[] Endget_highWaterMarks(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((changeRecordID_type[])(results[0]));
        }

        /// <remarks/>
        public void get_highWaterMarksAsync(get_highWaterMarks get_highWaterMarks1)
        {
            this.get_highWaterMarksAsync(get_highWaterMarks1, null);
        }

        /// <remarks/>
        public void get_highWaterMarksAsync(get_highWaterMarks get_highWaterMarks1, object userState)
        {
            if ((this.get_highWaterMarksOperationCompleted == null))
            {
                this.get_highWaterMarksOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_highWaterMarksOperationCompleted);
            }
            this.InvokeAsync("get_highWaterMarks", new object[] {
                    get_highWaterMarks1}, this.get_highWaterMarksOperationCompleted, userState);
        }

        private void Onget_highWaterMarksOperationCompleted(object arg)
        {
            if ((this.get_highWaterMarksCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_highWaterMarksCompleted(this, new get_highWaterMarksCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("transfer_custody", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void transfer_custody([System.Xml.Serialization.XmlElementAttribute("transfer_custody", Namespace = "urn:uddi-org:repl_v3")] transfer_custody transfer_custody1)
        {
            this.Invoke("transfer_custody", new object[] {
                    transfer_custody1});
        }

        /// <remarks/>
        public System.IAsyncResult Begintransfer_custody(transfer_custody transfer_custody1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("transfer_custody", new object[] {
                    transfer_custody1}, callback, asyncState);
        }

        /// <remarks/>
        public void Endtransfer_custody(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void transfer_custodyAsync(transfer_custody transfer_custody1)
        {
            this.transfer_custodyAsync(transfer_custody1, null);
        }

        /// <remarks/>
        public void transfer_custodyAsync(transfer_custody transfer_custody1, object userState)
        {
            if ((this.transfer_custodyOperationCompleted == null))
            {
                this.transfer_custodyOperationCompleted = new System.Threading.SendOrPostCallback(this.Ontransfer_custodyOperationCompleted);
            }
            this.InvokeAsync("transfer_custody", new object[] {
                    transfer_custody1}, this.transfer_custodyOperationCompleted, userState);
        }

        private void Ontransfer_custodyOperationCompleted(object arg)
        {
            if ((this.transfer_custodyCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.transfer_custodyCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_Subscription_SoapBinding", Namespace = "urn:uddi-org:sub_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_Subscription_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback delete_subscriptionOperationCompleted;

        private System.Threading.SendOrPostCallback get_subscriptionResultsOperationCompleted;

        private System.Threading.SendOrPostCallback get_subscriptionsOperationCompleted;

        private System.Threading.SendOrPostCallback save_subscriptionOperationCompleted;

        /// <remarks/>
        public UDDI_Subscription_SoapBinding()
        {
            this.Url = "http://localhost/uddi/subscription/";
        }

        /// <remarks/>
        public event delete_subscriptionCompletedEventHandler delete_subscriptionCompleted;

        /// <remarks/>
        public event get_subscriptionResultsCompletedEventHandler get_subscriptionResultsCompleted;

        /// <remarks/>
        public event get_subscriptionsCompletedEventHandler get_subscriptionsCompleted;

        /// <remarks/>
        public event save_subscriptionCompletedEventHandler save_subscriptionCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("delete_subscription", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        public void delete_subscription([System.Xml.Serialization.XmlElementAttribute("delete_subscription", Namespace = "urn:uddi-org:sub_v3")] delete_subscription delete_subscription1)
        {
            this.Invoke("delete_subscription", new object[] {
                    delete_subscription1});
        }

        /// <remarks/>
        public System.IAsyncResult Begindelete_subscription(delete_subscription delete_subscription1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("delete_subscription", new object[] {
                    delete_subscription1}, callback, asyncState);
        }

        /// <remarks/>
        public void Enddelete_subscription(System.IAsyncResult asyncResult)
        {
            this.EndInvoke(asyncResult);
        }

        /// <remarks/>
        public void delete_subscriptionAsync(delete_subscription delete_subscription1)
        {
            this.delete_subscriptionAsync(delete_subscription1, null);
        }

        /// <remarks/>
        public void delete_subscriptionAsync(delete_subscription delete_subscription1, object userState)
        {
            if ((this.delete_subscriptionOperationCompleted == null))
            {
                this.delete_subscriptionOperationCompleted = new System.Threading.SendOrPostCallback(this.Ondelete_subscriptionOperationCompleted);
            }
            this.InvokeAsync("delete_subscription", new object[] {
                    delete_subscription1}, this.delete_subscriptionOperationCompleted, userState);
        }

        private void Ondelete_subscriptionOperationCompleted(object arg)
        {
            if ((this.delete_subscriptionCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.delete_subscriptionCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_subscriptionResults", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("subscriptionResultsList", Namespace = "urn:uddi-org:sub_v3")]
        public subscriptionResultsList get_subscriptionResults([System.Xml.Serialization.XmlElementAttribute("get_subscriptionResults", Namespace = "urn:uddi-org:sub_v3")] get_subscriptionResults get_subscriptionResults1)
        {
            object[] results = this.Invoke("get_subscriptionResults", new object[] {
                    get_subscriptionResults1});
            return ((subscriptionResultsList)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_subscriptionResults(get_subscriptionResults get_subscriptionResults1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_subscriptionResults", new object[] {
                    get_subscriptionResults1}, callback, asyncState);
        }

        /// <remarks/>
        public subscriptionResultsList Endget_subscriptionResults(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((subscriptionResultsList)(results[0]));
        }

        /// <remarks/>
        public void get_subscriptionResultsAsync(get_subscriptionResults get_subscriptionResults1)
        {
            this.get_subscriptionResultsAsync(get_subscriptionResults1, null);
        }

        /// <remarks/>
        public void get_subscriptionResultsAsync(get_subscriptionResults get_subscriptionResults1, object userState)
        {
            if ((this.get_subscriptionResultsOperationCompleted == null))
            {
                this.get_subscriptionResultsOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_subscriptionResultsOperationCompleted);
            }
            this.InvokeAsync("get_subscriptionResults", new object[] {
                    get_subscriptionResults1}, this.get_subscriptionResultsOperationCompleted, userState);
        }

        private void Onget_subscriptionResultsOperationCompleted(object arg)
        {
            if ((this.get_subscriptionResultsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_subscriptionResultsCompleted(this, new get_subscriptionResultsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_subscriptions", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("subscriptions", Namespace = "urn:uddi-org:sub_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = false)]
        public subscription[] get_subscriptions([System.Xml.Serialization.XmlElementAttribute("get_subscriptions", Namespace = "urn:uddi-org:sub_v3")] get_subscriptions get_subscriptions1)
        {
            object[] results = this.Invoke("get_subscriptions", new object[] {
                    get_subscriptions1});
            return ((subscription[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_subscriptions(get_subscriptions get_subscriptions1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_subscriptions", new object[] {
                    get_subscriptions1}, callback, asyncState);
        }

        /// <remarks/>
        public subscription[] Endget_subscriptions(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((subscription[])(results[0]));
        }

        /// <remarks/>
        public void get_subscriptionsAsync(get_subscriptions get_subscriptions1)
        {
            this.get_subscriptionsAsync(get_subscriptions1, null);
        }

        /// <remarks/>
        public void get_subscriptionsAsync(get_subscriptions get_subscriptions1, object userState)
        {
            if ((this.get_subscriptionsOperationCompleted == null))
            {
                this.get_subscriptionsOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_subscriptionsOperationCompleted);
            }
            this.InvokeAsync("get_subscriptions", new object[] {
                    get_subscriptions1}, this.get_subscriptionsOperationCompleted, userState);
        }

        private void Onget_subscriptionsOperationCompleted(object arg)
        {
            if ((this.get_subscriptionsCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_subscriptionsCompleted(this, new get_subscriptionsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("save_subscription", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlArrayAttribute("subscriptions", Namespace = "urn:uddi-org:sub_v3")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = false)]
        public subscription[] save_subscription([System.Xml.Serialization.XmlElementAttribute("save_subscription", Namespace = "urn:uddi-org:sub_v3")] save_subscription save_subscription1)
        {
            object[] results = this.Invoke("save_subscription", new object[] {
                    save_subscription1});
            return ((subscription[])(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginsave_subscription(save_subscription save_subscription1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("save_subscription", new object[] {
                    save_subscription1}, callback, asyncState);
        }

        /// <remarks/>
        public subscription[] Endsave_subscription(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((subscription[])(results[0]));
        }

        /// <remarks/>
        public void save_subscriptionAsync(save_subscription save_subscription1)
        {
            this.save_subscriptionAsync(save_subscription1, null);
        }

        /// <remarks/>
        public void save_subscriptionAsync(save_subscription save_subscription1, object userState)
        {
            if ((this.save_subscriptionOperationCompleted == null))
            {
                this.save_subscriptionOperationCompleted = new System.Threading.SendOrPostCallback(this.Onsave_subscriptionOperationCompleted);
            }
            this.InvokeAsync("save_subscription", new object[] {
                    save_subscription1}, this.save_subscriptionOperationCompleted, userState);
        }

        private void Onsave_subscriptionOperationCompleted(object arg)
        {
            if ((this.save_subscriptionCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.save_subscriptionCompleted(this, new save_subscriptionCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_SubscriptionListener_SoapBinding", Namespace = "urn:uddi-org:subr_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_SubscriptionListener_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback notify_subscriptionListenerOperationCompleted;

        /// <remarks/>
        public UDDI_SubscriptionListener_SoapBinding()
        {
            this.Url = "http://localhost/uddi/subscriptionlistener/";
        }

        /// <remarks/>
        public event notify_subscriptionListenerCompletedEventHandler notify_subscriptionListenerCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("notify_subscriptionListener", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("dispositionReport", Namespace = "urn:uddi-org:api_v3")]
        public dispositionReport notify_subscriptionListener([System.Xml.Serialization.XmlElementAttribute("notify_subscriptionListener", Namespace = "urn:uddi-org:subr_v3")] notify_subscriptionListener notify_subscriptionListener1)
        {
            object[] results = this.Invoke("notify_subscriptionListener", new object[] {
                    notify_subscriptionListener1});
            return ((dispositionReport)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginnotify_subscriptionListener(notify_subscriptionListener notify_subscriptionListener1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("notify_subscriptionListener", new object[] {
                    notify_subscriptionListener1}, callback, asyncState);
        }

        /// <remarks/>
        public dispositionReport Endnotify_subscriptionListener(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((dispositionReport)(results[0]));
        }

        /// <remarks/>
        public void notify_subscriptionListenerAsync(notify_subscriptionListener notify_subscriptionListener1)
        {
            this.notify_subscriptionListenerAsync(notify_subscriptionListener1, null);
        }

        /// <remarks/>
        public void notify_subscriptionListenerAsync(notify_subscriptionListener notify_subscriptionListener1, object userState)
        {
            if ((this.notify_subscriptionListenerOperationCompleted == null))
            {
                this.notify_subscriptionListenerOperationCompleted = new System.Threading.SendOrPostCallback(this.Onnotify_subscriptionListenerOperationCompleted);
            }
            this.InvokeAsync("notify_subscriptionListener", new object[] {
                    notify_subscriptionListener1}, this.notify_subscriptionListenerOperationCompleted, userState);
        }

        private void Onnotify_subscriptionListenerOperationCompleted(object arg)
        {
            if ((this.notify_subscriptionListenerCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.notify_subscriptionListenerCompleted(this, new notify_subscriptionListenerCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_ValueSetValidation_SoapBinding", Namespace = "urn:uddi-org:vs_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_ValueSetValidation_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback validate_valuesOperationCompleted;

        /// <remarks/>
        public UDDI_ValueSetValidation_SoapBinding()
        {
            this.Url = "http://localhost/uddi/valuesetvalidation/";
        }

        /// <remarks/>
        public event validate_valuesCompletedEventHandler validate_valuesCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("validate_values", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("dispositionReport", Namespace = "urn:uddi-org:api_v3")]
        public dispositionReport validate_values([System.Xml.Serialization.XmlElementAttribute("validate_values", Namespace = "urn:uddi-org:vs_v3")] validate_values validate_values1)
        {
            object[] results = this.Invoke("validate_values", new object[] {
                    validate_values1});
            return ((dispositionReport)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginvalidate_values(validate_values validate_values1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("validate_values", new object[] {
                    validate_values1}, callback, asyncState);
        }

        /// <remarks/>
        public dispositionReport Endvalidate_values(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((dispositionReport)(results[0]));
        }

        /// <remarks/>
        public void validate_valuesAsync(validate_values validate_values1)
        {
            this.validate_valuesAsync(validate_values1, null);
        }

        /// <remarks/>
        public void validate_valuesAsync(validate_values validate_values1, object userState)
        {
            if ((this.validate_valuesOperationCompleted == null))
            {
                this.validate_valuesOperationCompleted = new System.Threading.SendOrPostCallback(this.Onvalidate_valuesOperationCompleted);
            }
            this.InvokeAsync("validate_values", new object[] {
                    validate_values1}, this.validate_valuesOperationCompleted, userState);
        }

        private void Onvalidate_valuesOperationCompleted(object arg)
        {
            if ((this.validate_valuesCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.validate_valuesCompleted(this, new validate_valuesCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "UDDI_ValueSetCaching_SoapBinding", Namespace = "urn:uddi-org:vscache_v3_binding")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignaturePropertiesType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ManifestType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(UDDIinstanceParmsContainer_type))]
    public partial class UDDI_ValueSetCaching_SoapBinding : System.Web.Services.Protocols.SoapHttpClientProtocol
    {

        private System.Threading.SendOrPostCallback get_allValidValuesOperationCompleted;

        /// <remarks/>
        public UDDI_ValueSetCaching_SoapBinding()
        {
            this.Url = "http://localhost/uddi/valuesetcaching/";
        }

        /// <remarks/>
        public event get_allValidValuesCompletedEventHandler get_allValidValuesCompleted;

        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("get_allValidValues", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("validValuesList", Namespace = "urn:uddi-org:vscache_v3")]
        public validValuesList get_allValidValues([System.Xml.Serialization.XmlElementAttribute("get_allValidValues", Namespace = "urn:uddi-org:vscache_v3")] get_allValidValues get_allValidValues1)
        {
            object[] results = this.Invoke("get_allValidValues", new object[] {
                    get_allValidValues1});
            return ((validValuesList)(results[0]));
        }

        /// <remarks/>
        public System.IAsyncResult Beginget_allValidValues(get_allValidValues get_allValidValues1, System.AsyncCallback callback, object asyncState)
        {
            return this.BeginInvoke("get_allValidValues", new object[] {
                    get_allValidValues1}, callback, asyncState);
        }

        /// <remarks/>
        public validValuesList Endget_allValidValues(System.IAsyncResult asyncResult)
        {
            object[] results = this.EndInvoke(asyncResult);
            return ((validValuesList)(results[0]));
        }

        /// <remarks/>
        public void get_allValidValuesAsync(get_allValidValues get_allValidValues1)
        {
            this.get_allValidValuesAsync(get_allValidValues1, null);
        }

        /// <remarks/>
        public void get_allValidValuesAsync(get_allValidValues get_allValidValues1, object userState)
        {
            if ((this.get_allValidValuesOperationCompleted == null))
            {
                this.get_allValidValuesOperationCompleted = new System.Threading.SendOrPostCallback(this.Onget_allValidValuesOperationCompleted);
            }
            this.InvokeAsync("get_allValidValues", new object[] {
                    get_allValidValues1}, this.get_allValidValuesOperationCompleted, userState);
        }

        private void Onget_allValidValuesOperationCompleted(object arg)
        {
            if ((this.get_allValidValuesCompleted != null))
            {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.get_allValidValuesCompleted(this, new get_allValidValuesCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }

        /// <remarks/>
        public new void CancelAsync(object userState)
        {
            base.CancelAsync(userState);
        }
    }

}
