private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, int depth) {
        if (resources.isEmpty())
            return block;

        // Add resource declaration or expression to block statements
        ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
        JCTree resource = resources.head;
        JCExpression expr = null;
        if (resource instanceof JCVariableDecl) {
            JCVariableDecl var = (JCVariableDecl) resource;
            expr = make.Ident(var.sym).setType(resource.type);
            stats.add(var);
        } else {
            Assert.check(resource instanceof JCExpression);
            VarSymbol syntheticTwrVar =
            new VarSymbol(SYNTHETIC | FINAL,
                          makeSyntheticName(names.fromString("twrVar" +
                                           depth), twrVars),
                          (resource.type.tag == TypeTags.BOT) ?
                          syms.autoCloseableType : resource.type,
                          currentMethodSym);
            twrVars.enter(syntheticTwrVar);
            JCVariableDecl syntheticTwrVarDecl =
                make.VarDef(syntheticTwrVar, (JCExpression)resource);
            expr = (JCExpression)make.Ident(syntheticTwrVar);
            stats.add(syntheticTwrVarDecl);
        }

        // Add primaryException declaration
        VarSymbol primaryException =
            new VarSymbol(SYNTHETIC,
                          makeSyntheticName(names.fromString("primaryException" +
                          depth), twrVars),
                          syms.throwableType,
                          currentMethodSym);
        twrVars.enter(primaryException);
        JCVariableDecl primaryExceptionTreeDecl = make.VarDef(primaryException, makeNull());
        stats.add(primaryExceptionTreeDecl);

        // Create catch clause that saves exception and then rethrows it
        VarSymbol param =
            new VarSymbol(FINAL|SYNTHETIC,
                          names.fromString("t" +
                                           target.syntheticNameChar()),
                          syms.throwableType,
                          currentMethodSym);
        JCVariableDecl paramTree = make.VarDef(param, null);
        JCStatement assign = make.Assignment(primaryException, make.Ident(param));
        JCStatement rethrowStat = make.Throw(make.Ident(param));
        JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
        JCCatch catchClause = make.Catch(paramTree, catchBlock);

        int oldPos = make.pos;
        make.at(TreeInfo.endPos(block));
        JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
        make.at(oldPos);
        JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
                                  List.<JCCatch>of(catchClause),
                                  finallyClause);
        stats.add(outerTry);
        return make.Block(0L, stats.toList());
    }