docs: public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
  		if (target == null) {
  			throw new AccessException("Cannot read property of null target");
  		}
  		if (target instanceof InternalFeature) {
  			InternalFeature feature = (InternalFeature) target;
  			if (feature.getAttributes().containsKey(name)) {
  				Attribute<?> attribute = feature.getAttributes().get(name);
  				return new TypedValue(attribute.getValue());
  			} else if (ID_PROPERTY_NAME.equalsIgnoreCase(ID_PROPERTY_NAME)) {
  				return new TypedValue(feature.getId());
  			} else {
  				throw new AccessException("Unknown attribute " + name + "for layer " + feature.getLayer().getId());
  			}
  		} else if (target instanceof AssociationValue) {
  			AssociationValue associationValue = (AssociationValue) target;
  			if (associationValue.getAllAttributes().containsKey(name)) {
  				Attribute<?> attribute = associationValue.getAllAttributes().get(name);
  				return new TypedValue(attribute.getValue());
  			} else if (ID_PROPERTY_NAME.equalsIgnoreCase(ID_PROPERTY_NAME)) {
  				Attribute<?> attribute = associationValue.getId();
  				return new TypedValue(attribute.getValue());
  			} else {
  				throw new AccessException("Unknown attribute " + name + " for association " + target);
  			}
  		} else {
  			throw new AccessException("Cannot read property " + name + "from class " + target.getClass());
  		}
  	}