private void BuildMethod(IndentBuilder classBuilder, MethodInfo method)
        {
            var isAsyncCall = typeof(Task).IsAssignableFrom(method.ReturnType);
            var returnType  = method.ReturnType;

            if (isAsyncCall && method.ReturnType.IsConstructedGenericType)
            {
                returnType = method.ReturnType.GetGenericArguments()[0];
            }

            var isVoid = returnType == typeof(void) || (isAsyncCall && !method.ReturnType.IsConstructedGenericType);

            // Write the method declaration

            classBuilder.Append("public ");
            if (isAsyncCall)
            {
                classBuilder.Append("async ");
                classBuilder.Append(typeof(Task).FullName);

                if (!isVoid)
                {
                    classBuilder.Append($"<{CompilerUtils.ToCompilableName(returnType)}>");
                }
            }
            else
            {
                classBuilder.Append(isVoid ? "void" : CompilerUtils.ToCompilableName(returnType));
            }

            var attribute = method.GetCustomAttribute <HttpMethodAttribute>();

            classBuilder.Append($" {method.Name}(");
            classBuilder.Append(string.Join(", ", method.GetParameters().Select(CompilerUtils.ToParameterDeclaration)));
            classBuilder.AppendLine(")");
            classBuilder.AppendLine("{");

            using (var methodBuilder = classBuilder.Indent())
            {
                methodBuilder.AppendLine(
                    "var 仮variables = new System.Collections.Generic.Dictionary<string,object>();");
                methodBuilder.AppendLine(
                    "var 仮reqParams = new System.Collections.Generic.Dictionary<string,string>();");

                var           contentHeaders  = new Dictionary <string, ParameterInfo>();
                var           requestHeaders  = new Dictionary <string, ParameterInfo>();
                var           responseHeaders = new Dictionary <string, ParameterInfo>();
                ParameterInfo bodyParam       = null;
                BodyAttribute bodyAttr        = null;

                foreach (var parameter in method.GetParameters())
                {
                    AttributeInterpreter.InterpretPathValue(parameter, methodBuilder);
                    AttributeInterpreter.InterpretRequestHeader(parameter, requestHeaders, contentHeaders);
                    AttributeInterpreter.InterpretBodyParameter(parameter, ref bodyParam, ref bodyAttr);
                    AttributeInterpreter.InterpretRequestParameter(parameter, methodBuilder);
                    AttributeInterpreter.InterpretResponseHeaderInParameters(parameter, isAsyncCall,
                                                                             ref responseHeaders);
                }

                methodBuilder.AppendLine(
                    $"var 仮request = CreateRequest({CompilerUtils.ToCompilableName(attribute.Method)}, \"{attribute.Path}\", 仮variables, 仮reqParams);");
                var hasContent = AttributeInterpreter.CreateContentObjectIfSpecified(bodyAttr, bodyParam, methodBuilder);

                foreach (var entry in requestHeaders)
                {
                    methodBuilder.AppendLine(
                        $"仮request.Headers.Add(\"{entry.Key}\", {entry.Value.Name}{(entry.Value.ParameterType.IsClass ? "?" : "")}.ToString());");
                }

                if (hasContent)
                {
                    // when setting content we can apply the contentHeaders
                    foreach (var entry in contentHeaders)
                    {
                        methodBuilder.AppendLine(
                            $"仮content.Headers.Add(\"{entry.Key}\", {entry.Value.Name}{(entry.Value.ParameterType.IsClass ? "?" : "")}.ToString());");
                    }

                    methodBuilder.AppendLine("仮request.Content = 仮content;");
                }

                methodBuilder.AppendLine(isAsyncCall
                    ? "var 仮response = await InvokeAsync(仮request);"
                    : "var 仮response = Invoke(仮request);");

                foreach (var entry in responseHeaders)
                {
                    methodBuilder.AppendLine(
                        $"{entry.Value.Name} = GetHeaderValue<{CompilerUtils.ToCompilableName(entry.Value.ParameterType)}>(仮response, \"{entry.Key}\");");
                }

                if (!isVoid)
                {
                    var returnBodyAttribute     = method.ReturnParameter?.GetCustomAttribute <BodyAttribute>();
                    var returnResponseAttribute = method.ReturnParameter?.GetCustomAttribute <ResponseHeaderAttribute>();

                    if (returnResponseAttribute != null && returnBodyAttribute != null)
                    {
                        throw new WebServiceCompileException(
                                  $"Cannot have different types of response attributes.  You had [{string.Join(", ", "Body", "ResponseHeader")}]");
                    }

                    if (returnResponseAttribute != null)
                    {
                        AttributeInterpreter.ReturnResponseHeader(returnResponseAttribute, returnType, methodBuilder);
                    }
                    else
                    {
                        if (returnBodyAttribute == null)
                        {
                            returnBodyAttribute = new BodyAttribute();
                        }

                        AttributeInterpreter.ReturnContentObject(returnBodyAttribute, returnType, isAsyncCall,
                                                                 methodBuilder);
                    }
                }
            }

            classBuilder.AppendLine("}");
        }
        private void BuildMethod(IndentBuilder classBuilder, MethodInfo method, string hystrixCommandName)
        {
            var isAsyncCall = typeof(Task).IsAssignableFrom(method.ReturnType);
            var returnType  = method.ReturnType;

            if (isAsyncCall && method.ReturnType.IsConstructedGenericType)
            {
                returnType = method.ReturnType.GetGenericArguments()[0];
            }

            var isVoid = returnType == typeof(void) || (isAsyncCall && !method.ReturnType.IsConstructedGenericType);

            // Write the method declaration

            classBuilder.Append("public ");
            if (isAsyncCall)
            {
                classBuilder.Append("async ");
                classBuilder.Append(typeof(Task).FullName);

                if (!isVoid)
                {
                    classBuilder.Append($"<{CompilerUtils.ToCompilableName(returnType)}>");
                }
            }
            else
            {
                classBuilder.Append(isVoid ? "void" : CompilerUtils.ToCompilableName(returnType));
            }

            classBuilder.Append($" {method.Name}(");
            classBuilder.Append(string.Join(", ", method.GetParameters().Select(CompilerUtils.ToParameterDeclaration)));
            classBuilder.AppendLine(")");
            classBuilder.AppendLine("{");
            using (var methodBuilder = classBuilder.Indent())
            {
                methodBuilder.Append($"var 仮command = new {hystrixCommandName}(this, 仮fallback, ");

                foreach (var inParam in method.GetParameters().Where(p => !p.IsOut))
                {
                    methodBuilder.Append($"{CompilerUtils.ToParameterUsage(inParam)}, ");
                }

                methodBuilder.AppendLine(" 仮logger);");

                methodBuilder.Append(isVoid ? string.Empty : "var 仮value = ");
                methodBuilder.AppendLine(isAsyncCall
                    ? "await 仮command.ExecuteAsync();"
                    : "仮command.Execute();");

                foreach (var outParam in method.GetParameters().Where(p => p.IsOut))
                {
                    methodBuilder.AppendLine($"{outParam.Name} = 仮command.{outParam.Name};");
                }

                if (!isVoid)
                {
                    methodBuilder.AppendLine("return 仮value;");
                }
            }

            classBuilder.AppendLine("}");
        }