/// <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
			var 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;
				}
			}

			var 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());
		}
		protected void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor,
		                                   ProxyConstructorImplementation impl, params FieldReference[] fields)
		{
            if (impl == ProxyConstructorImplementation.SkipConstructor)
                return;

			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, paramInfo.DefaultValue);
				}
			}
			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 (last.ParameterType.IsArray && last.HasAttribute<ParamArrayAttribute>())
				{
					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 (impl == ProxyConstructorImplementation.CallBase)
            {
                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());
		}