private void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor, params FieldReference[] fields)
		{
			ArgumentReference[] args;
			ParameterInfo[] baseConstructorParams = null;

			if (baseConstructor != null)
			{
				baseConstructorParams = baseConstructor.GetParameters();
			}

			if (baseConstructorParams != null && baseConstructorParams.Length != 0)
			{
				args = new ArgumentReference[fields.Length + baseConstructorParams.Length];

				int offset = fields.Length;

				for (int i = offset; i < offset + baseConstructorParams.Length; i++)
				{
					ParameterInfo paramInfo = baseConstructorParams[i - offset];
					args[i] = new ArgumentReference(paramInfo.ParameterType);
				}
			}
			else
			{
				args = new ArgumentReference[fields.Length];
			}

			for (int i = 0; i < fields.Length; i++)
			{
				args[i] = new ArgumentReference(fields[i].Reference.FieldType);
			}

			ConstructorEmitter constructor = emitter.CreateConstructor(args);

			for (int i = 0; i < fields.Length; i++)
			{
				constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression()));
			}

			// Invoke base constructor

			if (baseConstructor != null)
			{
				Debug.Assert(baseConstructorParams != null);

				var slice = new ArgumentReference[baseConstructorParams.Length];
				Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length);

				constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice);
			}
			else
			{
				constructor.CodeBuilder.InvokeBaseConstructor();
			}

			constructor.CodeBuilder.AddStatement(new ReturnStatement());
		}
		/// <summary>
		/// Generates a parameters constructor that initializes the proxy
		/// state with <see cref="StandardInterceptor"/> just to make it non-null.
		/// <para>
		/// This constructor is important to allow proxies to be XML serializable
		/// </para>
		/// </summary>
		protected void GenerateParameterlessConstructor(ClassEmitter emitter, Type baseClass, FieldReference interceptorField)
		{
			// Check if the type actually has a default constructor
			ConstructorInfo defaultConstructor = baseClass.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);

			if (defaultConstructor == null)
			{
				defaultConstructor = baseClass.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);

				if (defaultConstructor == null || defaultConstructor.IsPrivate)
				{
					return;
				}
			}

			ConstructorEmitter constructor = emitter.CreateConstructor();

			// initialize fields with an empty interceptor

			constructor.CodeBuilder.AddStatement(new AssignStatement(interceptorField,
			                                                         new NewArrayExpression(1, typeof (IInterceptor))));
			constructor.CodeBuilder.AddStatement(
				new AssignArrayStatement(interceptorField, 0, new NewInstanceExpression(typeof(StandardInterceptor), new Type[0])));

			// Invoke base constructor

			constructor.CodeBuilder.InvokeBaseConstructor(defaultConstructor);

			constructor.CodeBuilder.AddStatement(new ReturnStatement());
		}
		public void NoCustomCtorForInterfaces()
		{
			DisableVerification();
			ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes,
				TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false);
			emitter.CreateConstructor();
		}
		protected void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor,
		                                   params FieldReference[] fields)
		{
			ArgumentReference[] args;
			ParameterInfo[] baseConstructorParams = null;

			if (baseConstructor != null)
			{
				baseConstructorParams = baseConstructor.GetParameters();
			}

			if (baseConstructorParams != null && baseConstructorParams.Length != 0)
			{
				args = new ArgumentReference[fields.Length + baseConstructorParams.Length];

				var offset = fields.Length;
				for (var i = offset; i < offset + baseConstructorParams.Length; i++)
				{
					var paramInfo = baseConstructorParams[i - offset];
					args[i] = new ArgumentReference(paramInfo.ParameterType);
				}
			}
			else
			{
				args = new ArgumentReference[fields.Length];
			}

			for (var i = 0; i < fields.Length; i++)
			{
				args[i] = new ArgumentReference(fields[i].Reference.FieldType);
			}

			var constructor = emitter.CreateConstructor(args);
			if (baseConstructorParams != null && baseConstructorParams.Length != 0)
			{
				var last = baseConstructorParams.Last();

#if !NETFX_CORE
				if (last.ParameterType.IsArray && last.HasAttribute<ParamArrayAttribute>())
#else
				if (last.ParameterType.IsArray && ParameterInfoExtender.HasAttribute<ParamArrayAttribute>(last))
#endif
				{
					var parameter = constructor.ConstructorBuilder.DefineParameter(args.Length, ParameterAttributes.None, last.Name);
					var builder = AttributeUtil.CreateBuilder<ParamArrayAttribute>();
					parameter.SetCustomAttribute(builder);
				}
			}

			for (var i = 0; i < fields.Length; i++)
			{
				constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression()));
			}

			// Invoke base constructor

			if (baseConstructor != null)
			{
				Debug.Assert(baseConstructorParams != null);

				var slice = new ArgumentReference[baseConstructorParams.Length];
				Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length);

				constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice);
			}
			else
			{
				constructor.CodeBuilder.InvokeBaseConstructor();
			}

			constructor.CodeBuilder.AddStatement(new ReturnStatement());
		}
		private void GenerateSerializationConstructor(ClassEmitter emitter)
		{
			var serializationInfo = new ArgumentReference(typeof(SerializationInfo));
			var streamingContext = new ArgumentReference(typeof(StreamingContext));

			var ctor = emitter.CreateConstructor(serializationInfo, streamingContext);

			ctor.CodeBuilder.AddStatement(
				new ConstructorInvocationStatement(serializationConstructor,
				                                   serializationInfo.ToExpression(),
				                                   streamingContext.ToExpression()));

			foreach (var field in serializedFields)
			{
				var getValue = new MethodInvocationExpression(serializationInfo,
				                                              SerializationInfoMethods.GetValue,
				                                              new ConstReference(field.Reference.Name).ToExpression(),
				                                              new TypeTokenExpression(field.Reference.FieldType));
				ctor.CodeBuilder.AddStatement(new AssignStatement(
				                              	field,
				                              	new ConvertExpression(field.Reference.FieldType,
				                              	                      typeof(object),
				                              	                      getValue)));
			}
			ctor.CodeBuilder.AddStatement(new ReturnStatement());
		}
		/// <summary>
		/// Builds the adapter.
		/// </summary>
		/// <returns></returns>
		public Type Build()
		{

			//Setup emitter 
			ClassEmitter classEmitter = new ClassEmitter(ModuleScope,
				OriginalObject.Name + "Adapter",
				typeof(AdapterBase),
				new Type[] { }, TypeAttributes.Class,
				true);

			//Add a field to hold a reference to the original object that is being adapter.
			FieldReference adaptedObjectReference = classEmitter.CreateField("_Original", OriginalObject);

			//Add a constructor that accepts a reference to the original object and
			//assigns that reference to the field.
			ArgumentReference parameter = new ArgumentReference(OriginalObject);
			ConstructorEmitter constructor = classEmitter.CreateConstructor(parameter);
			constructor.CodeBuilder.AddStatement(
				new AssignStatement(adaptedObjectReference, new ReferenceExpression(parameter)));
			constructor.CodeBuilder.AddStatement(new ReturnStatement());

			//For each method, walk the pipeline
			foreach (MethodInfo method in OriginalObject.GetMethods())
			{
				AdapterBuilderStageContext context =
					new AdapterBuilderStageContext(OriginalObject, classEmitter, adaptedObjectReference, method);
				WalkPipeline(context);
			}

			//build the type			
			return classEmitter.BuildType();

		}
        protected void GenerateSerializationConstructor(ClassEmitter emitter, FieldReference interceptorField,
		                                                bool delegateToBaseGetObjectData)
        {
            ArgumentReference arg1 = new ArgumentReference(typeof(SerializationInfo));
            ArgumentReference arg2 = new ArgumentReference(typeof(StreamingContext));

            ConstructorEmitter constr = emitter.CreateConstructor(arg1, arg2);

            constr.CodeBuilder.AddStatement(
                new ConstructorInvocationStatement(serializationConstructor,
                                                   arg1.ToExpression(), arg2.ToExpression()));

            Type[] object_arg = new Type[] {typeof(String), typeof(Type)};
            MethodInfo getValueMethod = typeof(SerializationInfo).GetMethod("GetValue", object_arg);

            MethodInvocationExpression getInterceptorInvocation =
                new MethodInvocationExpression(arg1, getValueMethod,
                                               new ConstReference("__interceptors").ToExpression(),
                                               new TypeTokenExpression(typeof(IInterceptor[])));

            constr.CodeBuilder.AddStatement(new AssignStatement(
                                                interceptorField,
                                                new ConvertExpression(typeof(IInterceptor[]), typeof(object),
                                                                      getInterceptorInvocation)));

            constr.CodeBuilder.AddStatement(new ReturnStatement());
        }