internal void WriteGetPropertyValueMethod(System.Reflection.Emit.ILGenerator il)
        {
            var helper = new Helper.ILEmitter(this.GetType(), this, il);

            helper.DeclareLocal(typeof(bool));
            helper.DeclareLocal(typeof(bool));
            helper.DeclareLocal(typeof(object));


            //bool flag = string.IsNullOrWhiteSpace(property);
            //if (flag)
            //{
            //    throw new EmptyOrNullPropertyNameException(base.GetType(), property);
            //}

            helper.Nop();
            helper.Ldarg1();
            helper.Call(typeof(string).GetMethod("IsNullOrWhiteSpace"));
            //helper.Stloc0();
            //helper.Ldloc0();

            var label = helper.DefineLabel();

            helper.BrFalse(label);

            Label endlabel = helper.DefineLabel();


            helper.Nop();
            helper.Ldarg0();
            helper.Call(typeof(object), "GetType");
            helper.Ldarg1();
            helper.Newobj(typeof(Exceptions.EmptyOrNullPropertyNameException), typeof(Type), typeof(string));
            helper.Throw();

            helper.MarkLabel(label);

            var mcallStringEquals = typeof(string).GetMethod("Equals", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
                                                             null, new[] { typeof(string), typeof(string) }, null);

            var propertiesToImplement = Properties.Where(w => w.PropertyGetter != null).ToArray();

            var pLabel = helper.DefineLabel();

            foreach (var p in propertiesToImplement)
            {
                helper.MarkLabel(pLabel);
                pLabel = helper.DefineLabel();

                helper.Ldarg1();
                helper.LdStr(p.Name);
                helper.Call(mcallStringEquals);
                //helper.Stloc1();
                //helper.Ldloc1();
                helper.BrFalse(pLabel);

                helper.Nop();
                helper.Ldarg0();
                helper.Call(p.PropertyGetter);
                if (p.Type.IsValueType)
                {
                    helper.Box(p.Type);
                }
                //helper.Stloc2();
                helper.Br(endlabel);
            }

            helper.MarkLabel(pLabel);


            helper.Nop();
            helper.Ldarg0();
            helper.Callorvirt(typeof(object), "GetType");
            helper.Ldarg1();
            helper.Newobj(typeof(Exceptions.PropertyNotFoundException), typeof(Type), typeof(string));
            helper.Throw();


            helper.MarkLabel(endlabel);
            helper.Ret();
        }
        internal void WriteSetPropertyValueMethod(System.Reflection.Emit.ILGenerator il)
        {
            var allProperties = Properties.Where(w => w.PropertySetter != null).ToArray();

            var helper = new Helper.ILEmitter(this.GetType(), this.TypeBuilder, il);

            il.DeclareLocal(typeof(bool));

            for (int i = 0; i < allProperties.Length; i++)
            {
                il.DeclareLocal(typeof(bool));
            }


            helper.Nop();
            helper.Ldarg1();
            helper.Call(typeof(string), "IsNullOrWhiteSpace", typeof(string));

            var label = helper.DefineLabel();

            helper.BrFalse(label);

            var endlabel = helper.DefineLabel();


            helper.Nop();
            helper.Ldarg0();
            helper.Call(typeof(object), "GetType");
            helper.Ldarg1();
            helper.Newobj(typeof(Exceptions.EmptyOrNullPropertyNameException), typeof(Type), typeof(string));
            helper.Throw();

            helper.MarkLabel(label);


            var mcallStringEquals = typeof(string).GetMethod("Equals", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
                                                             null, new[] { typeof(string), typeof(string) }, null);


            var plabel = helper.DefineLabel();


            foreach (var p in allProperties)
            {
                helper.MarkLabel(plabel);
                plabel = helper.DefineLabel();

                helper.Ldarg1();
                helper.LdStr(p.Name);
                helper.Call(mcallStringEquals);
                helper.BrFalse(plabel);

                helper.Nop();
                helper.Ldarg0();
                helper.Ldarg2();
                helper.CastOrUnBox(p.Type);
                helper.Call(p.PropertySetter);
                helper.Nop();
                helper.Nop();
                helper.Br(endlabel);
            }

            helper.MarkLabel(plabel);

            helper.Nop();
            helper.Ldarg0();
            helper.Call(typeof(object), "GetType");
            helper.Ldarg1();
            helper.Newobj(typeof(Exceptions.PropertyNotFoundException), typeof(Type), typeof(string));
            helper.Throw();


            helper.MarkLabel(endlabel);
            helper.Ret();
        }