public static Type GetContractType(OperationInfo operationInfo, ReceiveActivity contextActivity)
        {
            if (operationInfo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo");
            }

            if (contextActivity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contextActivity");
            }

            if (string.IsNullOrEmpty(operationInfo.ContractName))
            {
                return null;
            }

            Activity rootActivity = contextActivity.RootActivity;
            Dictionary<string, ContractType> contractTypes =
                rootActivity.GetValue(DynamicContractTypeBuilder.DynamicContractTypesProperty) as Dictionary<string, ContractType>;

            if (contractTypes == null)
            {
                Activity definition = rootActivity.GetValue(Activity.WorkflowDefinitionProperty) as Activity;
                if (definition != null)
                {
                    contractTypes = definition.GetValue(DynamicContractTypeBuilder.DynamicContractTypesProperty) as Dictionary<string, ContractType>;
                }

                if (contractTypes != null)
                {
                    rootActivity.SetValue(DynamicContractTypeBuilder.DynamicContractTypesProperty, contractTypes);
                }
            }

            if (contractTypes == null)
            {
                contractTypes = BuildContractTypes(rootActivity);
                rootActivity.SetValue(DynamicContractTypeBuilder.DynamicContractTypesProperty, contractTypes);
            }

            if (contractTypes.ContainsKey(operationInfo.ContractName))
            {
                return contractTypes[operationInfo.ContractName];
            }

            return null;
        }
        internal ContractMethodInfo(ContractType declaringType, OperationInfo operationInfo)
        {
            if (declaringType == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("declaringType");
            }
            if (operationInfo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo");
            }
            if (string.IsNullOrEmpty(operationInfo.Name))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("operationInfo",
                    SR2.GetString(SR2.Error_OperationNameNotSpecified));
            }

            this.declaringType = declaringType;
            this.name = operationInfo.Name;
            this.methodAttributes = MethodAttributes.Public |
                MethodAttributes.Abstract |
                MethodAttributes.Virtual;

            SortedList<int, ContractMethodParameterInfo> localParameters =
                new SortedList<int, ContractMethodParameterInfo>();

            foreach (OperationParameterInfo operationParameterInfo in operationInfo.Parameters)
            {
                ContractMethodParameterInfo parameterInfo =
                    new ContractMethodParameterInfo(this, operationParameterInfo);
                if (parameterInfo.Position == -1)
                {
                    this.returnParam = parameterInfo;
                }
                else
                {
                    localParameters.Add(parameterInfo.Position, parameterInfo);
                }
            }

            this.parameters = new ParameterInfo[localParameters.Count];
            foreach (ContractMethodParameterInfo paramInfo in localParameters.Values)
            {
                this.parameters[paramInfo.Position] = paramInfo;
            }

            if (this.returnParam == null)
            {
                OperationParameterInfo returnParameterInfo = new OperationParameterInfo();
                returnParameterInfo.Position = -1;
                returnParameterInfo.ParameterType = typeof(void);

                this.returnParam = new ContractMethodParameterInfo(this, returnParameterInfo);
            }

            OperationContractAttribute operationContract = new OperationContractAttribute();
            if (operationInfo.HasProtectionLevel && operationInfo.ProtectionLevel != null)
            {
                operationContract.ProtectionLevel = (ProtectionLevel) operationInfo.ProtectionLevel;
            }
            operationContract.IsOneWay = operationInfo.IsOneWay;

            this.attributes = new Attribute[] { operationContract };

            declaringType.AddMethod(this);
        }
        static Dictionary <string, ContractType> BuildContractTypes(Activity contextActivity)
        {
            if (contextActivity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contextActivity");
            }

            Dictionary <string, ContractType> types = new Dictionary <string, ContractType>();

            Walker walker = new Walker(true);

            walker.FoundActivity += delegate(Walker w, WalkerEventArgs args)
            {
                ReceiveActivity currentActivity = args.CurrentActivity as ReceiveActivity;
                if (currentActivity == null)
                {
                    return;
                }
                OperationInfo operationInfo = currentActivity.ServiceOperationInfo as OperationInfo;
                if (operationInfo == null)
                {
                    return;
                }

                if (string.IsNullOrEmpty(operationInfo.ContractName) ||
                    string.IsNullOrEmpty(operationInfo.Name))
                {
                    return;
                }

                if (!types.ContainsKey(operationInfo.ContractName))
                {
                    types.Add(operationInfo.ContractName,
                              new ContractType(operationInfo.ContractName));
                }

                bool       hasReturnValue      = false;
                bool       duplicatedPositions = false;
                int        maxPosition         = -1;
                List <int> parameterIndexs     = new List <int>();

                foreach (OperationParameterInfo operationParameterInfo in operationInfo.Parameters)
                {
                    if (operationParameterInfo.Position == -1)
                    {
                        hasReturnValue = true;
                    }
                    else
                    {
                        maxPosition = (maxPosition < operationParameterInfo.Position) ? operationParameterInfo.Position : maxPosition;
                    }

                    if (parameterIndexs.Contains(operationParameterInfo.Position))
                    {
                        duplicatedPositions = true;
                        break;
                    }
                    else
                    {
                        parameterIndexs.Add(operationParameterInfo.Position);
                    }
                }

                if (duplicatedPositions ||
                    maxPosition > (operationInfo.Parameters.Count - (hasReturnValue ? 2 : 1)))
                {
                    return;
                }

                ContractType       contract   = types[operationInfo.ContractName];
                ContractMethodInfo methodInfo = new ContractMethodInfo(contract, operationInfo);
            };

            walker.Walk(contextActivity);

            return(types);
        }
        internal ContractMethodInfo(ContractType declaringType, OperationInfo operationInfo)
        {
            if (declaringType == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("declaringType");
            }
            if (operationInfo == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo");
            }
            if (string.IsNullOrEmpty(operationInfo.Name))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("operationInfo",
                                                                             SR2.GetString(SR2.Error_OperationNameNotSpecified));
            }

            this.declaringType    = declaringType;
            this.name             = operationInfo.Name;
            this.methodAttributes = MethodAttributes.Public |
                                    MethodAttributes.Abstract |
                                    MethodAttributes.Virtual;

            SortedList <int, ContractMethodParameterInfo> localParameters =
                new SortedList <int, ContractMethodParameterInfo>();

            foreach (OperationParameterInfo operationParameterInfo in operationInfo.Parameters)
            {
                ContractMethodParameterInfo parameterInfo =
                    new ContractMethodParameterInfo(this, operationParameterInfo);
                if (parameterInfo.Position == -1)
                {
                    this.returnParam = parameterInfo;
                }
                else
                {
                    localParameters.Add(parameterInfo.Position, parameterInfo);
                }
            }

            this.parameters = new ParameterInfo[localParameters.Count];
            foreach (ContractMethodParameterInfo paramInfo in localParameters.Values)
            {
                this.parameters[paramInfo.Position] = paramInfo;
            }

            if (this.returnParam == null)
            {
                OperationParameterInfo returnParameterInfo = new OperationParameterInfo();
                returnParameterInfo.Position      = -1;
                returnParameterInfo.ParameterType = typeof(void);

                this.returnParam = new ContractMethodParameterInfo(this, returnParameterInfo);
            }

            OperationContractAttribute operationContract = new OperationContractAttribute();

            if (operationInfo.HasProtectionLevel && operationInfo.ProtectionLevel != null)
            {
                operationContract.ProtectionLevel = (ProtectionLevel)operationInfo.ProtectionLevel;
            }
            operationContract.IsOneWay = operationInfo.IsOneWay;

            this.attributes = new Attribute[] { operationContract };

            declaringType.AddMethod(this);
        }