// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/Applicable.java
// public enum Applicable {
//     TEST_METHOD, FIXTURE_METHOD, REGULAR_METHOD, FIELD_FEATURE;
// 
//     @Component
//     static class ApplicableInjector {
//         @Autowired private FeatureProvider featureProvider;
// 
//         @PostConstruct
//         public void init() {
//             stream(Applicable.values()).forEach(applicable -> applicable.featureProvider = featureProvider);
//         }
//     }
// 
//     private FeatureProvider featureProvider;
// 
//     public void applyFeaturesToStatements(List<Object> statements) {
//         List<Feature> features = features();
//         for (int i = 0; i < statements.size(); i++) {
//             Object bodyNode = statements.get(i);
//             statements.remove(i);
//             for (Feature testMethodFeature : features) {
//                 bodyNode = testMethodFeature.apply(bodyNode);
//             }
//             statements.add(i, bodyNode);
//         }
//     }
// 
//     public List<Feature> features() {
//         return featureProvider.features(this);
//     }
// }
// 
// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/util/StringUtil.java
// public static final String SEPARATOR = System.getProperty("line.separator");
// 
// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/util/StringUtil.java
// public static String indentation(int indentationInTabs) {
//     return IntStream.rangeClosed(1, indentationInTabs).mapToObj(__ -> "\t").reduce("", (a, b) ->  a + b);
// }


import com.github.opaluchlukasz.junit2spock.core.Applicable;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TryStatement;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import static com.github.opaluchlukasz.junit2spock.core.util.StringUtil.SEPARATOR;
import static com.github.opaluchlukasz.junit2spock.core.util.StringUtil.indentation;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toCollection;
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("try {").append(SEPARATOR);
        body.forEach(printStatement(stringBuilder));
        stringBuilder.append(indentation(indentationLevel() + 1)).append("}");
        catchClauses.forEach(printStatement(stringBuilder));
        finallyBody.ifPresent(stmts -> {
            stringBuilder.append(" finally {").append(SEPARATOR);
            stmts.forEach(printStatement(stringBuilder));
            stringBuilder.append(indentation(indentationLevel() + 1)).append("}");
        });

        return stringBuilder.append(SEPARATOR).toString();
    }

    private static class CatchClauseWrapper extends BaseWrapper {
        private final LinkedList body = new LinkedList();
        private final SingleVariableDeclaration exception;

        CatchClauseWrapper(CatchClause catchClause, int indentationLevel, Applicable applicable) {
            super(indentationLevel, applicable);
            ofNullable(catchClause.getBody()).ifPresent(block -> body.addAll(block.statements()));
            exception = catchClause.getException();
            applicable.applyFeaturesToStatements(body);
        }

        @Override
        public String toString() {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(" catch(").append(exception).append(") {").append(SEPARATOR);
// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/Applicable.java
// public enum Applicable {
//     TEST_METHOD, FIXTURE_METHOD, REGULAR_METHOD, FIELD_FEATURE;
// 
//     @Component
//     static class ApplicableInjector {
//         @Autowired private FeatureProvider featureProvider;
// 
//         @PostConstruct
//         public void init() {
//             stream(Applicable.values()).forEach(applicable -> applicable.featureProvider = featureProvider);
//         }
//     }
// 
//     private FeatureProvider featureProvider;
// 
//     public void applyFeaturesToStatements(List<Object> statements) {
//         List<Feature> features = features();
//         for (int i = 0; i < statements.size(); i++) {
//             Object bodyNode = statements.get(i);
//             statements.remove(i);
//             for (Feature testMethodFeature : features) {
//                 bodyNode = testMethodFeature.apply(bodyNode);
//             }
//             statements.add(i, bodyNode);
//         }
//     }
// 
//     public List<Feature> features() {
//         return featureProvider.features(this);
//     }
// }
// 
// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/util/StringUtil.java
// public static final String SEPARATOR = System.getProperty("line.separator");
// 
// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/util/StringUtil.java
// public static String indentation(int indentationInTabs) {
//     return IntStream.rangeClosed(1, indentationInTabs).mapToObj(__ -> "\t").reduce("", (a, b) ->  a + b);
// }


// Path: src/main/java/com/github/opaluchlukasz/junit2spock/core/node/wrapper/TryStatementWrapper.java
import com.github.opaluchlukasz.junit2spock.core.Applicable;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TryStatement;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import static com.github.opaluchlukasz.junit2spock.core.util.StringUtil.SEPARATOR;
import static com.github.opaluchlukasz.junit2spock.core.util.StringUtil.indentation;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toCollection;

    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("try {").append(SEPARATOR);
        body.forEach(printStatement(stringBuilder));
        stringBuilder.append(indentation(indentationLevel() + 1)).append("}");
        catchClauses.forEach(printStatement(stringBuilder));
        finallyBody.ifPresent(stmts -> {
            stringBuilder.append(" finally {").append(SEPARATOR);
            stmts.forEach(printStatement(stringBuilder));
            stringBuilder.append(indentation(indentationLevel() + 1)).append("}");
        });

        return stringBuilder.append(SEPARATOR).toString();
    }

    private static class CatchClauseWrapper extends BaseWrapper {
        private final LinkedList body = new LinkedList();
        private final SingleVariableDeclaration exception;

        CatchClauseWrapper(CatchClause catchClause, int indentationLevel, Applicable applicable) {
            super(indentationLevel, applicable);
            ofNullable(catchClause.getBody()).ifPresent(block -> body.addAll(block.statements()));
            exception = catchClause.getException();
            applicable.applyFeaturesToStatements(body);
        }

        @Override
        public String toString() {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(" catch(").append(exception).append(") {").append(SEPARATOR);
            body.forEach(printStatement(stringBuilder));