DebugLog.log("collecting commitables for " + targetFile);
    public static SVNCommitItem[] harvestCommitables(SVNWCAccess baseAccess, Collection paths, Map lockTokens, boolean justLocked, boolean recursive) throws SVNException {        Map commitables = new TreeMap();        Collection danglers = new HashSet();        Iterator targets = paths.iterator();        do {            String target = targets.hasNext() ? (String) targets.next() : "";            // get entry for target            File targetFile = new File(baseAccess.getAnchor().getRoot(), target);            String targetName = "".equals(target) ? "" : PathUtil.tail(target);            String parentPath = "".equals(target) ? "" : PathUtil.removeTail(target);            if (parentPath.startsWith("/")) {                parentPath = PathUtil.removeLeadingSlash(parentPath);            }            SVNDirectory dir = baseAccess.getDirectory(parentPath);            SVNEntry entry = dir == null ? null : dir.getEntries().getEntry(targetName, false);            String url = null;            if (entry == null) {                SVNErrorManager.error("svn: '" + targetFile + "' is not under version control");            } else if (entry.getURL() == null) {                SVNErrorManager.error("svn: '" + targetFile + "' has no URL");            } else {                url = entry.getURL();            }            if (entry != null && (entry.isScheduledForAddition() || entry.isScheduledForReplacement())) {                // get parent (for file or dir-> get ""), otherwise open parent dir and get "".                SVNEntry parentEntry;                if (!"".equals(targetName)) {                    parentEntry = dir.getEntries().getEntry("", false);                } else {                    File parentFile = targetFile.getParentFile();                    SVNWCAccess parentAccess = SVNWCAccess.create(parentFile);                    parentEntry = parentAccess.getTarget().getEntries().getEntry("", false);                }                if (parentEntry == null) {                    SVNErrorManager.error("svn: '" + targetFile + "' is scheduled for addition within unversioned parent");                } else if (parentEntry.isScheduledForAddition() || parentEntry.isScheduledForReplacement()) {                    danglers.add(targetFile.getParentFile());                }            }            if (entry != null && entry.isCopied() && entry.getSchedule() == null) {                SVNErrorManager.error("svn: Entry for '" + targetFile + "' is marked as 'copied' but is not itself scheduled\n" +                                      "for addition.  Perhaps you're committing a target that is\n" +                                      "inside an unversioned (or not-yet-versioned) directory?");            }            harvestCommitables(commitables, dir, targetFile, null, entry, url, null, false, false, justLocked, lockTokens, recursive);        } while(targets.hasNext());        for (Iterator ds = danglers.iterator(); ds.hasNext();) {            File file = (File) ds.next();            if (!commitables.containsKey(file)) {                SVNErrorManager.error("svn: '" + file + "' is not under version control\n" +                                      "and is not part of the commit, \n" +                                      "yet its child is part of the commit");            }        }        return (SVNCommitItem[]) commitables.values().toArray(new SVNCommitItem[commitables.values().size()]);    }