public void traceProperties() {
        if (level == 0) return;
        CompiledQueryProfile profile = null;
        QueryProfileProperties profileProperties = parent.properties().getInstance(QueryProfileProperties.class);
        if (profileProperties != null)
            profile = profileProperties.getQueryProfile();

        if (profile == null)
            trace("No query profile is used", false, 1);
        else
            trace("Using " + profile, false, 1);

        if (level < 4) return;
        StringBuilder b = new StringBuilder("Resolved properties:\n");
        Set<String> mentioned = new HashSet<>();
        for (Map.Entry<String,String> requestProperty : requestProperties().entrySet() ) {
            Object resolvedValue = parent.properties().get(requestProperty.getKey(), requestProperties());
            if (resolvedValue == null && requestProperty.getKey().equals("queryProfile"))
                resolvedValue = requestProperty.getValue();

            b.append(requestProperty.getKey());
            b.append(": ");
            b.append(resolvedValue); // (may be null)
            b.append(" (");

            if (profile != null && ! profile.isOverridable(new CompoundName(requestProperty.getKey()), requestProperties()))
                b.append("from query profile - unoverridable, ignoring request value");
            else
                b.append("from request");
            b.append(")\n");
            mentioned.add(requestProperty.getKey());
        }
        if (profile != null) {
            appendQueryProfileProperties(profile, mentioned, b);
        }
        trace(b.toString(),false,4);
    }
Traces how properties was resolved and from where. Done after the fact to avoid special handling
of tracelevel, which is the property deciding whether this needs to be done
container-search/src/main/java/com/yahoo/search/query/Trace.java