public MemberDeclarationSyntax MakeProxy(TypeDefinition type)
        {
            var classDecl = ClassDeclaration(_names.MakeTypeName(type, NameUsage.Proxy).Identifier)
                            .AddModifiers(Public)
                            .AddBaseListTypes(
                SimpleBaseType(Type <Capnp.Rpc.Proxy>()),
                SimpleBaseType(_names.MakeGenericTypeName(type, NameUsage.Interface)));

            if (type.GenericParameters.Count > 0)
            {
                classDecl = classDecl
                            .AddTypeParameterListParameters(MakeTypeParameters(type).ToArray())
                            .AddConstraintClauses(MakeTypeParameterConstraints(type).ToArray());
            }

            var allMethods =
                from c in Types.FromDefinition(type).AllImplementedClasses
                from m in c.Definition.Methods
                select m;

            foreach (var method in allMethods)
            {
                var bodyStmts = new List <StatementSyntax>();

                bodyStmts.Add(LocalDeclarationStatement(
                                  VariableDeclaration(
                                      IdentifierName("var"))
                                  .WithVariables(
                                      SingletonSeparatedList(
                                          VariableDeclarator(
                                              _names.ParamsLocal.Identifier)
                                          .WithInitializer(
                                              EqualsValueClause(
                                                  InvocationExpression(
                                                      MemberAccessExpression(
                                                          SyntaxKind.SimpleMemberAccessExpression,
                                                          IdentifierName(nameof(Capnp.SerializerState)),
                                                          GenericName(
                                                              Identifier(nameof(Capnp.SerializerState.CreateForRpc)))
                                                          .WithTypeArgumentList(
                                                              TypeArgumentList(
                                                                  SingletonSeparatedList(
                                                                      _names.MakeTypeSyntax(
                                                                          method.ParamsStruct,
                                                                          method.ParamsStruct.Definition,
                                                                          TypeUsage.Writer))))))))))));

                if (method.ParamsStruct.Definition.SpecialName == SpecialName.MethodParamsStruct)
                {
                    bodyStmts.Add(LocalDeclarationStatement(
                                      VariableDeclaration(
                                          IdentifierName("var"))
                                      .WithVariables(
                                          SingletonSeparatedList <VariableDeclaratorSyntax>(
                                              VariableDeclarator(
                                                  _names.AnonymousParameter.Identifier)
                                              .WithInitializer(
                                                  EqualsValueClause(
                                                      ObjectCreationExpression(
                                                          _names.MakeTypeSyntax(
                                                              method.ParamsStruct,
                                                              method.ParamsStruct.Definition,
                                                              TypeUsage.DomainClass))
                                                      .WithArgumentList(
                                                          ArgumentList())
                                                      .WithInitializer(
                                                          InitializerExpression(
                                                              SyntaxKind.ObjectInitializerExpression,
                                                              SeparatedList <ExpressionSyntax>(
                                                                  CommonSnippetGen.MakeCommaSeparatedList(
                                                                      MakeProxyCallInitializerAssignments(method)).ToArray())))))))));
                }

                bodyStmts.Add(ExpressionStatement(
                                  InvocationExpression(
                                      MemberAccessExpression(
                                          SyntaxKind.SimpleMemberAccessExpression,
                                          _names.AnonymousParameter.IdentifierName,
                                          _names.SerializeMethod.IdentifierName))
                                  .AddArgumentListArguments(
                                      Argument(_names.ParamsLocal.IdentifierName))));

                var call = InvocationExpression(IdentifierName(nameof(Capnp.Rpc.BareProxy.Call)))
                           .AddArgumentListArguments(
                    Argument(
                        LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                          Literal(method.DeclaringInterface.Id))),
                    Argument(
                        LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(method.Id))),
                    Argument(
                        InvocationExpression(
                            MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                _names.ParamsLocal.IdentifierName,
                                GenericName(nameof(Capnp.SerializerState.Rewrap))
                                .AddTypeArgumentListArguments(Type <Capnp.DynamicSerializerState>())))
                        .AddArgumentListArguments()),
                    Argument(
                        LiteralExpression(SyntaxKind.FalseLiteralExpression)),
                    Argument(
                        _names.CancellationTokenParameter.IdentifierName));

                MethodDeclarationSyntax methodDecl;

                if (IsSubjectToPipelining(method))
                {
                    methodDecl = MethodDeclaration(
                        TransformReturnType(method),
                        _names.GetCodeIdentifier(method).Identifier)
                                 .AddParameterListParameters(TransformParameters(method))
                                 .AddModifiers(Public);

                    var pipelineAwareCall = InvocationExpression(
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            IdentifierName(nameof(Capnp.Rpc.Impatient)),
                            IdentifierName(nameof(Capnp.Rpc.Impatient.MakePipelineAware))))
                                            .AddArgumentListArguments(
                        Argument(call),
                        Argument(SimpleLambdaExpression(
                                     Parameter(_names.DeserializerLocal.Identifier),
                                     Block(
                                         MakeProxyCreateResult(method),
                                         MakeProxyReturnResult(method)))));

                    bodyStmts.Add(ReturnStatement(pipelineAwareCall));
                }
                else
                {
                    methodDecl = MethodDeclaration(
                        TransformReturnType(method),
                        _names.GetCodeIdentifier(method).Identifier)
                                 .AddParameterListParameters(TransformParameters(method))
                                 .AddModifiers(Public, Token(SyntaxKind.AsyncKeyword));

                    var whenReturned = MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        call,
                        IdentifierName(nameof(Capnp.Rpc.IPromisedAnswer.WhenReturned)));

                    var assignAwaited = LocalDeclarationStatement(
                        VariableDeclaration(
                            IdentifierName("var"))
                        .AddVariables(
                            VariableDeclarator(
                                _names.DeserializerLocal.Identifier)
                            .WithInitializer(
                                EqualsValueClause(
                                    AwaitExpression(whenReturned)))));

                    bodyStmts.Add(assignAwaited);
                    bodyStmts.Add(MakeProxyCreateResult(method));
                    bodyStmts.Add(MakeProxyReturnResult(method));
                }

                if (method.GenericParameters.Count > 0)
                {
                    methodDecl = methodDecl
                                 .AddTypeParameterListParameters(MakeTypeParameters(method).ToArray())
                                 .AddConstraintClauses(MakeTypeParameterConstraints(method).ToArray());
                }

                methodDecl = methodDecl.AddBodyStatements(bodyStmts.ToArray());

                classDecl = classDecl.AddMembers(methodDecl);
            }

            return(classDecl);
        }