private void GenerateAsyncOperation(TypeBuilder typeBuilder, MethodInfo methodInfo, string serviceContractNamespace)
        {
            if (IsAsyncOperation(methodInfo))
            {
                // Don't generate Async version of operation contracts that already return a "Task".
                // Otherwise something like "Task<int> GetFooAsync()" would be complemented by
                // "Task<Task<int>> GetFooAsyncAsync()" - pointless.
                return;
            }

            var parameters              = methodInfo.GetParameters();
            var parameterTypes          = parameters.Select(p => p.ParameterType).ToArray();
            var requiredCustomModifiers = parameters.Select(p => p.GetRequiredCustomModifiers()).ToArray();
            var optionalCustomModifiers = parameters.Select(p => p.GetOptionalCustomModifiers()).ToArray();

            Type[] returnTypeRequiredCustomModifiers = Type.EmptyTypes;
            Type[] returnTypeOptionalCustomModifiers = Type.EmptyTypes;
            if (methodInfo.ReturnParameter != null)
            {
                returnTypeRequiredCustomModifiers = methodInfo.ReturnParameter.GetRequiredCustomModifiers();
                returnTypeOptionalCustomModifiers = methodInfo.ReturnParameter.GetOptionalCustomModifiers();
            }

            var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name + "Async",
                                                         GeneratorHelpers.GetInterfaceMethodAttributes(), CallingConventions.Standard,
                                                         methodInfo.ReturnType == typeof(void) ? typeof(Task) : typeof(Task <>).MakeGenericType(methodInfo.ReturnType),
                                                         returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
                                                         parameterTypes, requiredCustomModifiers, optionalCustomModifiers);

            for (var i = 0; i < parameters.Length; ++i)
            {
                var parameter        = parameters[i];
                var parameterBuilder = methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name);
                if (((int)parameter.Attributes & (int)ParameterAttributes.HasDefault) != 0)
                {
                    parameterBuilder.SetConstant(parameter.RawDefaultValue);
                }

                foreach (var attribute in parameter.BuildCustomAttributes())
                {
                    parameterBuilder.SetCustomAttribute(attribute);
                }
            }

            bool isOneWay = IsOnewayOperation(methodInfo);

            foreach (var attribute in methodInfo.BuildCustomAttributes(serviceContractNamespace, isOneWay))
            {
                methodBuilder.SetCustomAttribute(attribute);
            }
        }