/// <summary>
        /// Adds the integration service generic method.
        /// </summary>
        /// <param name="assemblyCode">
        /// The assembly code.
        /// </param>
        /// <param name="process">
        /// The process.
        /// </param>
        /// <param name="service">
        /// The service.
        /// </param>
        /// <param name="method">
        /// The method.
        /// </param>
        private void AddIntegrationServiceGenericMethod(
            StringBuilder assemblyCode,
            IProcessDefinition process,
            IntegrationServiceDefinition service,
            IntegrationServiceMethodDefinition method)
        {
            var parametersString = new StringBuilder("Cebos.Veyron.SharedTypes.Integration.ActionType action");
            var callParametersString = new StringBuilder("action");
            
            if (method.Parameters.Any())
            {
                parametersString.AppendFormat(", {0}", GetMethodParameters(method));
                callParametersString.AppendFormat(", {0}", GetMethodCallParameters(method));
            }

            assemblyCode.AppendFormat(
                @"
        [System.Web.Services.WebMethodAttribute]
        [System.Web.Services.Protocols.SoapHeaderAttribute(""Credentials"")]
        {3}
        {4}
        public {5} @{0}({1})
        {{
            var result = {0}Internal({2});
",
                method.Name,
                parametersString,
                callParametersString,
                GetSoapDocumentMethodAttribute(method),
                GetSoapExtensionAttribute(process, service),
                GetIntegrationServiceMethodReturnType(method));

            AddIntegrationServiceMethodReturn(assemblyCode, method);

            assemblyCode.AppendFormat(@"
        }}
");
        }
 private static string GetSoapDocumentMethodAttribute(IntegrationServiceMethodDefinition method)
 {
     return string.Format(
         "[System.Web.Services.Protocols.SoapDocumentMethodAttribute(RequestNamespace = {0}, ResponseNamespace = {0})]",
         method.Namespace.ToLiteral());
 }
        private void AddIntegrationServiceMethodReturn(StringBuilder assemblyCode, IntegrationServiceMethodDefinition method)
        {
            if (string.IsNullOrEmpty(method.ResultType))
                return;

            assemblyCode.AppendFormat(@"
            if (result == null)
                return default({0});
", GetIntegrationServiceMethodReturnType(method));

            switch (method.ReturnMode)
            {
                case IntegrationServiceMethodReturnMode.First:
                    assemblyCode.AppendFormat(@"
            return result.Cast<{0}>().FirstOrDefault();", method.ResultType);
                    break;

                case IntegrationServiceMethodReturnMode.All:
                    assemblyCode.AppendFormat(@"
            return result.Cast<{0}>().ToArray();", method.ResultType);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        private string GetIntegrationServiceMethodReturnType(IntegrationServiceMethodDefinition method)
        {
            if (string.IsNullOrEmpty(method.ResultType))
                return "void";

            switch (method.ReturnMode)
            {
                case IntegrationServiceMethodReturnMode.First:
                    return method.ResultType;

                case IntegrationServiceMethodReturnMode.All:
                    return method.ResultType + "[]";

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        /// <summary>
        /// Adds the integration service internal method.
        /// </summary>
        /// <param name="assemblyCode">The assembly code.</param>
        /// <param name="method">The method.</param>
        private void AddIntegrationServiceInternalMethod(StringBuilder assemblyCode, IntegrationServiceMethodDefinition method)
        {
            var parametersString = new StringBuilder("Cebos.Veyron.SharedTypes.Integration.ActionType action");
            if (method.Parameters.Any())
                parametersString.AppendFormat(", {0}", GetMethodParameters(method));

            assemblyCode.AppendFormat(
                @"
        private System.Collections.IList {0}Internal({1})
        {{
            try
            {{
                CheckCredentials({2}, {3});

                var _root = new {0}Request();",
                method.Name,
                parametersString,
                method.Username.ToLiteral(),
                method.Password.ToLiteral());

            foreach (var parameter in method.Parameters)
            {
                assemblyCode.AppendFormat(@"
                _root.@{0} = @{0};", parameter.Name);
            }

            assemblyCode.AppendFormat(@"

                var dataContext = new Cebos.Veyron.SharedTypes.Integration.SourceData(_root);
                var serviceMethod = {0}Method;
                System.Collections.IList methodResult = null;

                switch (action)
                {{", method.Name);

            if (method.CanInsert)
                assemblyCode.AppendFormat(@"
                    case Cebos.Veyron.SharedTypes.Integration.ActionType.Insert:
                        methodResult = serviceMethod.Insert(dataContext);
                        break;
");

            if (method.CanUpdate)
                assemblyCode.AppendFormat(@"
                    case Cebos.Veyron.SharedTypes.Integration.ActionType.Update:
                        methodResult = serviceMethod.Update(dataContext);
                        break;
");

            if (method.CanInsertOrUpdate)
                assemblyCode.AppendFormat(@"
                    case Cebos.Veyron.SharedTypes.Integration.ActionType.InsertOrUpdate:
                        methodResult = serviceMethod.InsertOrUpdate(dataContext);
                        break;
");

            if (method.CanRemove)
                assemblyCode.AppendFormat(@"
                    case Cebos.Veyron.SharedTypes.Integration.ActionType.Remove:
                        methodResult = serviceMethod.Remove(dataContext);
                        break;
");

            if (method.CanSelect)
                assemblyCode.AppendFormat(@"
                    case Cebos.Veyron.SharedTypes.Integration.ActionType.Select:
                        methodResult = serviceMethod.SelectItems(dataContext);
                        break;
");

            assemblyCode.AppendFormat(@"
                    default:
                        throw new System.InvalidOperationException(""Invalid action."");
                }}

                return methodResult;
            }}
            catch (System.Exception _ex)
            {{
                Logger.Log(Cebos.Veyron.SharedTypes.Logging.LogSeverity.Error, ""Integration Service"", _ex);

                throw;
            }}
        }}");
        }
 /// <summary>
 /// Gets the method call parameters.
 /// </summary>
 /// <param name="method">The method.</param>
 /// <returns>System.String.</returns>
 private string GetMethodCallParameters(IntegrationServiceMethodDefinition method)
 {
     return string.Join(", ", method.Parameters.Select(p => "@" + p.Name));
 }
 /// <summary>
 /// Gets the method parameters.
 /// </summary>
 /// <param name="method">The method.</param>
 /// <returns>System.String.</returns>
 private string GetMethodParameters(IntegrationServiceMethodDefinition method)
 {
     return string.Join(", ", method.Parameters.Select(p => string.Format("{2} {0} @{1}", GetCSharpType(p), p.Name, GetXmlAttribute(p))));
 }
        private void AddMethodDefinition(StringBuilder assemblyCode, IProcessDefinition process, IntegrationServiceMethodDefinition method)
        {
            assemblyCode.AppendFormat(@"
        private static Cebos.Veyron.SharedTypes.Integration.IntegrationServiceMethodDefinition Get{0}Definition()
        {{
            var methodDefinition = new Cebos.Veyron.SharedTypes.Integration.IntegrationServiceMethodDefinition();
            methodDefinition.ProcessName = {1};
", method.Name, process.Name.ToLiteral());

            var parameterExpressionScripts = ExpressionService.PrepareScriptForMultipleDestinations(method.ParametersMapping, null);
            var variableCollection = new VariableCollection();

            foreach (var fieldMapping in method.DestinationFields)
            {
                var mappingVariable = AddFieldMapping(assemblyCode, fieldMapping, parameterExpressionScripts, variableCollection);
                assemblyCode.AppendFormat(@"
            methodDefinition.ParameterMappings.Add({0});
", mappingVariable.Name);
            }

            if (!string.IsNullOrEmpty(method.ResultType))
            {
                assemblyCode.AppendFormat(@"
            methodDefinition.ResultType = typeof(@{0});
", method.ResultType);
            }

            if (method.ResultMapping != null)
            {
                var resultExpressionScripts = ExpressionService.PrepareScriptForMultipleDestinations(method.ResultMappingExpression, null);
                var mappingVariable = AddFieldMapping(assemblyCode, method.ResultMapping, resultExpressionScripts, variableCollection);
                assemblyCode.AppendFormat(@"
            methodDefinition.ResultMapping = {0};
", mappingVariable.Name);
            }

            assemblyCode.AppendFormat(@"

            return methodDefinition;
        }}
");
        }
        /// <summary>
        /// Adds the type of the integration service method request.
        /// </summary>
        /// <param name="assemblyCode">The assembly code.</param>
        /// <param name="method">The method.</param>
        private void AddIntegrationServiceMethodRequestType(StringBuilder assemblyCode, IntegrationServiceMethodDefinition method)
        {
            assemblyCode.AppendFormat(@"
        private class {0}Request
        {{", method.Name);

            foreach (var parameter in method.Parameters)
            {
                assemblyCode.AppendFormat(@"
            public {0} @{1} {{ get; set; }}", GetCSharpType(parameter), parameter.Name);
            }

            assemblyCode.AppendFormat(@"
        }}
");
        }