/**
  * Add an array of objects reporting View's Constituents' surface form and character offsets. May
  * make deserialization to TextAnnotation problematic, as the relevant methods deduce token
  * character offsets directly from list of token strings and raw text.
  *
  * @param fieldName name to give to this field
  * @param view view whose character offsets will be serialized
  * @param json Json object to which resulting array will be added
  */
 private static void writeTokenOffsets(String fieldName, View view, JsonObject json) {
   JsonArray offsetArray = new JsonArray();
   for (Constituent c : view.getConstituents()) {
     JsonObject cJ = new JsonObject();
     writeString(FORM, c.getSurfaceForm(), cJ);
     writeInt(STARTCHAROFFSET, c.getStartCharOffset(), cJ);
     writeInt(ENDCHAROFFSET, c.getEndCharOffset(), cJ);
     offsetArray.add(cJ);
   }
   json.add(fieldName, offsetArray);
 }
 public Constituent getRateUnit(Problem prob) {
   for (Constituent cons : connectedNPs) {
     if (cons.getSurfaceForm().toLowerCase().contains("each")) {
       return cons;
     }
   }
   for (Constituent cons : connectedNPs) {
     if (cons.getSurfaceForm().toLowerCase().contains("every")) {
       return cons;
     }
   }
   if (quantPhrase.getSurfaceForm().contains("each")
       || quantPhrase.getSurfaceForm().contains("every")) {
     return quantPhrase;
   }
   int chunkId = getChunkIndex(prob, quantPhrase.getStartSpan());
   if (chunkId + 2 < prob.chunks.size()
       && prob.chunks.get(chunkId + 1).getSurfaceForm().equals("per")) {
     return prob.chunks.get(chunkId + 2);
   }
   return null;
 }