/*
   * createGST and gstMATCH
   *
   * Methods to implement the GST-TILING methodology of matching strings.
   */
  private GST createGST(int needleLength, String haystack) {
    GST gst = new GST(haystack);
    // Needs to be at least a third of the needle length to
    // count as a match
    gst.setMinimumTileLength((int) Math.ceil(needleLength / 3));

    return gst;
  }
  // ## TextConstraint gstMatch
  //
  // Matches a constraint within passed content. Makes sure that
  // the constraint text is found within the content, but in order to
  // be a true match, it has to match in or near the same location as
  // the original constraint
  //
  // Parameters:
  //
  // * primaryContent - String - content to find context within
  //
  // * originalConstraint - TextConstraint - object to test internal constraint against
  private TextConstraint gstMatch(String primaryContent, TextConstraint originalConstraint)
      throws NoMatchFoundException {
    GST g = createGST(this.beforeContext.length(), primaryContent);

    g.match(this.beforeContext);
    if (g.getTiles().size() == 0) throw new Context.NoMatchFoundException();
    int startMatch = -1;
    int maxMatchIndex =
        originalConstraint.getStartPos()
            - (this.beforeContext.length() + (int) Math.ceil((this.beforeContext.length() / 3)));
    int minMatchIndex =
        originalConstraint.getStartPos()
            - (int) Math.ceil(Math.ceil(this.beforeContext.length() / 3));
    int i;
    // go through each matched TILE and see
    // if the match is close to our context
    for (GSTTile item : g.getTiles()) {
      i = item.getStart();
      if (i > startMatch && i > minMatchIndex && i <= maxMatchIndex) {
        startMatch = item.getStart();
      }
    }
    // Check if no matches found
    if (startMatch < 1) throw new Context.NoMatchFoundException();

    minMatchIndex =
        originalConstraint.getEndPos()
            + (this.afterContext.length() + (int) Math.ceil((this.beforeContext.length() / 3)));
    maxMatchIndex = originalConstraint.getEndPos() + this.afterContext.length();
    int endMatch = -1;

    for (GSTTile item : g.getTiles()) {
      i = item.getStart() + item.getLength();
      if (i > endMatch && i > minMatchIndex && i <= maxMatchIndex) {
        endMatch = item.getStart();
      }
    }

    if (endMatch < 1) throw new Context.NoMatchFoundException();

    return new TextConstraint(startMatch, endMatch);
  }