// Path: src/edu/stanford/nlp/semparse/open/dataset/entity/TargetEntity.java
// public interface TargetEntity {
//   public boolean match(String predictedEntity);
//   public boolean matchAny(Collection<String> predictedEntities);
// }
// 
// Path: src/edu/stanford/nlp/semparse/open/dataset/entity/TargetEntityNearMatch.java
// public class TargetEntityNearMatch implements TargetEntity {
//   public static class Options {
//     @Option public int nearMatchMaxEditDistance = 2;
//     @Option(gloss = "level of target entity string normalization "
//                   + "(0 = none / 1 = whitespace / 2 = simple / 3 = aggressive)")
//     public int targetNormalizeEntities = 2;
//   }
//   public static Options opts = new Options();
//   
//   public final String expected, normalizedExpected;
//   
//   public TargetEntityNearMatch(String expected) {
//     this.expected = expected;
//     this.normalizedExpected = LingUtils.normalize(expected, opts.targetNormalizeEntities);
//   }
//   
//   @Override public String toString() {
//     StringBuilder sb = new StringBuilder(expected);
//     if (!expected.equals(normalizedExpected))
//       sb.append(" || ").append(normalizedExpected);
//     return sb.toString();
//   }
// 
//   @Override
//   public boolean match(String predictedEntity) {
//     // Easy cases
//     if (expected.equals(predictedEntity))
//       return true;
//     // Edit distance
//     if (EditDistance.withinEditDistance(normalizedExpected, predictedEntity, opts.nearMatchMaxEditDistance))
//       return true;
//     return false;
//   }
// 
//   @Override
//   public boolean matchAny(Collection<String> predictedEntities) {
//     for (String predictedEntity : predictedEntities) {
//       if (match(predictedEntity)) return true;
//     }
//     return false;
//   }
// 
// }
// 
// Path: src/edu/stanford/nlp/semparse/open/dataset/library/JSONDataset.java
// @JsonIgnoreProperties(ignoreUnknown=true)
// public static class JSONDatasetDatum {
//   public String hashcode;
//   public String query;
//   public String url;
//   public List<String> entities;
//   public List<JSONDatasetRawAnswers> rawanswers;
//   public JSONDatasetCriteria criteria;
//     
//   @Override
//   public String toString() {
//     return new StringBuilder()
//       .append("[").append(query)
//       .append(hashcode == null ? "" : " " + hashcode).append("]")
//       .toString();
//   }
// }


import java.util.*;
import edu.stanford.nlp.semparse.open.dataset.entity.TargetEntity;
import edu.stanford.nlp.semparse.open.dataset.entity.TargetEntityNearMatch;
import edu.stanford.nlp.semparse.open.dataset.library.JSONDataset.JSONDatasetDatum;
package edu.stanford.nlp.semparse.open.dataset;



/**
 * Must match first, second, and last entities
 */
public class CriteriaGeneralWeb implements Criteria {
  public final JSONDatasetDatum datum;
  public final TargetEntity first, second, last;
  
  public CriteriaGeneralWeb(JSONDatasetDatum datum) {
    this.datum = datum;
    this.first = new TargetEntityNearMatch(datum.criteria.first);
    this.second = new TargetEntityNearMatch(datum.criteria.second);
    this.last = new TargetEntityNearMatch(datum.criteria.last);
  }

  @Override
// Path: src/edu/stanford/nlp/semparse/open/dataset/entity/TargetEntity.java
// public interface TargetEntity {
//   public boolean match(String predictedEntity);
//   public boolean matchAny(Collection<String> predictedEntities);
// }
// 
// Path: src/edu/stanford/nlp/semparse/open/dataset/entity/TargetEntityNearMatch.java
// public class TargetEntityNearMatch implements TargetEntity {
//   public static class Options {
//     @Option public int nearMatchMaxEditDistance = 2;
//     @Option(gloss = "level of target entity string normalization "
//                   + "(0 = none / 1 = whitespace / 2 = simple / 3 = aggressive)")
//     public int targetNormalizeEntities = 2;
//   }
//   public static Options opts = new Options();
//   
//   public final String expected, normalizedExpected;
//   
//   public TargetEntityNearMatch(String expected) {
//     this.expected = expected;
//     this.normalizedExpected = LingUtils.normalize(expected, opts.targetNormalizeEntities);
//   }
//   
//   @Override public String toString() {
//     StringBuilder sb = new StringBuilder(expected);
//     if (!expected.equals(normalizedExpected))
//       sb.append(" || ").append(normalizedExpected);
//     return sb.toString();
//   }
// 
//   @Override
//   public boolean match(String predictedEntity) {
//     // Easy cases
//     if (expected.equals(predictedEntity))
//       return true;
//     // Edit distance
//     if (EditDistance.withinEditDistance(normalizedExpected, predictedEntity, opts.nearMatchMaxEditDistance))
//       return true;
//     return false;
//   }
// 
//   @Override
//   public boolean matchAny(Collection<String> predictedEntities) {
//     for (String predictedEntity : predictedEntities) {
//       if (match(predictedEntity)) return true;
//     }
//     return false;
//   }
// 
// }
// 
// Path: src/edu/stanford/nlp/semparse/open/dataset/library/JSONDataset.java
// @JsonIgnoreProperties(ignoreUnknown=true)
// public static class JSONDatasetDatum {
//   public String hashcode;
//   public String query;
//   public String url;
//   public List<String> entities;
//   public List<JSONDatasetRawAnswers> rawanswers;
//   public JSONDatasetCriteria criteria;
//     
//   @Override
//   public String toString() {
//     return new StringBuilder()
//       .append("[").append(query)
//       .append(hashcode == null ? "" : " " + hashcode).append("]")
//       .toString();
//   }
// }


// Path: src/edu/stanford/nlp/semparse/open/dataset/CriteriaGeneralWeb.java
import java.util.*;
import edu.stanford.nlp.semparse.open.dataset.entity.TargetEntity;
import edu.stanford.nlp.semparse.open.dataset.entity.TargetEntityNearMatch;
import edu.stanford.nlp.semparse.open.dataset.library.JSONDataset.JSONDatasetDatum;

package edu.stanford.nlp.semparse.open.dataset;



/**
 * Must match first, second, and last entities
 */
public class CriteriaGeneralWeb implements Criteria {
  public final JSONDatasetDatum datum;
  public final TargetEntity first, second, last;
  
  public CriteriaGeneralWeb(JSONDatasetDatum datum) {
    this.datum = datum;
    this.first = new TargetEntityNearMatch(datum.criteria.first);
    this.second = new TargetEntityNearMatch(datum.criteria.second);
    this.last = new TargetEntityNearMatch(datum.criteria.last);
  }

  @Override
  public List<TargetEntity> getTargetEntities() {