private Expression RewriteFaultHandler(TryExpression node)
        {
            //
            // 0. Recurse into the children.
            //
            var body  = Visit(node.Body);
            var fault = Visit(node.Fault);

            //
            // 1. Initialize rewriter.
            //
            var rewriter = new HandlerRewriter();

            //
            // 2. Rewrite body and handler.
            //
            var rewrittenTry          = rewriter.Rewrite(body)();
            var rewrittenTryHandler   = Expression.Lambda <Func <LeaveHandlerData> >(rewrittenTry);
            var rewrittenFaultHandler = Expression.Lambda <Action>(fault);

            //
            // 3. Emit call to TryFault helper.
            //
            var tryFault = Expression.Call(s_tryFault, rewrittenTryHandler, rewrittenFaultHandler);

            //
            // 4. Create resulting expression.
            //
            return(CreateRewrittenTry(node, rewriter, tryFault));
        }
        private Expression RewriteFilterHandler(TryExpression node)
        {
            if (node.Handlers.Count == 1 && node.Finally == null)
            {
                //
                // 0. Recurse into the children.
                //
                var body    = Visit(node.Body);
                var handler = VisitCatchBlock(node.Handlers[0]);

                //
                // 1. Initialize rewriter.
                //
                var rewriter = new HandlerRewriter();

                //
                // 2. Obtain rewriters for the body and the handler.
                //
                var bodyRewriter  = rewriter.Rewrite(body);
                var catchRewriter = rewriter.Rewrite(handler.Body); // TODO: verify we can't jump out of the filter

                //
                // 3. Rewrite body, handler, and filter.
                //
                var rewrittenTry           = bodyRewriter();
                var rewrittenTryHandler    = Expression.Lambda <Func <LeaveHandlerData> >(rewrittenTry);
                var rewrittenCatch         = catchRewriter();
                var rewrittenCatchHandler  = Expression.Lambda(rewrittenCatch, handler.Variable);
                var rewrittenFilterHandler = Expression.Lambda(handler.Filter, handler.Variable);

                //
                // 4. Emit call to TryFilter helper.
                //
                var tryFilter = Expression.Call(s_tryFilter.MakeGenericMethod(handler.Test), rewrittenTryHandler, rewrittenFilterHandler, rewrittenCatchHandler);

                //
                // 4. Create resulting expression.
                //
                return(CreateRewrittenTry(node, rewriter, tryFilter));
            }
            else
            {
                return(Visit(Expand(node)));
            }
        }
        private Expression RewriteFilterHandler(TryExpression node)
        {
            if (node.Handlers.Count == 1 && node.Finally == null)
            {
                //
                // 0. Recurse into the children.
                //
                var body = Visit(node.Body);
                var handler = VisitCatchBlock(node.Handlers[0]);

                //
                // 1. Initialize rewriter.
                //
                var rewriter = new HandlerRewriter();

                //
                // 2. Obtain rewriters for the body and the handler.
                //
                var bodyRewriter = rewriter.Rewrite(body);
                var catchRewriter = rewriter.Rewrite(handler.Body); // TODO: verify we can't jump out of the filter

                //
                // 3. Rewrite body, handler, and filter.
                //
                var rewrittenTry = bodyRewriter();
                var rewrittenTryHandler = Expression.Lambda<Func<LeaveHandlerData>>(rewrittenTry);
                var rewrittenCatch = catchRewriter();
                var rewrittenCatchHandler = Expression.Lambda(rewrittenCatch, handler.Variable);
                var rewrittenFilterHandler = Expression.Lambda(handler.Filter, handler.Variable);

                //
                // 4. Emit call to TryFilter helper.
                //
                var tryFilter = Expression.Call(s_tryFilter.MakeGenericMethod(handler.Test), rewrittenTryHandler, rewrittenFilterHandler, rewrittenCatchHandler);

                //
                // 4. Create resulting expression.
                //
                return CreateRewrittenTry(node, rewriter, tryFilter);
            }
            else
            {
                return Visit(Expand(node));
            }
        }
        private Expression RewriteFaultHandler(TryExpression node)
        {
            //
            // 0. Recurse into the children.
            //
            var body = Visit(node.Body);
            var fault = Visit(node.Fault);

            //
            // 1. Initialize rewriter.
            //
            var rewriter = new HandlerRewriter();

            //
            // 2. Rewrite body and handler.
            //
            var rewrittenTry = rewriter.Rewrite(body)();
            var rewrittenTryHandler = Expression.Lambda<Func<LeaveHandlerData>>(rewrittenTry);
            var rewrittenFaultHandler = Expression.Lambda<Action>(fault);

            //
            // 3. Emit call to TryFault helper.
            //
            var tryFault = Expression.Call(s_tryFault, rewrittenTryHandler, rewrittenFaultHandler);

            //
            // 4. Create resulting expression.
            //
            return CreateRewrittenTry(node, rewriter, tryFault);
        }