class HugeProperty<V> implements Property<V>, GraphType {

    protected final HugeElement owner;
    protected final PropertyKey pkey;
    protected final V value;

    public HugeProperty(HugeElement owner, PropertyKey pkey, V value) {
        E.checkArgument(owner != null, "Property owner can't be null");
        E.checkArgument(pkey != null, "Property key can't be null");
        E.checkArgument(value != null, "Property value can't be null");

        this.owner = owner;
        this.pkey = pkey;
        this.value = pkey.validValueOrThrow(value);
    }

    public PropertyKey propertyKey() {
        return this.pkey;
    }

    public Object id() {
        return SplicingIdGenerator.concat(this.owner.id().asString(), this.key());
    }

    @Override
    public HugeType type() {
        return HugeType.PROPERTY;
    }

    @Override
    public String name() {
        return this.pkey.name();
    }

    @Override
    public String key() {
        return this.pkey.name();
    }

    @Override
    public V value() throws NoSuchElementException {
        return this.value;
    }

    public Object serialValue(boolean encodeNumber) {
        return this.pkey.serialValue(this.value, encodeNumber);
    }

    @Override
    public boolean isPresent() {
        return null != this.value;
    }

    public boolean isAggregateType() {
        return !this.pkey.aggregateType().isNone();
    }

    @Override
    public HugeElement element() {
        return this.owner;
    }

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

    @Override
    public int hashCode() {
        return ElementHelper.hashCode(this);
    }

    @Override
    public String toString() {
        return StringFactory.propertyString(this);
    }
}

        if (!(obj instanceof HugeProperty)) {
            return false;
        }

        HugeProperty<?> other = (HugeProperty<?>) obj;
        return this.owner.equals(other.owner) && this.pkey.equals(other.pkey);
    
<no_super_class>