SVNDebugLog.log(th);
SVNDebugLog.logInfo(th);
    public static Object[] parse(InputStream is, String templateStr, Object[] target) throws SVNException {        if (!is.markSupported()) {            throw new SVNException(                    "SVNReader works only with markable input streams");        }        if (target != null) {            for (int i = 0; i < target.length; i++) {                if (target[i] instanceof Collection || target[i] instanceof Map                        || target[i] instanceof ISVNDirEntryHandler                        || target[i] instanceof ISVNEditor                        || target[i] instanceof OutputStream) {                    continue;                }                target[i] = null;            }        }        StringBuffer template = normalizeTemplate(templateStr);        SVNEditModeReader editorBaton = null;        int targetIndex = 0;        boolean unconditionalThrow = false;        for (int i = 0; i < template.length(); i++) {            char ch = template.charAt(i);            boolean optional = ch == '?' || ch == '*';            boolean multiple = ch == '*';            boolean doRead = Character.isUpperCase(ch)                    && !isListed(INVALID_CARDINALITY_SUBJECTS, ch);            ch = Character.toLowerCase(ch);            if (optional) {                // cardinality                char next = i + 1 < template.length() ? template.charAt(i + 1)                        : '<';                doRead = Character.isUpperCase(next)                        && !isListed(INVALID_CARDINALITY_SUBJECTS, next);                next = Character.toLowerCase(next);                if (isListed(INVALID_CARDINALITY_SUBJECTS, next)) {                    throw new SVNException("malformed template '" + templateStr                            + "' invalid type after cardinality: " + next);                }                i++;                ch = next;            }            is.mark(0x200);            Object result = null;            try {                if (ch == 'b' || ch == 'i' || ch == 's') {                    if (ch == 'b') {                        result = readStringAsBytes(is);                    } else if (ch == 's') {                        result = readString(is);                    } else {                        result = createDelegatingStream(is);                    }                } else if (ch == 'p') {                    readChar(is, '(');                    String name = readString(is);                    String value = null;                    // may not be there                    InputStream is2 = new RollbackInputStream(is);                    is2.mark(0x100);                    try {                        value = readString(is2);                    } catch (SVNException exception) {                        try {                            value = null;                            is2.reset();                        } catch (IOException e1) {                        }                    }                    readChar(is, ')');                    result = new String[] { name, value };                } else if (ch == 'z') {                    readChar(is, '(');                    String name = readString(is);                    String value = null;                    // may not be there                    readChar(is, '(');                    InputStream is2 = new RollbackInputStream(is);                    is2.mark(0x100);                    try {                        value = readString(is2);                    } catch (SVNException exception) {                        try {                            value = null;                            is2.reset();                        } catch (IOException e1) {                        }                    }                    readChar(is, ')');                    readChar(is, ')');                    result = new String[] { name, value };                } else if (ch == 'w') {                    String word = readWord(is);                    result = word;                } else if (ch == 't') {                    result = Boolean.valueOf(readBoolean(is));                } else if (ch == 'n') {                    result = new Long(readNumber(is));                } else if (ch == '[') {                    readChar(is, '(');                    String word = readWord(is);                    if ("failure".equals(word)) {                        // read errors and throw                        readChar(is, '(');                        StringBuffer errorMessage = new StringBuffer();                        RollbackInputStream is2 = new RollbackInputStream(is);                        try {                            while (true) {                                is2.mark(0x5);                                if (errorMessage.length() > 0) {                                    errorMessage.append("\n");                                }                                errorMessage.append(readError(is2));                            }                        } catch (SVNException e) {                            try {                                is2.reset();                                readChar(is2, ')');                                readChar(is2, ')');                            } catch (IOException e1) {                                //                            } catch (SVNException e2) {                                //                            }                        }                        String message = "svn: " + (errorMessage.length() == 0 ?                                 "svnserve reported an error"                                : errorMessage.toString());                        throw new SVNException(message);                    } else if (!"success".equals(word)) {                        throw new SVNException(                                "network data doesn't match template, 'success' or 'failure' expected, '"                                        + word + "' read");                    }                } else if (ch == ')' || ch == ']') {                    readChar(is, ')');                } else if (ch == '(') {                    readChar(is, '(');                } else if (ch == 'd') {                    result = readDirEntry(new RollbackInputStream(is));                } else if (ch == 'f') {                    result = readStatEntry(new RollbackInputStream(is));                } else if (ch == 'e') {                    if (editorBaton == null) {                        editorBaton = new SVNEditModeReader();                        if (target[targetIndex] instanceof ISVNEditor) {                            editorBaton                                    .setEditor((ISVNEditor) target[targetIndex]);                        }                    }                    readChar(is, '(');                    String commandName = readWord(is);                    boolean hasMore;                    try {                        hasMore = editorBaton.processCommand(commandName, is);                    } catch (Throwable th) {                        unconditionalThrow = true;                        SVNDebugLog.log(th);                        if (th instanceof SVNException) {                            throw ((SVNException) th);                        }                        throw new SVNException(th);                    }                    if (!"textdelta-chunk".equals(commandName)) {                        readChar(is, ')');                    }                    if (!hasMore) {                        return target;                    }                } else if (ch == 'x') {                    String word = readWord(is);                    if (!"done".equals(word)) {                        throw new SVNException(                                "netword data doesn't match template, 'done' was expected, but '"                                        + word + "' read.");                    }                } else if (ch == 'l') {                    result = readLock(new RollbackInputStream(is));                }                if (doRead) {                    target = reportResult(target, targetIndex, result, multiple);                }                if (multiple) {                    i -= 2;                } else if (doRead) {                    targetIndex++;                }            } catch (SVNException e) {                if (unconditionalThrow) {                    throw e;                }                try {                    is.reset();                } catch (IOException e1) {                    //                }                if (optional) {                    if (doRead) {                        targetIndex++;                    }                } else {                    throw e;                }            }        }        if (target == null) {            target = new Object[0];        }        return target;    }