gt:                 if (entry.isDirectory() || !entry.getName().endsWith(".java"))
context: /*
   * A Gradle plugin for the creation of Minecraft mods and MinecraftForge plugins.
   * Copyright (C) 2013 Minecraft Forge
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
   * USA
   */
  package net.minecraftforge.gradle.tasks;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.util.Map;
  import java.util.jar.JarEntry;
  import java.util.jar.JarOutputStream;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipException;
  import java.util.zip.ZipInputStream;
  
  import net.minecraftforge.gradle.common.Constants;
  import net.minecraftforge.gradle.util.caching.Cached;
  import net.minecraftforge.gradle.util.caching.CachedTask;
  
  import org.gradle.api.tasks.InputFile;
  import org.gradle.api.tasks.OutputFile;
  import org.gradle.api.tasks.ParallelizableTask;
  import org.gradle.api.tasks.TaskAction;
  
  import com.google.common.collect.Maps;
  import com.google.common.io.ByteStreams;
  
  @ParallelizableTask
  public abstract class AbstractEditJarTask extends CachedTask
  {
      @InputFile
      private Object inJar;
  
      @Cached
      @OutputFile
      private Object outJar;
  
      protected File resolvedInJar;
      protected File resolvedOutJar;
  
      @TaskAction
      public void doTask() throws Throwable
      {
          resolvedInJar = getInJar();
          resolvedOutJar = getOutJar();
  
          doStuffBefore();
  
          if (storeJarInRam())
          {
              getLogger().debug("Reading jar: " + resolvedInJar);
  
              Map<String, String> sourceMap = Maps.newHashMap();
              Map<String, byte[]> resourceMap = Maps.newHashMap();
  
              readAndStoreJarInRam(resolvedInJar, sourceMap, resourceMap);
  
              doStuffMiddle(sourceMap, resourceMap);
  
              saveJar(resolvedOutJar, sourceMap, resourceMap);
  
              getLogger().debug("Saving jar: " + resolvedOutJar);
          }
          else
          {
              copyJar(resolvedInJar, resolvedOutJar);
          }
  
          doStuffAfter();
      }
  
      /**
       * Do Stuff before the jar is read
       * @throws Exception for convenience
       */
      public abstract void doStuffBefore() throws Exception;
  
      /**
       * Called as the .java files of the jar are read from the jar
       * @param name name of the current entry
       * @param file current contents of the entry
       * @return new new contents of the file
       * @throws Exception as a convenience for any potential exceptions thrown in this method
       */
      public abstract String asRead(String name, String file) throws Exception;
  
      /**
       * Do Stuff after the jar is read, but before it is written.
       * @param sourceMap name-&gt;contents for all java files in the jar
       * @param resourceMap name-&gt;contents for everything else
       * @throws Exception for convenience
       */
      public abstract void doStuffMiddle(Map<String, String> sourceMap, Map<String, byte[]> resourceMap) throws Exception;
  
      /**
       * Do Stuff after the jar is Written
       * @throws Exception for convenience
       */
      public abstract void doStuffAfter() throws Exception;
  
      /**
       * Whether to store the contents of the jar in RAM.
       * If this returns false, then the doStuffMiddle method is not called.
       * @return store jar in ram
       */
      protected abstract boolean storeJarInRam();
  
      private final void readAndStoreJarInRam(File jar, Map<String, String> sourceMap, Map<String, byte[]> resourceMap) throws Exception
      {
          ZipInputStream zin = new ZipInputStream(new FileInputStream(jar));
          ZipEntry entry = null;
          String fileStr;
  
          while ((entry = zin.getNextEntry()) != null)
          {
              // ignore META-INF, it shouldnt be here. If it is we remove it from the output jar.
              if (entry.getName().contains("META-INF"))
              {
                  continue;
              }
  
              // resources or directories.
              if (entry.isDirectory() || (!entry.getName().endsWith(".java")
                      && !entry.getName().endsWith(".scala") // scala files
                      && !entry.getName().endsWith(".groovy") // groovy files
                      && !entry.getName().endsWith(".kt") // kotlin files
                      ))
              {
                  resourceMap.put(entry.getName(), ByteStreams.toByteArray(zin));
              }
              else
              {
                  // source!
                  fileStr = new String(ByteStreams.toByteArray(zin), Constants.CHARSET);
  
                  fileStr = asRead(entry.getName(), fileStr);
  
                  sourceMap.put(entry.getName(), fileStr);
              }
          }
  
          zin.close();
      }
  
      protected static void saveJar(File output, Map<String, String> sourceMap, Map<String, byte[]> resourceMap) throws IOException
      {
          output.getParentFile().mkdirs();
  
          JarOutputStream zout = new JarOutputStream(new FileOutputStream(output));
  
          // write in resources
          for (Map.Entry<String, byte[]> entry : resourceMap.entrySet())
          {
              zout.putNextEntry(new JarEntry(entry.getKey()));
              zout.write(entry.getValue());
              zout.closeEntry();
          }
  
          // write in sources
          for (Map.Entry<String, String> entry : sourceMap.entrySet())
          {
              zout.putNextEntry(new JarEntry(entry.getKey()));
              zout.write(entry.getValue().getBytes());
              zout.closeEntry();
          }
  
          zout.close();
      }
  
      private void copyJar(File input, File output) throws Exception
      {
          // begin reading jar
          ZipInputStream zin = new ZipInputStream(new FileInputStream(input));
          JarOutputStream zout = new JarOutputStream(new FileOutputStream(output));
          ZipEntry entry = null;
  
          while ((entry = zin.getNextEntry()) != null)
          {
              // no META or dirs. wel take care of dirs later.
              if (entry.getName().contains("META-INF"))
              {
                  continue;
              }
  
              // resources or directories.
              try
              {
  