public static String extractPercentComplete(String line) {
    Matcher jar = JAR_COMPLETE.matcher(line);
    if (jar.find())
      return jar.group().trim();

    Matcher pig = PIG_COMPLETE.matcher(line);
    if (pig.find())
      return pig.group().trim();

    Matcher beeline = HIVE_BEELINE_COMPLETE.matcher(line);
    if (beeline.find()) {
      return beeline.group(1).trim() + " complete";
    }

    Matcher hive = HIVE_COMPLETE.matcher(line);
    if(hive.find()) {
      return "map " + hive.group(1) + " reduce " + hive.group(2);
    }
    Matcher hiveTez = HIVE_TEZ_COMPLETE.matcher(line);
    if(hiveTez.find()) {
      int totalTasks = 0;
      int completedTasks = 0;
      do {
        //here each group looks something like "Map 2: 2/4" "Reducer 3: 1(+2)/4"
        //just parse the numbers and ignore one from "Map 2" and from "(+2)" if it's there
        Matcher counts = TEZ_COUNTERS.matcher(hiveTez.group());
        List<String> items = new ArrayList<String>(4);
        while(counts.find()) {
          items.add(counts.group());
        }
        completedTasks += Integer.parseInt(items.get(1));
        if(items.size() == 3) {
          totalTasks += Integer.parseInt(items.get(2));
        }
        else {
          totalTasks += Integer.parseInt(items.get(3));
        }
      } while(hiveTez.find());
      if(totalTasks == 0) {
        return "0% complete (0 total tasks)";
      }
      return completedTasks * 100 / totalTasks + "% complete";
    }
    Matcher pigTez = PIG_TEZ_COMPLETE.matcher(line);
    if(pigTez.find()) {
      int totalTasks = Integer.parseInt(pigTez.group(1));
      int completedTasks = Integer.parseInt(pigTez.group(2));
      if(totalTasks == 0) {
          return "0% complete (0 total tasks)";
        }
        return completedTasks * 100 / totalTasks + "% complete";
    }
    return null;
  }
@Test
  public void testExtractPercentComplete() {
    Assert.assertNull(TempletonUtils.extractPercentComplete("fred"));
    for (String line : CONTROLLER_LINES) {
      Assert.assertNull(TempletonUtils.extractPercentComplete(line));
    }

    String fifty = "2011-12-15 18:12:36,333 [main] INFO  org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MapReduceLauncher - 50% complete";
    Assert.assertEquals("50% complete", TempletonUtils.extractPercentComplete(fifty));

    String beeline = "VERTICES: 01/02  [==========================>>] 70%  ELAPSED TIME: 3.79 s";
    Assert.assertEquals("70% complete", TempletonUtils.extractPercentComplete(beeline));
  }