// Path: src/main/java/org/moe/gradle/utils/FileUtils.java
// public class FileUtils {
//     public static void deleteFileOrFolder(final @NotNull Path path) throws IOException {
//         Require.nonNull(path);
// 
//         if (!path.toFile().exists()) {
//             return;
//         }
//         Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
//             @Override
//             public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
//                     throws IOException {
//                 Files.delete(file);
//                 return CONTINUE;
//             }
// 
//             @Override
//             public FileVisitResult postVisitDirectory(final Path dir, final IOException e)
//                     throws IOException {
//                 if (e != null) throw e;
//                 Files.delete(dir);
//                 return CONTINUE;
//             }
//         });
//     }
// 
//     public static void deleteFileOrFolder(final @NotNull File file) throws IOException {
//         Require.nonNull(file);
// 
//         deleteFileOrFolder(Paths.get(file.toURI()));
//     }
// 
//     @NotNull
//     public static String read(@NotNull File file) {
//         Require.nonNull(file);
// 
//         String string;
//         try {
//             string = new String(Files.readAllBytes(Paths.get(file.toURI())));
//         } catch (IOException e) {
//             throw new GradleException("Failed to read " + file, e);
//         }
//         return string;
//     }
// 
//     public static void write(@NotNull File file, @NotNull String string) {
//         Require.nonNull(file);
//         Require.nonNull(string);
// 
//         try {
//             Files.write(Paths.get(file.toURI()), string.getBytes(),
//                     StandardOpenOption.CREATE,
//                     StandardOpenOption.WRITE,
//                     StandardOpenOption.TRUNCATE_EXISTING);
//         } catch (IOException e) {
//             throw new GradleException("Failed to write " + file, e);
//         }
//     }
// 
//     @NotNull
//     public static File getRelativeTo(@NotNull File base, @NotNull File other) {
//         Require.nonNull(base);
//         Require.nonNull(other);
// 
//         return Paths.get(base.getAbsolutePath()).relativize(Paths.get(other.getAbsolutePath())).toFile();
//     }
// 
//     @NotNull
//     public static String getNameAsArtifact(@NotNull File file, @NotNull String version) {
//         Require.nonNull(file);
//         Require.nonNull(version);
// 
//         final String name = file.getName();
//         final int idx = name.indexOf('.');
//         if (idx == -1) {
//             throw new GradleException("Unexpected state");
// 
//         } else {
//             final String baseName = name.substring(0, idx);
//             final String ext = name.substring(idx + 1);
//             return "multi-os-engine:" + baseName + ":" + version + "@" + ext;
//         }
//     }
// 
//     public static void classAndJarInputIterator(
//             @NotNull FileCollection fileCollection,
//             @NotNull Consumer<InputStream> consumer
//     ) {
//         FileUtilsKt.classAndJarInputIterator(fileCollection, (path, inputStream) -> {
//             consumer.accept(inputStream);
//             return Unit.INSTANCE;
//         });
//     }
// }


import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.Test;
import org.moe.generator.project.MOEProjectComposer;
import org.moe.generator.project.MOEProjectComposer.MOEProjectComposerException;
import org.moe.generator.project.MOEProjectComposer.Template;
import org.moe.gradle.utils.FileUtils;
import java.io.File;
import java.io.IOException;
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS;
import static org.junit.Assert.*;

        copyJavaSourceFile("IgnoredController.java");
        copyJavaSourceFile("InvalidController.java");
        copyJavaSourceFile("UnmappedController.java");
        copyJavaSourceFile("ValidController.java");

        final File buildGradleFile = new File(testProjectDir.getRoot(), "build.gradle");
        String gradle = FileUtils.read(buildGradleFile);
        gradle = gradle.replace("classpath group:", "// classpath group:");
        gradle = gradle.replace("apply plugin: 'moe'", "plugins { id 'moe'; id 'eclipse' }");
        gradle = gradle.replaceAll("apply plugin: '\\w+'", "");
        final StringBuilder gradleBuilder = new StringBuilder(gradle);
        gradleBuilder.append('\n');
        gradleBuilder.append("moe.actionsAndOutlets.include 'org\\\\.moe\\\\.InvalidController'\n");
        gradleBuilder.append("moe.actionsAndOutlets.include 'org\\\\.moe\\\\.UnmappedController'\n");
        gradleBuilder.append("moe.actionsAndOutlets.include 'org\\\\.moe\\\\.ValidController'\n");
        gradleBuilder.append("moe.actionsAndOutlets.excludeLibrary 'AVFoundation'\n");
        gradleBuilder.append("moe.actionsAndOutlets.additionalCode '#warning This is my additional code!'\n");
        FileUtils.write(buildGradleFile, gradleBuilder.toString());

        BuildResult result = GradleRunner.create()
                .withProjectDir(testProjectDir.getRoot())
                .withArguments("moeGenerateUIObjCInterfaces", "-Pmoe.sdk.localbuild=" + getSdkLocalbuild(), "-s")
                .withPluginClasspath(getPluginClasspath())
                .build();

        final String output = result.getOutput();
        assertTrue(output.contains("moe"));
        assertEquals(result.task(":moeGenerateUIObjCInterfaces").getOutcome(), SUCCESS);

// Path: src/main/java/org/moe/gradle/utils/FileUtils.java
// public class FileUtils {
//     public static void deleteFileOrFolder(final @NotNull Path path) throws IOException {
//         Require.nonNull(path);
// 
//         if (!path.toFile().exists()) {
//             return;
//         }
//         Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
//             @Override
//             public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
//                     throws IOException {
//                 Files.delete(file);
//                 return CONTINUE;
//             }
// 
//             @Override
//             public FileVisitResult postVisitDirectory(final Path dir, final IOException e)
//                     throws IOException {
//                 if (e != null) throw e;
//                 Files.delete(dir);
//                 return CONTINUE;
//             }
//         });
//     }
// 
//     public static void deleteFileOrFolder(final @NotNull File file) throws IOException {
//         Require.nonNull(file);
// 
//         deleteFileOrFolder(Paths.get(file.toURI()));
//     }
// 
//     @NotNull
//     public static String read(@NotNull File file) {
//         Require.nonNull(file);
// 
//         String string;
//         try {
//             string = new String(Files.readAllBytes(Paths.get(file.toURI())));
//         } catch (IOException e) {
//             throw new GradleException("Failed to read " + file, e);
//         }
//         return string;
//     }
// 
//     public static void write(@NotNull File file, @NotNull String string) {
//         Require.nonNull(file);
//         Require.nonNull(string);
// 
//         try {
//             Files.write(Paths.get(file.toURI()), string.getBytes(),
//                     StandardOpenOption.CREATE,
//                     StandardOpenOption.WRITE,
//                     StandardOpenOption.TRUNCATE_EXISTING);
//         } catch (IOException e) {
//             throw new GradleException("Failed to write " + file, e);
//         }
//     }
// 
//     @NotNull
//     public static File getRelativeTo(@NotNull File base, @NotNull File other) {
//         Require.nonNull(base);
//         Require.nonNull(other);
// 
//         return Paths.get(base.getAbsolutePath()).relativize(Paths.get(other.getAbsolutePath())).toFile();
//     }
// 
//     @NotNull
//     public static String getNameAsArtifact(@NotNull File file, @NotNull String version) {
//         Require.nonNull(file);
//         Require.nonNull(version);
// 
//         final String name = file.getName();
//         final int idx = name.indexOf('.');
//         if (idx == -1) {
//             throw new GradleException("Unexpected state");
// 
//         } else {
//             final String baseName = name.substring(0, idx);
//             final String ext = name.substring(idx + 1);
//             return "multi-os-engine:" + baseName + ":" + version + "@" + ext;
//         }
//     }
// 
//     public static void classAndJarInputIterator(
//             @NotNull FileCollection fileCollection,
//             @NotNull Consumer<InputStream> consumer
//     ) {
//         FileUtilsKt.classAndJarInputIterator(fileCollection, (path, inputStream) -> {
//             consumer.accept(inputStream);
//             return Unit.INSTANCE;
//         });
//     }
// }


// Path: src/test/java/org/moe/gradle/UIActionsAndOutletsTest.java
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.Test;
import org.moe.generator.project.MOEProjectComposer;
import org.moe.generator.project.MOEProjectComposer.MOEProjectComposerException;
import org.moe.generator.project.MOEProjectComposer.Template;
import org.moe.gradle.utils.FileUtils;
import java.io.File;
import java.io.IOException;
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS;
import static org.junit.Assert.*;


        copyJavaSourceFile("IgnoredController.java");
        copyJavaSourceFile("InvalidController.java");
        copyJavaSourceFile("UnmappedController.java");
        copyJavaSourceFile("ValidController.java");

        final File buildGradleFile = new File(testProjectDir.getRoot(), "build.gradle");
        String gradle = FileUtils.read(buildGradleFile);
        gradle = gradle.replace("classpath group:", "// classpath group:");
        gradle = gradle.replace("apply plugin: 'moe'", "plugins { id 'moe'; id 'eclipse' }");
        gradle = gradle.replaceAll("apply plugin: '\\w+'", "");
        final StringBuilder gradleBuilder = new StringBuilder(gradle);
        gradleBuilder.append('\n');
        gradleBuilder.append("moe.actionsAndOutlets.include 'org\\\\.moe\\\\.InvalidController'\n");
        gradleBuilder.append("moe.actionsAndOutlets.include 'org\\\\.moe\\\\.UnmappedController'\n");
        gradleBuilder.append("moe.actionsAndOutlets.include 'org\\\\.moe\\\\.ValidController'\n");
        gradleBuilder.append("moe.actionsAndOutlets.excludeLibrary 'AVFoundation'\n");
        gradleBuilder.append("moe.actionsAndOutlets.additionalCode '#warning This is my additional code!'\n");
        FileUtils.write(buildGradleFile, gradleBuilder.toString());

        BuildResult result = GradleRunner.create()
                .withProjectDir(testProjectDir.getRoot())
                .withArguments("moeGenerateUIObjCInterfaces", "-Pmoe.sdk.localbuild=" + getSdkLocalbuild(), "-s")
                .withPluginClasspath(getPluginClasspath())
                .build();

        final String output = result.getOutput();
        assertTrue(output.contains("moe"));
        assertEquals(result.task(":moeGenerateUIObjCInterfaces").getOutcome(), SUCCESS);

        assertTrue(output.contains(