class Attribute implements Comparable<Attribute> {

  private final Key key;
  private final List<Value> values;
  private final AttributeType type;

  public Attribute(Key key, List<Value> values, AttributeType type) {
    this.key = key;
    this.values = values;
    this.type = type;
  }

  public Attribute(Key key, Value value, AttributeType type) {
    this(key, Collections.singletonList(value), type);
  }

  public Attribute(String key, String value, AttributeType type) {
    this(new Key(key), new Value(value), type);
  }

  public Attribute(String key, List<String> values, AttributeType type) {
    this(new Key(key), values.stream().map(Value::new).collect(Collectors.toList()), type);
  }

  public Attribute(Key key, Value value) {
    this(key, value, WITH);
  }

  public Attribute(String key, String value) {
    this(new Key(key), new Value(value));
  }

  public Key getKey() {
    return key;
  }

  public List<Value> getValues() {
    return values;
  }

  @Override
  public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

  @Override
  public int hashCode() {
    return Objects.hash(key, values);
  }

  @Override
  public String toString() {
    return "{" +
        "key:" + key +
        ", values:" + values +
        '}';
  }

  public AttributeType getType() {
    return type;
  }

  @Override
  public int compareTo(Attribute o) {
    return key.compareTo(o.key);
  }
}

    if (this == o)
      return true;
    if (o == null || getClass() != o.getClass())
      return false;
    Attribute attribute = (Attribute) o;
    return Objects.equals(key, attribute.key) && Objects.equals(values, attribute.values);
  
<no_super_class>