private void addZhaoSupervisedCombinedFeats(
      FeaturizedToken pred,
      FeaturizedToken arg,
      ArrayList<String> feats,
      ArrayList<FeaturizedToken> dependencyPathObjectList,
      ArrayList<FeaturizedToken> linePathCoNLL,
      List<Pair<Integer, Dir>> dpPathArg) {
    // ------- Combined features (supervised) -------
    String feat;
    // a.lemma + p.lemma
    feat = arg.getLemma() + "_" + pred.getLemma();
    feats.add(feat);
    // (a:p|dpPath.dprel) + p.FEAT1
    // a:p|dpPath.lemma.seq
    // a:p|dpPath.lemma.bag
    ArrayList<String> depRelPath = new ArrayList<String>();
    ArrayList<String> depRelPathLemma = new ArrayList<String>();
    for (FeaturizedToken t : dependencyPathObjectList) {
      depRelPath.add(t.getDeprel());
      depRelPathLemma.add(t.getLemma());
    }

    feat = buildString(depRelPath) + pred.getFeat6().get(0);
    feats.add(feat);
    feat = buildString(depRelPathLemma);
    feats.add(feat);
    ArrayList<String> depRelPathLemmaBag = bag(depRelPathLemma);
    feat = buildString(depRelPathLemmaBag);
    feats.add(feat);
    // a:p|linePath.FEAT1.bag
    // a:p|linePath.lemma.seq
    // a:p|linePath.dprel.seq
    ArrayList<String> linePathFeat = new ArrayList<String>();
    ArrayList<String> linePathLemma = new ArrayList<String>();
    ArrayList<String> linePathDeprel = new ArrayList<String>();
    for (FeaturizedToken t : linePathCoNLL) {
      linePathFeat.add(t.getFeat6().get(0));
      linePathLemma.add(t.getLemma());
      linePathDeprel.add(t.getDeprel());
    }
    ArrayList<String> linePathFeatBag = bag(linePathFeat);
    feat = buildString(linePathFeatBag);
    feats.add(feat);
    feat = buildString(linePathLemma);
    feats.add(feat);
    feat = buildString(linePathDeprel);
    feats.add(feat);
    ArrayList<String> dpPathLemma = new ArrayList<String>();
    for (Pair<Integer, Dir> dpP : dpPathArg) {
      dpPathLemma.add(getFeatureObject(dpP.get1()).getLemma());
    }
    // a:p|dpPathArgu.lemma.seq
    feat = buildString(dpPathLemma);
    feats.add(feat);
    // a:p|dpPathArgu.lemma.bag
    feat = buildString(bag(dpPathLemma));
    feats.add(feat);
  }
 protected ArrayList<FeaturizedToken> getFeatureObjectList(List<Pair<Integer, Dir>> path) {
   ArrayList<FeaturizedToken> pathObjectList = new ArrayList<FeaturizedToken>();
   for (Pair<Integer, Dir> p : path) {
     FeaturizedToken newFeatureObject = getFeatureObject(p.get1());
     // Adding directionality here, given the type of path.
     // These serve as additional features following Bjorkelund.
     newFeatureObject.setDirection(p.get2());
     pathObjectList.add(newFeatureObject);
   }
   return pathObjectList;
 }