gt:         last.put("Byte", new Holder(0, true, "obyte"));
context: package net.minecraftforge.gradle.extrastuff;
  
  import com.google.code.regexp.Matcher;
  import com.google.code.regexp.Pattern;
  import com.google.common.base.Joiner;
  import com.google.common.base.Splitter;
  import com.google.common.base.Strings;
  import com.google.common.collect.Lists;
  import com.google.common.collect.Maps;
  
  import net.minecraftforge.gradle.StringUtils;
  import net.minecraftforge.gradle.common.Constants;
  
  import java.util.*;
  import java.util.Map.Entry;
  
  public class FmlCleanup
  {
      //private static final Pattern METHOD_REG = Pattern.compile("^ {4}(\\w+\\s+\\S.*\\(.*|static)$");
      private static final Pattern METHOD_REG = Pattern.compile("^(?<indent>\\s+)(?<modifiers>(?:(?:" + FFPatcher.MODIFIERS + ") )*)(?:(?<return>[\\w\\[\\]\\.$]+) )?(?<name>[\\w$]+)\\((?<parameters>.*?)\\)(?<end>(?: throws (?<throws>[\\w$.]+(?:, [\\w$.]+)*))?)");
      private static final Pattern CATCH_REG = Pattern.compile("catch \\((.*)\\)$");
      private static final Pattern METHOD_DEC_END = Pattern.compile("(}|\\);|throws .+?;)$");
      private static final Pattern CAPS_START = Pattern.compile("^[A-Z]");
      private static final Pattern ARRAY = Pattern.compile("(\\[|\\.\\.\\.)");
      private static final Pattern VAR_CALL = Pattern.compile("(?i)[a-z_$][a-z0-9_\\[\\]]+ var\\d+(?:x)*");
      private static final Pattern VAR = Pattern.compile("var\\d+(?:x)*");
  
      private static final Comparator<String> COMPARATOR = new Comparator<String>()
      {
          @Override
          public int compare(String str1, String str2)
          {
              return str2.length() - str1.length();
          }
      };
  
      public static String renameClass(String text)
      {
          String[] lines = text.split("(\r\n|\r|\n)");
          List<String> output = new ArrayList<String>(lines.length);
          MethodInfo method = null;
  
          for (String line : lines)
          {
              Matcher matcher = METHOD_REG.matcher(line);
              boolean found = matcher.find();
              if (!line.endsWith(";") && !line.endsWith(",") && found)// && !line.contains("=") && !NESTED_PERINTH.matcher(line).find())
              {
                  method = new MethodInfo(method, matcher.group("indent"));
                  method.lines.add(line);
  
                  boolean invalid = false; // Can't think of a better way to filter out enum declarations, so make sure that all the parameters have types
                  String args = matcher.group("parameters");
                  if (args != null)
                  {
                      for (String str : Splitter.on(',').trimResults().omitEmptyStrings().split(args))
                      {
                          if (str.indexOf(' ') == -1)
                          {
                              invalid = true;
                              break;
                          }
                          method.addVar(str);
                      }
                  }
  
                  if (invalid || METHOD_DEC_END.matcher(line).find())
                  {
                      if (method.parent != null)
                      {
                          method.parent.children.remove(method);
                      }
                      method = method.parent;
                      
                      if (method == null) // dont output if there is a parent method.
                          output.add(line);
                  }
              }
              else if (method != null && method.ENDING.equals(line))
              {
                  method.lines.add(line);
  
                  if (method.parent == null)
                  {
                      for (String l : Splitter.on(Constants.NEWLINE).split(method.rename(null)))
                      {
                          output.add(l);
                      }
                  }
  
                  method = method.parent;
              }
              else if (method != null)
              {
                  method.lines.add(line);
                  matcher = CATCH_REG.matcher(line);
                  if (matcher.find())
                  {
                      method.addVar(matcher.group(1));
                  }
                  else
                  {
                      matcher = VAR_CALL.matcher(line);
                      while (matcher.find())
                      {
                          String match = matcher.group();
                          if (!match.startsWith("return") && !match.startsWith("throw"))
                          {
                              method.addVar(match);
                          }
                      }
                  }
              }
              else // If we get to here, then we are outside of all methods
              {
                  output.add(line);
              }
          }
  
          return Joiner.on(Constants.NEWLINE).join(output);
      }
  
      private static class MethodInfo
      {
          private MethodInfo parent = null;
          private List<Object> lines = Lists.newArrayList();
          private List<String> vars = Lists.newArrayList();
          private List<MethodInfo> children = Lists.newArrayList();
          private final String ENDING;
  
          private MethodInfo(MethodInfo parent, String indent)
          {
              this.parent = parent;
              ENDING = indent + "}";
              if (parent != null)
              {
                  parent.children.add(this);
                  parent.lines.add(this);
              }
          }
  
          private void addVar(String info)
          {
              vars.add(info);
          }
  
          private String rename(FmlCleanup namer)
          {
              namer = namer == null ? new FmlCleanup() : new FmlCleanup(namer);
  
              Map<String, String> renames = Maps.newHashMap();
              Map<String, String> unnamed = Maps.newHashMap();
  
              for (String var : vars)
              {
                  String[] split = var.split(" ");
  
                  if (!split[1].startsWith("var"))
                      renames.put(split[1], namer.getName(split[0], split[1]));
                  else
                      unnamed.put(split[1], split[0]);
              }
  
              if (unnamed.size() > 0)
              {
                  // We sort the var## names because FF is non-deterministic and sometimes decompiles the declarations in different orders.
                  List<String> sorted = new ArrayList<String>(unnamed.keySet());
                  Collections.sort(sorted, new Comparator<String>()
                  {
                      @Override
                      public int compare(String o1, String o2)
                      {
                          if (o1.length() < o2.length()) return -1;
                          if (o1.length() > o2.length()) return  1;
                          return o1.compareTo(o2);
                      }
                  });
                  for (String s : sorted)
                  {
                      renames.put(s, namer.getName(unnamed.get(s), s));
                  }
              }
  
              StringBuilder buf = new StringBuilder();
              for (Object line : lines)
              {
                  if (line instanceof MethodInfo)
                      buf.append(((MethodInfo)line).rename(namer)).append(Constants.NEWLINE);
                  else
                      buf.append((String)line).append(Constants.NEWLINE);
              }
  
              String body = buf.toString();
  
              if (renames.size() > 0)
              {
                  List<String> sortedKeys = new ArrayList<String>(renames.keySet());
                  Collections.sort(sortedKeys, COMPARATOR);
  
                  // closure changes the sort, to sort by the return value of the closure.
                  for (String key : sortedKeys)
                  {
                      if (VAR.matcher(key).matches())
                      {
                          body = body.replace(key, renames.get(key));
                      }
                  }
              }
  
              return body.substring(0, body.length() - Constants.NEWLINE.length());
          }
      }
  
      HashMap<String, Holder> last;
      HashMap<String, String> remap;
  
      private FmlCleanup()
      {
          last = new HashMap<String, Holder>();
          last.put("byte", new Holder(0, false, "b"));
          last.put("char", new Holder(0, false, "c"));
          last.put("short", new Holder(1, false, "short"));
          last.put("int", new Holder(0, true, "i", "j", "k", "l"));
          last.put("boolean", new Holder(0, true, "flag"));
          last.put("double", new Holder(0, false, "d"));
          last.put("float", new Holder(0, true, "f"));
          last.put("File", new Holder(1, true, "file"));
          last.put("String", new Holder(0, true, "s"));
          last.put("Class", new Holder(0, true, "oclass"));
          last.put("Long", new Holder(0, true, "olong"));
  