private static void ImplementGetter(TypeBuilder typeBuilder, ExpressionPropertyBuilder builder, PropertyInfo property)
        {
            if (TinyProtocol.Check(property.PropertyType).CanBuildProxy())
            {
                var field = typeBuilder.DefineField("<prx>_" + property.Name, property.PropertyType, FieldAttributes.Private);
                builder.ImplementGetter(
                    Expression.Coalesce(
                        builder.This.MemberField(field),
                        Expression.Assign(
                            builder.This.MemberField(field),
                            builder.This.CallMember(CreateMemberProxy.MakeGenericMethod(property.PropertyType), Expression.Constant(property.Name)))));
                return;
            }

            bool isSerializable = TinyProtocol.Check(property.PropertyType).CanDeserialize();
            var  dict           = Expression.Parameter(typeof(IDictionary <string, string>));
            var  block          = new List <Expression>();

            block.Add(Expression.Assign(dict, builder.This.CallMember(CreateQuery)));
            if (isSerializable)
            {
                block.Add(Wait(builder.This.CallMember(ExecuteQueryRet.MakeGenericMethod(property.PropertyType), Expression.Constant(property.Name), dict)));
            }
            else
            {
                block.Add(Expression.Throw(Expression.New(typeof(Exception).GetConstructor(new [] { typeof(string) }), Expression.Constant("incompatible return type"))));
                block.Add(Expression.Default(property.PropertyType));
            }

            builder.ImplementGetter(
                Expression.Block(
                    property.PropertyType,
                    new[] { dict },
                    block));
        }
        private static void ImplementSetter(ExpressionPropertyBuilder builder, PropertyInfo property)
        {
            var dict  = Expression.Parameter(typeof(IDictionary <string, string>));
            var block = new List <Expression>();

            block.Add(Expression.Assign(dict, builder.This.CallMember(CreateQuery)));
            block.Add(dict.CallMember(AddParameter, Expression.Constant("value"), builder.Value.Serialize(builder.This.MemberField(typeof(ProxyBase).GetField("Endpoint", BindingFlags.Instance | BindingFlags.NonPublic)))));
            if (TinyProtocol.Check(property.PropertyType).CanSerialize())
            {
                block.Add(Wait(builder.This.CallMember(ExecuteQuery, Expression.Constant(property.Name), dict)));
            }
            else
            {
                block.Add(Expression.Throw(Expression.New(typeof(Exception).GetConstructor(new[] { typeof(string) }), Expression.Constant("incompatible return type"))));
                block.Add(Expression.Default(property.PropertyType));
            }

            builder.ImplementSetter(
                Expression.Block(
                    typeof(void),
                    new[] { dict },
                    block));
        }