private TeamResult readTeamResultXml(
      final List<MatchInfo> matchCache,
      final List<TeamInfo> teamCache,
      final List<Category> categories,
      final Element resultElm)
      throws Exception {
    /*  example team result XML file content
    <result matchNumber="1" teamNumber="1" cat1="-1" cat2="-1" cat3="-1" ... >
        Specific notes about this team and this match
    </result>
    */

    // Process <result> XML element
    int theMatchNumber = resultElm.getAttribute("matchNumber").getIntValue();
    MatchInfo match =
        matchCache.stream().filter(m -> m.getMatchNumber() == theMatchNumber).findFirst().get();

    int theTeamNumber = resultElm.getAttribute("teamNumber").getIntValue();
    TeamInfo team =
        teamCache.stream().filter(t -> t.getTeamNumber() == theTeamNumber).findFirst().get();

    Map<Category, Integer> scores = new HashMap<>();
    for (Category c : categories) {
      String score = resultElm.getAttributeValue(c.getName());
      if ((score != null) && (score.length() > 0)) {
        scores.put(c, Integer.valueOf(score));
      }
    }

    TeamResult tr = new TeamResult(match, team, scores);
    tr.setNotes(resultElm.getTextNormalize());

    return tr;
  }
  private TeamInfo readTeamXml(final Element team) throws Exception {
    /*  example team XML file content
    <team teamNumber="1329" name="RoboRebels" city="St Louis" state="MO" country="US">
        General notes about this team
    </team>
    */
    int theTeamNumber = team.getAttribute("teamNumber").getIntValue();
    String theTeamName = team.getAttribute("name").getValue();
    String theTeamCity = team.getAttribute("city").getValue();
    String theTeamState = team.getAttribute("state").getValue();
    String theTeamCountry = team.getAttribute("country").getValue();
    String theNotes = team.getTextNormalize();

    TeamInfo theTeam =
        new TeamInfo(theTeamNumber, theTeamName, theTeamCity, theTeamState, theTeamCountry, null);
    theTeam.setNotes(theNotes);
    theTeam.setImageFile(locateImageFile(theTeamNumber));

    return theTeam;
  }
  @Override
  public void beforeAllMethods(ITypeRoot root, CompilationUnit cUnit) {
    JMLElement rootXML = null;
    try {
      rootXML = XMLFromSource.createXML(cUnit, root.getSource(), true, true);
    } catch (JavaModelException e) {
      e.printStackTrace();
    }

    // for use of NLP
    XMLOutputter output = new XMLOutputter(rootXML);

    // could make this pretty later - at the moment building XML just to parse it...
    try {
      InputStream istream = new ByteArrayInputStream(output.getString().getBytes());
      Document jdoc = new SAXBuilder().build(istream);
      istream.close();

      NLPResult result = new NLPResult();

      for (Element classElement : jdoc.getRootElement().getChildren()) {
        for (Element methodElement : classElement.getChildren()) {

          // get the start and end lines of this method
          Integer startLine = new Integer(methodElement.getAttributeValue("line"));
          Integer endLine = new Integer(methodElement.getAttributeValue("endLine"));

          // build set of variable names in scope
          Set<String> variableNames = new HashSet<String>();

          Element paramsElement = methodElement.getChild("params");
          if (paramsElement != null)
            for (Element paramElement : paramsElement.getChildren())
              variableNames.add(paramElement.getAttributeValue("name"));

          for (Element declarationElement : methodElement.getChildren("declaration"))
            variableNames.add(declarationElement.getAttributeValue("name"));

          Machine intRangeMachine = new IntRangeMachine(variableNames);

          // analyse each of the comments
          for (Element commentElement : methodElement.getChildren("comment")) {

            Map<String, String> frame =
                intRangeMachine.recognise(commentElement.getTextNormalize());
            if (frame != null) {

              String op = frame.get("op");
              String a1 = frame.containsKey("a1") ? frame.get("a1") : "0";

              PositiveNegativeLattice expected = null;
              if (op.equals("eq") && a1.equals("0")) {
                expected = PositiveNegativeLattice.ZERO;
              } else if ((op.equals("gt") && a1.equals("0"))
                  || (op.equals("ge") && a1.equals("1"))) {
                expected = PositiveNegativeLattice.POS;
              } else if ((op.equals("lt") && a1.equals("0"))
                  || (op.equals("le") && a1.equals("1"))) {
                expected = PositiveNegativeLattice.NEG;
              }

              if (expected != null) {
                int commentLineNo = -1;
                int lineFrom = new Integer(methodElement.getAttributeValue("line"));
                int lineTo = new Integer(methodElement.getAttributeValue("endLine"));
                String varName = frame.get("a0");
                String methodName = methodElement.getAttributeValue("name");
                result.addComment(
                    AnalysisType.SRA,
                    new RangeAnalysisComment(
                        commentLineNo, lineFrom, lineTo, expected, varName, methodName));
              }
            }
          }
        }
      }

      for (AnalysisType c : result.getTypes()) {
        try {

          c.classFile
              .getConstructor(CommentCollection.class)
              .newInstance(result.getAnnotations(c))
              .runAnalysis(getReporter(), getInput(), root, cUnit);

        } catch (InstantiationException
            | IllegalAccessException
            | IllegalArgumentException
            | InvocationTargetException
            | NoSuchMethodException
            | SecurityException e) {
          e.printStackTrace();
        }
      }

    } catch (JDOMException | IOException e) {
      e.printStackTrace();
    }
  }