code: package zemberek.dependency;
  
  import java.util.Objects;
  
  public class DependencyItem {
  
    public int id;
    public String form;
    public String lemma;
    public CoarsePosTag coarsePosTag;
    public PosTag posTag;
    public String feats;
    public int head;
    public DependencyRelation depRelation;
    public int projectiveHead;
    public DependencyRelation projectiveDepRelation;
  
    public static DependencyItem buildFromConnlLine(String line) {
      DependencyItem di = new DependencyItem();
      String[] splitz = line.trim().split("[\t]");
      di.id = di.readInt(splitz[0]);
      di.form = di.readString(splitz[1]);
      di.lemma = di.readString(splitz[2]);
      di.coarsePosTag = CoarsePosTag.getFromName(splitz[3]);
      di.posTag = PosTag.getFromName(splitz[4]);
      di.feats = di.readString(splitz[5]);
      di.head = di.readInt(splitz[6]);
      di.depRelation = DependencyRelation.getFromName(splitz[7]);
      di.projectiveHead = di.readInt(splitz[8]);
      di.projectiveDepRelation = DependencyRelation.getFromName(splitz[9]);
      return di;
    }
  
    @Override
    public DependencyItem clone() {
      try {
        return (DependencyItem) super.clone();
      } catch (CloneNotSupportedException e) {
        e.printStackTrace();
      }
      return null;
    }
  
    public boolean hasLemma() {
      return lemma != null && lemma.length() > 0;
    }
  
    public boolean hasForm() {
      return form != null && form.length() > 0;
    }
  
    public boolean isPunctuation() {
      return coarsePosTag.equals(CoarsePosTag.Punc);
    }
  
    private int readInt(String s) {
      if (s.equals("_")) {
        return -1;
      } else {
        return Integer.parseInt(s);
      }
    }
  
    String forConnl(int i) {
      return i == -1 ? "_" : String.valueOf(i);
    }
  
    String forConnl(String s) {
      return s.length() == 0 ? "_" : s;
    }
  
    private String readString(String s) {
      if (s.equals("_")) {
        return "";
      } else {
        return s;
      }
    }
  
    public String toString() {
      return getAsSpaceString();
    }
  
    public String getAsConnlString() {
      StringBuilder builder = new StringBuilder();
      builder.append(forConnl(id)).append('\t');
      builder.append(forConnl(form)).append('\t');
      builder.append(forConnl(lemma)).append('\t');
      builder.append(coarsePosTag.getAsConnlValue()).append('\t');
      builder.append(posTag.getAsConnlValue()).append('\t');
      builder.append(forConnl(feats)).append('\t');
      builder.append(forConnl(head)).append('\t');
      builder.append(depRelation.getAsConnlString()).append('\t');
      builder.append(forConnl(projectiveHead)).append('\t');
      builder.append(projectiveDepRelation.getAsConnlString());
      return builder.toString();
    }
  
    public String getAsSpaceString() {
      StringBuilder builder = new StringBuilder();
      builder.append(forConnl(id)).append(' ');
      builder.append(forConnl(form)).append(' ');
      builder.append(forConnl(lemma)).append(' ');
      builder.append(coarsePosTag.getAsConnlValue()).append(' ');
      builder.append(posTag.getAsConnlValue()).append(' ');
      builder.append(forConnl(feats)).append(' ');
      builder.append(forConnl(head)).append(' ');
      builder.append(depRelation.getAsConnlString()).append(' ');
      builder.append(forConnl(projectiveHead)).append(' ');
      builder.append(projectiveDepRelation.getAsConnlString());
      return builder.toString();
    }
  
    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
  
      DependencyItem that = (DependencyItem) o;
  
      if (id != that.id) {
        return false;
      }
      if (!Objects.equals(form, that.form)) {
        return false;
      }
      if (!Objects.equals(lemma, that.lemma)) {
        return false;
      }
  
      return true;
    }
  
    @Override
    public int hashCode() {
      int result = id;
      result = 31 * result + (form != null ? form.hashCode() : 0);
      result = 31 * result + (lemma != null ? lemma.hashCode() : 0);
      return result;
    }
  }
  