File: System\Workflow\Activities\SendActivity.cs
Project: ndp\cdf\src\NetFx35\System.WorkflowServices\System.WorkflowServices.csproj (System.WorkflowServices)
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
 
#pragma warning disable 1634, 1691
namespace System.Workflow.Activities
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Drawing;
    using System.Globalization;
    using System.Reflection;
    using System.Runtime;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Compiler;
    using System.Workflow.ComponentModel.Design;
    using System.Workflow.Runtime.Hosting;
 
    [SR2Description(SR2DescriptionAttribute.SendActivityDescription)]
    [SR2Category(SR2CategoryAttribute.Standard)]
    [DesignerAttribute(typeof(SendActivityDesigner), typeof(IDesigner))]
    [ToolboxBitmap(typeof(SendActivity), "Design.Resources.SendActivity.png")]
    [ActivityValidator(typeof(SendActivityValidator))]
    [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
    public sealed class SendActivity : Activity
    {
        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
        public static readonly DependencyProperty AfterResponseEvent =
            DependencyProperty.Register("AfterResponse",
            typeof(EventHandler<SendActivityEventArgs>),
            typeof(SendActivity));
 
        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
        public static readonly DependencyProperty BeforeSendEvent =
            DependencyProperty.Register("BeforeSend",
            typeof(EventHandler<SendActivityEventArgs>),
            typeof(SendActivity));
 
        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
        public static readonly DependencyProperty CustomAddressProperty =
            DependencyProperty.Register("CustomAddress",
            typeof(string),
            typeof(SendActivity),
            new PropertyMetadata(null));
 
        public const string ReturnValuePropertyName = "(ReturnValue)";
 
        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
        internal static readonly DependencyProperty ChannelTokenProperty =
            DependencyProperty.Register("ChannelToken",
            typeof(ChannelToken),
            typeof(SendActivity),
            new PropertyMetadata(null, DependencyPropertyOptions.Metadata));
 
        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
        internal static readonly DependencyProperty ParameterBindingsProperty =
            DependencyProperty.Register("ParameterBindings",
            typeof(WorkflowParameterBindingCollection),
            typeof(SendActivity),
            new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly));
 
        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
        internal static readonly DependencyProperty ServiceOperationInfoProperty =
            DependencyProperty.Register("ServiceOperationInfo",
            typeof(TypedOperationInfo),
            typeof(SendActivity),
            new PropertyMetadata(DependencyPropertyOptions.Metadata));
 
        [NonSerialized]
        private SendOperationInfoHelper operationHelper;
 
        public SendActivity()
        {
            base.SetReadOnlyPropertyValue(SendActivity.ParameterBindingsProperty,
                new WorkflowParameterBindingCollection(this));
        }
 
        public SendActivity(String name)
            : base(name)
        {
            base.SetReadOnlyPropertyValue(SendActivity.ParameterBindingsProperty,
                new WorkflowParameterBindingCollection(this));
        }
 
        [SuppressMessage("Microsoft.Naming", "CA1713:EventsShouldNotHaveBeforeOrAfterPrefix")]
        [Browsable(true)]
        [SR2Category(SR2CategoryAttribute.Handlers)]
        [SR2Description(SR2DescriptionAttribute.Send_AfterResponse_Description)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public event EventHandler<SendActivityEventArgs> AfterResponse
        {
            add
            {
                base.AddHandler(SendActivity.AfterResponseEvent, value);
            }
            remove
            {
                base.RemoveHandler(SendActivity.AfterResponseEvent, value);
            }
        }
 
        [SuppressMessage("Microsoft.Naming", "CA1713:EventsShouldNotHaveBeforeOrAfterPrefix")]
        [Browsable(true)]
        [SR2Category(SR2CategoryAttribute.Handlers)]
        [SR2Description(SR2DescriptionAttribute.Send_BeforeSend_Description)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public event EventHandler<SendActivityEventArgs> BeforeSend
        {
            add
            {
                base.AddHandler(SendActivity.BeforeSendEvent, value);
            }
            remove
            {
                base.RemoveHandler(SendActivity.BeforeSendEvent, value);
            }
        }
 
        [DefaultValue(null)]
        [MergableProperty(false)]
        [RefreshProperties(RefreshProperties.All)]
        [SR2Category(SR2CategoryAttribute.Activity)]
        [SR2Description(SR2DescriptionAttribute.Send_ChannelToken_Description)]
        public ChannelToken ChannelToken
        {
            get
            {
                return (ChannelToken) this.GetValue(SendActivity.ChannelTokenProperty);
            }
            set
            {
                this.SetValue(SendActivity.ChannelTokenProperty, value);
            }
        }
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IDictionary<string, string> Context
        {
            get
            {
                if (this.ServiceOperationInfo == null)
                {
#pragma warning suppress 56503
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name)));
                }
 
                return SendActivity.GetContext(this, this.ChannelToken, this.ServiceOperationInfo.ContractType);
            }
            set
            {
                if (this.ServiceOperationInfo == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name)));
                }
 
                SendActivity.SetContext(this, this.ChannelToken, this.ServiceOperationInfo.ContractType, value);
            }
        }
 
        [DefaultValue(null)]
        [SR2Category(SR2CategoryAttribute.Activity)]
        [SR2Description(SR2DescriptionAttribute.Send_CustomAddress_Description)]
        public string CustomAddress
        {
            get
            {
                return (string) GetValue(CustomAddressProperty);
            }
 
            set
            {
                SetValue(CustomAddressProperty, value);
            }
        }
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public WorkflowParameterBindingCollection ParameterBindings
        {
            get
            {
                return ((WorkflowParameterBindingCollection)(base.GetValue(SendActivity.ParameterBindingsProperty)));
            }
        }
 
        [Browsable(true)]
        [SR2Category(SR2CategoryAttribute.Activity)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [SR2Description(SR2DescriptionAttribute.Send_OperationInfo_Description)]
        public TypedOperationInfo ServiceOperationInfo
        {
            get
            {
                return ((TypedOperationInfo)(base.GetValue(SendActivity.ServiceOperationInfoProperty)));
            }
            set
            {
                OperationInfoBase currentValue = ((OperationInfoBase)(base.GetValue(SendActivity.ServiceOperationInfoProperty)));
                if (value != null && currentValue != value)
                {
                    DependencyProperty ParentDependencyObjectProperty =
                        DependencyProperty.FromName("ParentDependencyObject", typeof(DependencyObject));
 
                    Activity currentParent = value.GetValue(ParentDependencyObjectProperty) as Activity;
 
                    if (currentParent != null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(
                            "value",
                            SR2.GetString(SR2.Error_OperationIsAlreadyAssociatedWithActivity,
                            value,
                            currentParent.QualifiedName));
                    }
 
                    if (currentValue != null)
                    {
                        currentValue.SetValue(ParentDependencyObjectProperty, null);
                    }
 
                    value.SetValue(ParentDependencyObjectProperty, this);
                }
 
                if (this.DesignMode)
                {
                    Activity rootActivity = this.RootActivity;
                    rootActivity.RemoveProperty(DynamicContractTypeBuilder.DynamicContractTypesProperty);
                }
 
                base.SetValue(SendActivity.ServiceOperationInfoProperty, value);
            }
        }
 
        SendOperationInfoHelper OperationHelper
        {
            get
            {
                if (this.operationHelper == null)
                {
                    if (this.UserData.Contains(typeof(SendOperationInfoHelper)))
                    {
                        this.operationHelper = this.UserData[typeof(SendOperationInfoHelper)] as SendOperationInfoHelper;
                    }
                }
 
                if (this.operationHelper == null)
                {
                    this.operationHelper = new SendOperationInfoHelper(this.Site, this);
                    this.UserData[typeof(SendOperationInfoHelper)] = this.operationHelper;
                }
 
                return this.operationHelper;
            }
        }
 
        public static IDictionary<string, string> GetContext(Activity activity,
            ChannelToken endpoint,
            Type contractType)
        {
            if (activity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
            }
            if (endpoint == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
            }
            if (contractType == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType");
            }
 
            return GetContext(activity, endpoint.Name, endpoint.OwnerActivityName, contractType);
        }
 
        public static IDictionary<string, string> GetContext(Activity activity,
            string endpointName,
            string ownerActivityName,
            Type contractType)
        {
            if (activity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
            }
            if (string.IsNullOrEmpty(endpointName))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("endpointName",
                    SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString));
            }
            if (contractType == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType");
            }
 
            LogicalChannel logicalChannel = ChannelToken.GetLogicalChannel(activity, endpointName, ownerActivityName, contractType);
            if (logicalChannel != null)
            {
                return logicalChannel.Context;
            }
 
            return null;
        }
 
        public static void SetContext(Activity activity,
            ChannelToken endpoint,
            Type contractType,
            IDictionary<string, string> context)
        {
            if (activity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
            }
            if (endpoint == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
            }
            if (contractType == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType");
            }
 
            SetContext(activity, endpoint.Name, endpoint.OwnerActivityName, contractType, context);
        }
 
        public static void SetContext(Activity activity,
            string endpointName,
            string ownerActivityName,
            Type contractType,
            IDictionary<string, string> context)
        {
            if (activity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
            }
            if (string.IsNullOrEmpty(endpointName))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("endpointName",
                    SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString));
            }
            if (contractType == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType");
            }
 
            LogicalChannel logicalChannel = ChannelToken.GetLogicalChannel(activity, endpointName, ownerActivityName, contractType);
            if (logicalChannel != null)
            {
                if (context != null)
                {
                    logicalChannel.Context = context;
                }
                else
                {
                    logicalChannel.Context = ContextMessageProperty.Empty.Context;
                }
            }
        }
 
        protected internal override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            TypedOperationInfo serviceOperationInfo = this.ServiceOperationInfo;
            if (serviceOperationInfo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name)));
            }
 
            MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(executionContext);
            if (methodInfo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR2.GetString(SR2.Error_MethodInfoNotAvailable, this.Name)));
            }
 
            ChannelToken channelToken = this.ChannelToken;
 
            LogicalChannel logicalChannel = ChannelToken.Register(this, channelToken, serviceOperationInfo.ContractType);
            if (!logicalChannel.Initialized)
            {
                logicalChannel.Initialize(channelToken.EndpointName, this.CustomAddress);
            }
 
            using (ChannelManagerService.ChannelTicket leasedChannel = ChannelManagerService.Take(executionContext, this.WorkflowInstanceId, logicalChannel))
            {
                using (OperationContextScope scope = new OperationContextScope((IContextChannel) leasedChannel.Channel))
                {
                    EventHandler<SendActivityEventArgs>[] invocationList = this.GetInvocationList<EventHandler<SendActivityEventArgs>>(SendActivity.BeforeSendEvent);
                    if (invocationList != null && invocationList.Length > 0)
                    {
                        base.RaiseGenericEvent(SendActivity.BeforeSendEvent, this, new SendActivityEventArgs(this));
                    }
 
                    SendOperationInfoHelper helper = this.OperationHelper;
                    WorkflowParameterBindingCollection bindings = this.ParameterBindings;
 
                    object[] parameters = helper.GetInputs(this, bindings);
                    object returnValue = null;
 
                    bool isSessionless = ChannelManagerHelpers.IsSessionlessContract(logicalChannel.ContractType);
                    bool hasContext = (logicalChannel.Context != null && logicalChannel.Context.Count > 0);
                    bool fatalException = false;
 
                    if (!isSessionless && hasContext)
                    {
                        ChannelManagerService.ApplyLogicalChannelContext(logicalChannel);
                    }
 
                    try
                    {
                        returnValue = this.InvokeOperation(methodInfo, leasedChannel.Channel, parameters);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            fatalException = true;
                        }
                        throw;
                    }
                    finally
                    {
                        if (!fatalException &&
                            !hasContext && !isSessionless && !helper.IsOneWay)
                        {
                            ChannelManagerService.UpdateLogicalChannelContext(logicalChannel);
                        }
                    }
 
                    helper.PopulateOutputs(this, bindings, parameters, returnValue);
 
                    invocationList = this.GetInvocationList<EventHandler<SendActivityEventArgs>>(SendActivity.AfterResponseEvent);
                    if (invocationList != null && invocationList.Length > 0)
                    {
                        base.RaiseGenericEvent(SendActivity.AfterResponseEvent, this, new SendActivityEventArgs(this));
                    }
                }
            }
 
            return ActivityExecutionStatus.Closed;
        }
 
        internal void GetParameterPropertyDescriptors(IDictionary properties)
        {
            if (properties == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties");
            }
 
            if (((IComponent) this).Site == null)
            {
                return;
            }
 
            TypedOperationInfo serviceOperationInfo = this.ServiceOperationInfo;
            if (serviceOperationInfo != null)
            {
                MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(((IComponent) this).Site);
                if (methodInfo != null)
                {
                    ArrayList paramInfo = new ArrayList(methodInfo.GetParameters());
                    if (!(methodInfo.ReturnType == typeof(void)))
                    {
                        paramInfo.Add(methodInfo.ReturnParameter);
                    }
 
                    foreach (ParameterInfo param in paramInfo)
                    {
                        if (param.ParameterType != null)
                        {
                            PropertyDescriptor prop =
                                new ParameterInfoBasedPropertyDescriptor(typeof(ReceiveActivity),
                                param, true, DesignOnlyAttribute.Yes);
 
                            properties[prop.Name] = prop;
                        }
                    }
                }
            }
        }
 
        protected override void InitializeProperties()
        {
            TypedOperationInfo serviceOperationInfo = this.ServiceOperationInfo;
 
            if (serviceOperationInfo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name)));
            }
 
            OperationParameterInfoCollection parameters = null;
 
            Activity definitionRoot = base.RootActivity.GetValue(Activity.WorkflowDefinitionProperty) as Activity;
            if (definitionRoot != null)
            {
                SendActivity definition = definitionRoot.GetActivityByName(this.QualifiedName, true) as SendActivity;
                if ((definition != null) && definition.UserData.Contains(typeof(OperationParameterInfoCollection)))
                {
                    parameters = definition.UserData[typeof(OperationParameterInfoCollection)] as OperationParameterInfoCollection;
                }
            }
 
            if (parameters == null)
            {
                parameters = serviceOperationInfo.GetParameters(this.Site);
                this.UserData[typeof(OperationParameterInfoCollection)] = parameters;
            }
 
            WorkflowParameterBindingCollection parameterBindings = this.ParameterBindings;
 
            foreach (OperationParameterInfo parameterInfo in parameters)
            {
                if (!parameterBindings.Contains(parameterInfo.Name))
                {
                    parameterBindings.Add(new WorkflowParameterBinding(parameterInfo.Name));
                }
            }
 
            base.InitializeProperties();
        }
 
        object InvokeOperation(MethodInfo operation, IChannel channel, object[] parameters)
        {
            Guid workflowInstanceId = this.WorkflowInstanceId;
            string qualifiedName = this.QualifiedName;
 
            System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0,
                "Workflow Instance {0}, send activity {1} - invoking operation",
                workflowInstanceId, qualifiedName);
 
            try
            {
                object retVal = operation.ReflectedType.InvokeMember(operation.Name,
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
                    null,
                    channel,
                    parameters,
                    CultureInfo.InvariantCulture);
 
                System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0,
                    "Workflow Instance {0}, send activity {1} - operation invoke succeeded",
                    workflowInstanceId, qualifiedName);
 
                return retVal;
 
            }
            catch (TargetInvocationException e)
            {
                if (e.InnerException != null)
                {
                    System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0,
                        "Workflow Instance {0}, send activity {1} - operation invoke failed with error: {2}",
                        workflowInstanceId, qualifiedName, e.InnerException.Message);
 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.InnerException);
                }
                else
                {
                    System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0,
                        "Workflow Instance {0}, send activity {1} - operation invoke failed with error: {2}",
                        workflowInstanceId, qualifiedName, e.Message);
 
                    throw;
                }
            }
        }
 
        [Serializable]
        class SendOperationInfoHelper
        {
            bool hasReturnValue = false;
            IList<KeyValuePair<int, string>> inputParameters;
            bool isOneWay = false;
            string operationName;
            IList<KeyValuePair<int, string>> outputParameters;
            int parameterCount = 0;
 
            public SendOperationInfoHelper(IServiceProvider serviceProvider, SendActivity activity)
            {
                outputParameters = new List<KeyValuePair<int, string>>();
                inputParameters = new List<KeyValuePair<int, string>>();
                hasReturnValue = false;
 
                if (activity == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
                }
 
                OperationInfoBase serviceOperationInfo = activity.ServiceOperationInfo;
                if (serviceOperationInfo == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, activity.Name)));
                }
 
                MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(serviceProvider);
                if (methodInfo == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new InvalidOperationException(SR2.GetString(SR2.Error_MethodInfoNotAvailable, activity.Name)));
                }
 
                if (methodInfo.ReturnType != null && methodInfo.ReturnType != typeof(void))
                {
                    hasReturnValue = true;
                }
 
                foreach (ParameterInfo parameter in methodInfo.GetParameters())
                {
                    if (parameter.ParameterType.IsByRef ||
                        parameter.IsOut || (parameter.IsIn && parameter.IsOut))
                    {
                        outputParameters.Add(new KeyValuePair<int, string>(parameter.Position, parameter.Name));
                    }
 
                    if (!parameter.IsOut || (parameter.IsIn && parameter.IsOut))
                    {
                        inputParameters.Add(new KeyValuePair<int, string>(parameter.Position, parameter.Name));
                    }
                }
 
                this.parameterCount = methodInfo.GetParameters().Length;
 
                this.operationName = serviceOperationInfo.Name;
 
                object[] operationContractAttribs = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true);
 
                if (operationContractAttribs != null && operationContractAttribs.Length > 0)
                {
                    if (operationContractAttribs[0] is OperationContractAttribute)
                    {
                        this.isOneWay = ((OperationContractAttribute) operationContractAttribs[0]).IsOneWay;
                    }
                }
            }
 
            public bool IsOneWay
            {
                get
                {
                    return this.isOneWay;
                }
            }
 
            public object[] GetInputs(SendActivity activity, WorkflowParameterBindingCollection bindings)
            {
                if (activity == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
                }
 
                object[] inputs = new object[this.parameterCount];
 
                if (inputParameters.Count > 0)
                {
                    for (int index = 0; index < inputParameters.Count; index++)
                    {
                        KeyValuePair<int, string> parameterInfo = inputParameters[index];
 
                        if (bindings.Contains(parameterInfo.Value))
                        {
                            inputs[parameterInfo.Key] = bindings[parameterInfo.Value].Value;
                        }
                        else
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                new InvalidOperationException(SR2.GetString(SR2.Error_ParameterBindingMissing,
                                parameterInfo.Value,
                                this.operationName,
                                activity.Name)));
                        }
                    }
                }
 
                return inputs;
            }
 
            public void PopulateOutputs(SendActivity activity, WorkflowParameterBindingCollection bindings, object[] outputs, object returnValue)
            {
                if (activity == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity");
                }
 
                if (outputs == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("outputs");
                }
 
                if (this.outputParameters.Count > 0 && outputs.Length > 0)
                {
                    for (int index = 0; index < outputParameters.Count; ++index)
                    {
                        KeyValuePair<int, string> parameterInfo = outputParameters[index];
                        if (bindings.Contains(parameterInfo.Value))
                        {
                            bindings[parameterInfo.Value].Value = outputs[parameterInfo.Key];
                        }
                        else
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                new InvalidOperationException(SR2.GetString(SR2.Error_ParameterBindingMissing,
                                parameterInfo.Value, this.operationName, activity.Name)));
                        }
                    }
                }
 
                if (hasReturnValue)
                {
                    if (bindings.Contains(SendActivity.ReturnValuePropertyName))
                    {
                        bindings[SendActivity.ReturnValuePropertyName].Value = returnValue;
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new InvalidOperationException(SR2.GetString(SR2.Error_ParameterBindingMissing,
                            SendActivity.ReturnValuePropertyName,
                            this.operationName,
                            activity.Name)));
                    }
                }
            }
        }
    }
}