@NonNull
        private T parseNextRawExpression() throws ParseException {
            final String typeId = ignoreSpecialCharsInTypeIds ?
                    TextUtils.toComparableStringIgnoreCaseAndSpecialChars(parseToNextDelim().trim()) :
                    parseToNextDelim().trim().toLowerCase(Locale.getDefault());

            final LegacyFilterConfig typeConfig = new LegacyFilterConfig();
            if (currentCharIs(CONFIG_SEPARATOR, false)) {
                idx++;
                idx = parseConfiguration(config, idx, typeConfig);
            }
            if (typeId.isEmpty() && isEmpty(typeConfig)) {
                throwParseException("Expression expected, but none was found");
            }

            final T expression;
            if (registeredExpressions.containsKey(typeId)) {
                expression = registeredExpressions.get(typeId).get();
                if (!isEmpty(typeConfig)) {
                    expression.setConfig(typeConfig);
                }
            } else if (registeredExpressions.containsKey("") && isEmpty(typeConfig)) {
                expression = registeredExpressions.get("").get();
                typeConfig.put(null, Collections.singletonList(typeId));
                expression.setConfig(typeConfig);
            } else {
                expression = null; //make compiler happy, value will never be used
                throwParseException("No expression type found for id '" + typeId + "' and no default expression could be applied");
            }

            return Objects.requireNonNull(expression);
        }
Parses next expression starting from idx and leaving idx at next token AFTER expression
main/src/main/java/cgeo/geocaching/utils/config/LegacyFilterConfigParser.java