private String substituteArguments(final FrozenSlice slice, final UserDefinedCommandOrEnvironment commandOrEnvironment,
            final UserDefinedCommandOrEnvironmentArgumentSearchResult argumentSearchResult) {
        boolean inEscape = false; /* Whether we are in the middle of a character escape */
        boolean inArgument = false; /* Whether we are inside an argument */
        int index, argumentIndex;
        char c;
        StringBuilder substitutionBuilder = new StringBuilder();
        WorkingDocument sliceDocument = slice.getDocument();
        for (index=slice.startIndex; index<slice.endIndex; index++) {
            c = (char) sliceDocument.charAt(index);
            if (!inEscape && c=='\\') {
                inEscape = true;
                substitutionBuilder.append(c);
            }
            else if (inEscape) {
                inEscape = false;
                substitutionBuilder.append(c);
            }
            else if (c=='#') {
                inArgument = true; /* (Will get actual argument on next iteration) */
            }
            else if (inArgument) {
                /* NB: The argument will already have been checked for sanity */
                inArgument = false;
                argumentIndex = c-'0';
                if (commandOrEnvironment.isAllowingOptionalArgument()) {
                    argumentIndex--;
                }
                if (argumentIndex>0) {
                    /* Required argument */
                    substitutionBuilder.append(argumentSearchResult.requiredArguments[argumentIndex-1]);
                }
                else {
                    /* Optional argument */
                    substitutionBuilder.append(argumentSearchResult.optionalArgument!=null ? argumentSearchResult.optionalArgument : commandOrEnvironment.getOptionalArgument());
                }
            }
            else {
                substitutionBuilder.append(c);
            }
        }
        return substitutionBuilder.toString();
    }