private String wj(Sentence sent, int pos, int i, int j) {
   String cp = "wj:" + Integer.toString(i) + ":" + Integer.toString(j) + ":";
   if ((pos + i) >= sent.size() || (pos + i) < 0 || (pos + j) < 0 || (pos + j) >= sent.size())
     cp = "";
   else {
     cp += sent.getWordAt(pos + i) + ":" + sent.getWordAt(pos + j);
   }
   return cp;
 }
  private String w(Sentence sent, int pos, int i) {
    String cp = "w:" + Integer.toString(i) + ":";
    if (pos + i == -1) cp += "BS";
    else if (pos + i == sent.size()) cp += "ES";
    else if (0 <= (pos + i) && (pos + i) < sent.size()) cp += sent.getWordAt(pos + i);
    else cp = "";

    return cp;
  }
  private String mk(Sentence sent, int pos, int i) {
    String cp;
    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      cp = "mk:" + Integer.toString(i);
      String word = sent.getWordAt(pos + i);
      if (!StringUtils.isSign(word)) cp = "";
    } else cp = "";

    return cp;
  }
  private String com(Sentence sent, int pos, int i) {
    String cp;
    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      cp = "hyph:" + Integer.toString(i);

      String word = sent.getWordAt(pos + i);
      if (!word.contains(":")) cp = "";
    } else cp = "";

    return cp;
  }
  private String hn(Sentence sent, int pos, int i) {
    String cp;
    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      cp = "hn:" + Integer.toString(i);

      String word = sent.getWordAt(pos + i);
      if (!StringUtils.containNumber(word)) cp = "";
    } else cp = "";

    return cp;
  }
  private String sff(Sentence sent, int pos, int i) {
    String cp;
    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      cp = "sff:" + Integer.toString(i) + ":";

      String word = sent.getWordAt(pos + i);
      String[] sylls = word.split("_");
      if (sylls.length >= 2) {
        cp += sylls[sylls.length - 1];
      } else cp = "";
    } else cp = "";

    return cp;
  }
  private String dict(Sentence sent, int pos, int i) {
    String cp = "";

    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      String word = sent.getWordAt(pos + i);
      if (word2dictags.containsKey(word)) {
        List tags = (List) word2dictags.get(word);

        for (int j = 0; j < tags.size(); ++j) {
          cp += "dict:" + Integer.toString(i) + ":" + tags.get(j) + " ";
        }
      }
    }

    return cp.trim();
  }
  private String ac(Sentence sent, int pos, int i) {
    String cp;
    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      cp = "ac:" + Integer.toString(i);

      String word = sent.getWordAt(pos + i);
      boolean isAllCap = true;

      for (int j = 0; j < word.length(); ++j) {
        if (word.charAt(j) == '_' || word.charAt(j) == '.') continue;

        if (!Character.isUpperCase(word.charAt(j))) {
          isAllCap = false;
          break;
        }
      }

      if (!isAllCap) cp = "";
    } else cp = "";
    return cp;
  }
  private String rr(Sentence sent, int pos, int i) {
    String cp = "";

    if (0 <= (pos + i) && (pos + i) < sent.size()) {
      String word = sent.getWordAt(pos + i);
      String[] sylls = word.split("_");

      if (sylls.length == 2) { // consider 2-syllable words
        VnSyllParser parser1 = new VnSyllParser(sylls[0]);
        VnSyllParser parser2 = new VnSyllParser(sylls[1]);

        if (parser1.isValidVnSyllable() && parser2.isValidVnSyllable()) {
          if (parser1.getNonToneSyll().equalsIgnoreCase(parser2.getNonToneSyll())) {
            cp += "fr:" + Integer.toString(i) + " ";
          } else if (parser1.getRhyme().equalsIgnoreCase(parser2.getRhyme())) {
            cp += "pr:" + Integer.toString(i) + " ";
          }
        }
      }
    }

    return cp.trim();
  }