Represents a type that can create methods.
        /// <summary>
        /// Adds a GetServiceHashCode method to a target type.
        /// </summary>
        /// <param name="targetType">The target type.</param>
        /// <param name="shouldBeVisible">A boolean flag that indicates whether or not the method should be public.</param>
        /// <returns>The GetServiceHashCode method.</returns>
        public MethodDefinition AddGetServiceHashMethodTo(TypeDefinition targetType, bool shouldBeVisible)
        {
            var options = new MethodBuilderOptions();
            DefineOptions(targetType, shouldBeVisible, options);

            var module = targetType.Module;

            var methodBuilder = new MethodBuilder();
            var method = methodBuilder.CreateMethod(options);

            var body = method.Body;
            var il = body.GetILProcessor ();

            var getHashCodeMethod = module.ImportMethod<object>("GetHashCode");

            var hashVariable = EmitGetServiceTypeHashCode(module, body, il, getHashCodeMethod);

            // Calculate the hash code for the service name
            // if it isn't null
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ceq);

            var skipNameHash = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Brtrue, skipNameHash);

            EmitGetServiceNameHashCode(il, getHashCodeMethod, hashVariable);

            il.Append(skipNameHash);
            il.Emit(OpCodes.Ldloc, hashVariable);
            il.Emit(OpCodes.Ret);

            return method;
        }
        /// <summary>
        /// Adds a method override for a particular <paramref name="targetMethod"/>.
        /// </summary>
        /// <param name="targetMethod">The target method.</param>
        /// <param name="hostType">The type that will host the new method.</param>
        /// <returns>The overridden method.</returns>
        public MethodDefinition AddOverrideFor(MethodInfo targetMethod, TypeDefinition hostType)
        {
            var module = hostType.Module;
            var options = new MethodBuilderOptions();

            options.IsPublic = true;
            options.MethodName = targetMethod.Name;

            var parameterTypes = new List<System.Type>();
            foreach (var param in targetMethod.GetParameters())
            {
                parameterTypes.Add(param.ParameterType);
            }

            options.HostType = hostType;
            options.SetMethodParameters(parameterTypes.ToArray());
            options.ReturnType = targetMethod.ReturnType;

            var builder = new MethodBuilder();
            return builder.CreateMethod(options);
        }