public QualifiedName rest() {
   if (isSimpleName()) {
     throw new UnsupportedOperationException();
   }
   if (base.isSimpleName()) {
     return new QualifiedName(name);
   } else {
     return new QualifiedName(base.rest(), name);
   }
 }
 public String firstSegment() {
   if (isSimpleName()) {
     return name;
   } else {
     return base.firstSegment();
   }
 }
 public static QualifiedName create(List<String> base) {
   if (base.isEmpty()) {
     throw new IllegalArgumentException();
   } else if (base.size() == 1) {
     return new QualifiedName(base.get(0));
   } else {
     return new QualifiedName(
         QualifiedName.create(base.subList(0, base.size() - 1)), base.get(base.size() - 1));
   }
 }
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    QualifiedName that = (QualifiedName) o;

    if (base != null ? !base.equals(that.base) : that.base != null) return false;
    if (!name.equals(that.name)) return false;

    return true;
  }
  @Override
  public Optional<Node> findAmongImported(String name, SymbolResolver resolver) {
    if (alias == null) {
      throw new UnsupportedOperationException();
    } else {
      if (alias.equals(name)) {
        String canonicalTypeName = packagePart.qualifiedName() + "." + typeName;
        TypeDefinition typeDefinition =
            resolver.getTypeDefinitionIn(canonicalTypeName, this, resolver);

        Node importedValue = typeDefinition.getField(fieldsPath, resolver);
        return Optional.of(importedValue);
      } else {
        return Optional.empty();
      }
    }
  }
 @Override
 public int hashCode() {
   int result = base != null ? base.hashCode() : 0;
   result = 31 * result + name.hashCode();
   return result;
 }