private void setInternal(CompoundName key, Object value, Map<String,String> context) {
        GetterSetter propertyAccessor = propertyAccessors.get(key);
        if (propertyAccessor != null && propertyAccessor.setter != null) {
            propertyAccessor.setter.set(query, value);
            return;
        }

        if (key.first().equals(Ranking.RANKING)) {
            if (key.size() > 2) {
                String restKey = key.rest().rest().toString();
                chained().requireSettable(key, value, context);
                if (key.get(1).equals(Ranking.FEATURES)) {
                    setRankFeature(query, restKey, toSpecifiedType(restKey, value,
                            profileRegistry.getTypeRegistry().getComponent("features"),
                            context));
                    return;
                } else if (key.get(1).equals(Ranking.PROPERTIES)) {
                    Ranking ranking = query.getRanking();
                    ranking.getProperties().put(restKey, toSpecifiedType(restKey, value,
                            profileRegistry.getTypeRegistry().getComponent("properties"),
                            context));
                    return;
                }
            }
        }
        if (reservedPrefix.contains(key.first())) {
            // Setting a property under the reserved paths are illegal, while retrieving(get) one is not.
            throwIllegalParameter(key.rest().toString(), key.first());
        } else {
            super.set(key, value, context);
        }
    }
Maps between the query model and text properties.
This can be done simpler by using reflection but the performance penalty was not worth it,
especially since we should be conservative in adding things to the query model.

@author bratseth
container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java