public void parseFile(final Uri uri, String readOnlyContext, Map<String, String> keyValues) {
        final InputStream is = ContentStorage.get().openForRead(uri);
        if (is == null) {
            throw new IllegalArgumentException("profile " + uri + " does not exist");
        }
        try {
            if (readOnlyContext != null) {
                linenr = 1;
                final String realContext = context;
                context = readOnlyContext;

                final InputStream is2 = ContentStorage.get().openForRead(uri);
                expressionList = parseFileHelper(is2, keyValues);
                variableData = new float[variableNumbers.size()];
                evaluate(lookupData); // lookupData is dummy here - evaluate just to create the variables
                context = realContext;
            }
            linenr = 1;
            minWriteIdx = variableData == null ? 0 : variableData.length;

            expressionList = parseFileHelper(is, null);
            lastAssignedExpression = null;

            // determine the build-in variable indices
            final String[] varNames = getBuildInVariableNames();
            nBuildInVars = varNames.length;
            buildInVariableIdx = new int[nBuildInVars];
            for (int vi = 0; vi < varNames.length; vi++) {
                buildInVariableIdx[vi] = getVariableIdx(varNames[vi], false);
            }

            final float[] readOnlyData = variableData;
            variableData = new float[variableNumbers.size()];
            for (int i = 0; i < minWriteIdx; i++) {
                variableData[i] = readOnlyData[i];
            }
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("ParseException " + uri.toString() + " at line " + linenr + ": " + e.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (expressionList.isEmpty()) {
            throw new IllegalArgumentException("profile does not contain expressions for context " + context + " (old version?)");
        }
    }
add a new lookup-value for the given name to the given lookupData array.
If no array is given (null value passed), the value is added to
the context-binded array. In that case, unknown names and values are
created dynamically.

@return a newly created value element, if any, to optionally add aliases
main/src/main/java/cgeo/geocaching/brouter/expressions/BExpressionContext.java