@Override
  public boolean equals(final Object obj) {

    if (obj == null) {
      return false;
    }
    if (!Identifier.class.isInstance(obj)) {
      return false;
    }
    if (!VirtualIdentifier.class.isInstance(obj)) {
      // we assume it is of type KT
      if (key != null) {
        return key.equals(obj);
      } else {
        return false;
      }
    }
    if (getClass() != obj.getClass()) {
      // NOTE this would be a problem if we have multiple virtual identifiers implemented per one KT
      return false;
    }
    final AbstractVirtualIdentifier other = (AbstractVirtualIdentifier) obj;
    if (!this.isVirtual() && !other.isVirtual()) {
      return this.getKey().equals(other.getKey());
    }
    return (this.getVirtualId() == other.getVirtualId());
  }
  @Override
  public int compareTo(final Identifier<K> other) {

    if (!(other instanceof VirtualIdentifier)) {
      return -other.compareTo(this);
    }
    final AbstractVirtualIdentifier<K> otherCasted = (AbstractVirtualIdentifier<K>) other;
    if (!this.isVirtual() && !otherCasted.isVirtual()) {
      return this.getKey().compareTo(otherCasted.getKey());
    }
    return this.getVirtualId().compareTo(otherCasted.getVirtualId());
  }