public static Expression Bind(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression, ParameterExpression zone, ParameterExpression theCopy)
        {
            var builder = new PropertiesToCopyExpressionBinder(codeGenerationContext, expression.Type, zone, theCopy);

            builder.Visit(expression);

            return builder.statements.ToStatementisedGroupedExpression();
        }
        public static Expression Bind(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression, ParameterExpression zone, ParameterExpression theCopy)
        {
            var builder = new PropertiesToCopyExpressionBinder(codeGenerationContext, expression.Type, zone, theCopy);

            builder.Visit(expression);

            return(builder.statements.ToStatementisedGroupedExpression());
        }
        private Expression CreateCopyWithZoneMethod(TypeDefinitionExpression expression)
        {
            var currentType = (FickleType)expression.Type;
            var zone        = FickleExpression.Parameter("NSZone", "zone");
            var self        = Expression.Parameter(currentType, "self");
            var theCopy     = Expression.Variable(expression.Type, "theCopy");

            Expression newExpression;

            if (expression.Type.BaseType == typeof(object))
            {
                newExpression = FickleExpression.Call(FickleExpression.Call(FickleExpression.Call(self, "Class", "class", null), "allocWithZone", zone), expression.Type, "init", null);
            }
            else
            {
                var super = FickleExpression.Variable(expression.Type.BaseType.Name, "super");

                newExpression = FickleExpression.Call(super, FickleType.Define("id"), "copyWithZone", zone);
            }

            var initTheCopy     = Expression.Assign(theCopy, newExpression).ToStatement();
            var returnStatement = Expression.Return(Expression.Label(), theCopy).ToStatement();
            var copyStatements  = PropertiesToCopyExpressionBinder.Bind(codeGenerationContext, expression, zone, theCopy);

            Expression methodBody = Expression.Block
                                    (
                new[] { theCopy },
                initTheCopy,
                FickleExpression.GroupedWide
                (
                    copyStatements,
                    returnStatement
                )
                                    );

            return(new MethodDefinitionExpression("copyWithZone", new Expression[] { zone }.ToReadOnlyCollection(), typeof(object), methodBody, false, null));
        }