@Override
  public Set<Feature> getFeatures(Constituent c) throws EdisonException {
    TextAnnotation ta = c.getTextAnnotation();
    Set<Feature> features = new LinkedHashSet<>();
    TreeView parse = (TreeView) ta.getView(dependencyViewName);
    // get equivalent of c in the parse view
    Constituent c2 = parse.getConstituentsCoveringToken(c.getStartSpan()).get(0);
    List<Relation> incomingRelations = c2.getIncomingRelations();
    if (incomingRelations.size() > 0) {
      Constituent c1 =
          parse
              .getConstituentsCoveringToken(incomingRelations.get(0).getSource().getStartSpan())
              .get(0);

      Pair<List<Constituent>, List<Constituent>> paths =
          PathFeatureHelper.getPathsToCommonAncestor(c1, c2, 400);

      List<String> path = new ArrayList<>();
      List<String> pos = new ArrayList<>();

      for (int i = 0; i < paths.getFirst().size() - 1; i++) {
        Constituent cc = paths.getFirst().get(i);
        path.add(
            cc.getIncomingRelations().get(0).getRelationName() + PathFeatureHelper.PATH_UP_STRING);

        pos.add(
            WordHelpers.getPOS(ta, cc.getStartSpan())
                + ":"
                + cc.getIncomingRelations().get(0).getRelationName()
                + PathFeatureHelper.PATH_UP_STRING);
      }

      Constituent top = paths.getFirst().get(paths.getFirst().size() - 1);

      pos.add(WordHelpers.getPOS(ta, top.getStartSpan()) + ":*");
      path.add("*");

      if (paths.getSecond().size() > 1) {
        for (int i = paths.getSecond().size() - 2; i >= 0; i--) {
          Constituent cc = paths.getSecond().get(i);

          pos.add(
              WordHelpers.getPOS(ta, cc.getStartSpan()) + ":" + PathFeatureHelper.PATH_DOWN_STRING);
          path.add(PathFeatureHelper.PATH_DOWN_STRING);
        }
      }

      features.addAll(getNgrams(path, ""));
      features.addAll(getNgrams(pos, "pos"));
    }
    return features;
  }
  private static Constituent getHead(Constituent c, TreeView dependency) {
    Constituent end = null;
    List<Constituent> constituentsCovering = dependency.getConstituentsCovering(c);
    for (Constituent d : constituentsCovering) {
      List<Relation> in = d.getIncomingRelations();
      if (in.size() == 0) {
        end = d;
        break;
      } else {
        Constituent parent = in.get(0).getSource();

        int parentToken = parent.getStartSpan();
        if (c.getStartSpan() <= parentToken && parentToken < c.getEndSpan()) continue;

        if (end == null) {
          end = d;
        } else if (end.getStartSpan() < d.getStartSpan()) {
          end = d;
        }
      }
    }

    Constituent c1;
    if (end == null) c1 = constituentsCovering.get(0).cloneForNewView("");
    else c1 = end.cloneForNewView("");

    return addPointerToSource(c, c1);
  }
        @Override
        public List<Constituent> transform(Constituent input) {

          TextAnnotation ta = input.getTextAnnotation();
          int tokenPosition = input.getStartSpan();
          TreeView dependency = (TreeView) ta.getView(ViewNames.DEPENDENCY);

          Constituent verbNode = dependency.getConstituentsCoveringToken(tokenPosition).get(0);
          boolean done = false;

          while (!done) {
            String pos = WordHelpers.getPOS(ta, verbNode.getStartSpan());

            if (POSUtils.isPOSVerb(pos)) {
              done = true;
            } else {
              List<Relation> incoming = verbNode.getIncomingRelations();
              if (incoming == null || incoming.size() == 0) {
                return new ArrayList<>();
              } else verbNode = incoming.get(0).getSource();
            }
          }

          return Collections.singletonList(addPointerToSource(input, verbNode));
        }
        @Override
        public List<Constituent> transform(Constituent input) {

          List<Constituent> c = new ArrayList<>();
          for (Relation r : input.getIncomingRelations()) {
            c.add(addPointerToSource(input, r.getSource()));
          }
          return c;
        }
 public Constituent getDependentVerb(Problem prob, QuantSpan qs) {
   Constituent result =
       getDependencyConstituentCoveringTokenId(
           prob, prob.ta.getTokenIdFromCharacterOffset(qs.start));
   if (result == null) {
     System.out.println(
         "Text : "
             + prob.question
             + " Token : "
             + prob.ta.getTokenIdFromCharacterOffset(qs.start));
     Tools.printCons(prob.dependency);
   }
   while (result != null) {
     if (result.getIncomingRelations().size() == 0) break;
     //			System.out.println(result.getIncomingRelations().get(0).getSource()+" --> "+result);
     result = result.getIncomingRelations().get(0).getSource();
     if (prob.posTags.get(result.getStartSpan()).getLabel().startsWith("VB")) {
       return result;
     }
   }
   return result;
 }
  private static List<Constituent> getGovernor(Constituent input, TreeView dependency) {
    List<Constituent> constituentsCovering = dependency.getConstituentsCovering(input);

    if (constituentsCovering.size() == 0) return new ArrayList<>();

    Constituent c = constituentsCovering.get(0);

    List<Relation> incomingRelations = c.getIncomingRelations();

    if (incomingRelations == null || incomingRelations.size() == 0) return new ArrayList<>();
    else
      return Collections.singletonList(
          addPointerToSource(input, incomingRelations.get(0).getSource()));
  }
        @Override
        public List<Constituent> transform(Constituent c) {
          TextAnnotation ta = c.getTextAnnotation();
          int tokenPosition = c.getStartSpan();
          TreeView dependency = (TreeView) ta.getView(ViewNames.DEPENDENCY);

          Constituent prepositionDepConstituent =
              dependency.getConstituentsCoveringToken(tokenPosition).get(0);

          List<Relation> incomingRelations = prepositionDepConstituent.getIncomingRelations();

          List<Constituent> list = new ArrayList<>();
          if (incomingRelations != null && incomingRelations.size() > 0) {

            Constituent parent = incomingRelations.get(0).getSource();

            for (Relation out : parent.getOutgoingRelations()) {
              if (out == incomingRelations.get(0)) continue;

              String label = out.getRelationName();

              if (label.contains("prep")) {
                Constituent ppNode = out.getTarget();

                list.add(addPointerToSource(c, ppNode));

                // get the first child of the pp and add this
                List<Relation> ppOut = ppNode.getOutgoingRelations();

                if (ppOut != null && ppOut.size() != 0) {

                  Constituent child = ppOut.get(0).getTarget();
                  list.add(addPointerToSource(c, child));
                }
              }
            }
          }

          return list;
        }