private void AddOnDispatchMethod(
            TypeBuilder classBuilder,
            InterfaceDescription interfaceDescription,
            MethodBodyTypesBuildResult methodBodyTypesBuildResult)
        {
            var dispatchMethodImpl = CodeBuilderUtils.CreateProtectedMethodBuilder(
                classBuilder,
                "OnDispatch",
                typeof(void),
                typeof(int),     // method id
                typeof(object),  // remote object
                typeof(object)); // message body

            var ilGen = dispatchMethodImpl.GetILGenerator();

            var castedObject = ilGen.DeclareLocal(interfaceDescription.InterfaceType);

            ilGen.Emit(OpCodes.Ldarg_2);             // load object
            ilGen.Emit(OpCodes.Castclass, interfaceDescription.InterfaceType);
            ilGen.Emit(OpCodes.Stloc, castedObject); // store casted result to local 0

            foreach (var methodDescription in interfaceDescription.Methods)
            {
                if (!TypeUtility.IsVoidType(methodDescription.ReturnType))
                {
                    continue;
                }

                var elseLable = ilGen.DefineLabel();

                this.AddIfMethodIdInvokeBlock(
                    ilGen: ilGen,
                    elseLabel: elseLable,
                    castedObject: castedObject,
                    methodDescription: methodDescription,
                    requestBodyType: methodBodyTypesBuildResult.MethodBodyTypesMap[methodDescription.Name]
                    .RequestBodyType);

                ilGen.MarkLabel(elseLable);
            }

            ilGen.ThrowException(typeof(MissingMethodException));
        }
        private void AddCreateResponseBodyMethod(
            TypeBuilder classBuilder,
            InterfaceDescription interfaceDescription,
            MethodBodyTypesBuildResult methodBodyTypesBuildResult)
        {
            var methodBuilder = CodeBuilderUtils.CreateProtectedMethodBuilder(
                classBuilder,
                "CreateResponseBody",
                typeof(object),  // responseBody - return value
                typeof(int),     // methodId
                typeof(object)); // retval from the invoked method on the remoted object

            var ilGen = methodBuilder.GetILGenerator();

            foreach (var methodDescription in interfaceDescription.Methods)
            {
                var methodBodyTypes = methodBodyTypesBuildResult.MethodBodyTypesMap[methodDescription.Name];
                if (methodBodyTypes.ResponseBodyType == null)
                {
                    continue;
                }

                var elseLabel = ilGen.DefineLabel();

                this.AddIfMethodIdCreateResponseBlock(
                    ilGen,
                    elseLabel,
                    methodDescription.Id,
                    methodBodyTypes.ResponseBodyType);

                ilGen.MarkLabel(elseLabel);
            }

            // return null; (if method id's do not match)
            ilGen.Emit(OpCodes.Ldnull);
            ilGen.Emit(OpCodes.Ret);
        }