Example usage for java.util LinkedList removeFirst

List of usage examples for java.util LinkedList removeFirst

Introduction

In this page you can find the example usage for java.util LinkedList removeFirst.

Prototype

public E removeFirst() 

Source Link

Document

Removes and returns the first element from this list.

Usage

From source file:com.trsst.Command.java

public int doBegin(String[] argv, PrintStream out, InputStream in) {

    buildOptions(argv, out, in);//  w  ww.  ja v  a 2s  . co  m

    int result = 0;
    Server server = null;
    try {

        CommandLineParser argParser = new GnuParser();
        CommandLine commands;
        try {
            commands = argParser.parse(mergedOptions, argv);
        } catch (Throwable t) {
            log.error("Unexpected error parsing arguments: " + Arrays.asList(argv), t);
            return 127;
        }
        LinkedList<String> arguments = new LinkedList<String>();
        for (Object o : commands.getArgList()) {
            arguments.add(o.toString()); // dodge untyped param warning
        }
        if (commands.hasOption("?")) {
            printAllUsage();
            return 0;
        }
        if (arguments.size() < 1) {
            printAllUsage();
            return 127; // "command not found"
        }
        if (!commands.hasOption("strict")) {
            // most trsst nodes run with self-signed certificates,
            // so by default we accept them
            Common.enableAnonymousSSL();
        } else {
            System.err.println("Requiring signed SSL");
        }
        // System.out.println("Commands: " + arguments );
        String mode = arguments.removeFirst().toString();

        // for port requests
        if ("serve".equals(mode)) {
            // start a server and exit
            result = doServe(commands, arguments);
            return 0;
        }

        // attempt to parse next argument as a server url
        Client client = null;
        if (commands.hasOption("h")) {
            String host = commands.getOptionValue("h");
            try {
                URL url = new URL(host);
                // this argument is a server url
                client = new Client(url);
                System.err.println("Using service: " + host);
            } catch (MalformedURLException e) {
                // otherwise: ignore and continue
                System.err.println("Bad hostname: " + host);
            }
        }

        // if a server url wasn't specified
        if (client == null) {
            // start a client with a local server
            server = new Server();
            client = new Client(server.getServiceURL());
            System.err.println("Starting temporary service at: " + server.getServiceURL());
        }

        if ("pull".equals(mode)) {
            // pull feeds from server
            result = doPull(client, commands, arguments, out);
        } else if ("push".equals(mode)) {
            // push feeds to server
            result = doPush(client, commands, arguments, out);
        } else if ("post".equals(mode)) {
            // post (and push) entries
            result = doPost(client, commands, arguments, out, in);
        } else {
            printAllUsage();
            result = 127; // "command not found"
        }
    } catch (Throwable t) {
        log.error("Unexpected error: " + t, t);
        result = 1; // "catchall for general errors"
    }
    if (server != null) {
        server.stop();
    }
    return result;
}

From source file:ru.codeinside.gses.activiti.forms.definitions.FormParser.java

void processBlocks(Map<String, PropertyParser> nodes, List<PropertyParser> rootList) throws BuildException {
    final ArrayList<PropertyParser> allPropertyParsers = new ArrayList<PropertyParser>(nodes.values());
    final LinkedList<BlockStartParser> stack = new LinkedList<BlockStartParser>();
    for (final PropertyParser propertyParser : allPropertyParsers) {
        final BlockStartParser block = stack.peekFirst();
        propertyParser.block = block;//w w  w  .j  av  a  2 s.  c  o  m
        final boolean end = (propertyParser instanceof EndBlockParser);
        if (!end) {
            if (block == null) {
                if (!(propertyParser instanceof SignatureParser)) {
                    rootList.add(propertyParser);
                }
            } else {
                block.items.add(propertyParser);
            }
            if (propertyParser instanceof BlockStartParser) {
                final BlockStartParser start = (BlockStartParser) propertyParser;
                start.items = new ArrayList<PropertyParser>();
                stack.addFirst(start);
            }
        } else {
            if (block == null
                    || !block.property.id.substring(1).equals(propertyParser.property.id.substring(1))) {
                throw new BuildException("   ",
                        propertyParser);
            }
            stack.removeFirst();
        }
    }

    PropertyParser badStart = stack.peekFirst();
    if (badStart != null) {
        throw new BuildException("?   ?", badStart);
    }

    for (PropertyParser propertyParser : allPropertyParsers) {
        if (propertyParser instanceof BlockStartParser) {
            final BlockStartParser start = (BlockStartParser) propertyParser;
            if (start.items.isEmpty()) {
                throw new BuildException("? ", propertyParser);
            }
        }
    }
}

From source file:mergedoc.core.Comment.java

/**
 * JDK1.5  API ???? pre HTML ??/*w  w w  .  j a v a  2 s . c  o  m*/
 * ???????????Java ?????
 * ????pre ????????????? API ?
 * ???
 */
private void replacePreBody() {

    // pre ??????????
    if (!docBody.contains("<pre>")) {
        return;
    }

    // Java ? pre ??
    LinkedList<String> pres = null;
    String commentBody = FastStringUtils.replaceAll(srcBody, "(?m)^\\s*\\*( |)", "");
    Pattern pat = PatternCache.getPattern("(?s)(<pre>\n)(.+?)(\n</pre>)");
    Matcher mat = pat.matcher(commentBody);
    while (mat.find()) {
        if (pres == null) {
            pres = new LinkedList<String>();
        }
        pres.add(mat.group(2));
    }
    if (pres == null) {
        return;
    }

    // API ? pre ?? Java ???
    Matcher descMatcher = pat.matcher(docBody);
    StringBuffer sb = new StringBuffer();
    while (descMatcher.find()) {

        // pre ??????????
        if (pres.size() == 0) {
            return;
        }
        String value = FastStringUtils.quoteReplacement(pres.removeFirst());
        descMatcher.appendReplacement(sb, "$1" + value + "$3");
    }
    descMatcher.appendTail(sb);

    // pre ????????
    if (pres.size() == 0) {
        docBody = sb.toString();
    }
}

From source file:org.opennms.netmgt.eventd.adaptors.tcp.TcpStreamHandler.java

/**
 * The main execution context for processing a remote XML document. Once the
 * document is processed and an event receipt is returned to the client the
 * thread will exit.//ww w . j  av a2s .  c om
 */
@Override
public void run() {
    // get the context and stop if necessary
    m_context = Thread.currentThread();
    synchronized (m_context) {
        m_context.notifyAll();
    }

    // check the stop flag
    if (m_stop) {
        LOG.debug("The stop flag was set prior to thread entry, closing connection");
        try {
            m_connection.close();
        } catch (final IOException e) {
            LOG.error("An error occured while closing the connection.", e);
        }

        LOG.debug("Thread context exiting");

        return;
    }

    // Log the startup of this stream handler
    final InetAddress sender = m_connection.getInetAddress();
    LOG.debug("Event Log Stream Handler Started for {}", sender);

    /*
     * This linked list is used to exchange
     * instances of PipedOutputStreams. Whenever a
     * pipe output stream is recovered it must be
     * signaled to inform the EOT thread of the
     * ability to write to the pipe. Also, when
     * the descriptor is close a EOFException is
     * passed on the list.
     */
    final LinkedList<Object> pipeXchange = new LinkedList<Object>();
    final TcpRecordHandler chunker = new TcpRecordHandler(m_connection, pipeXchange);
    final Thread tchunker = new Thread(chunker, "TCPRecord Chunker["
            + InetAddressUtils.str(m_connection.getInetAddress()) + ":" + m_connection.getPort() + "]");
    synchronized (tchunker) {
        tchunker.start();
        try {
            tchunker.wait();
        } catch (final InterruptedException e) {
            LOG.error("The thread was interrupted.", e);
        }
    }

    MAINLOOP: while (!m_stop && m_parent.getStatus() != Fiber.STOP_PENDING
            && m_parent.getStatus() != Fiber.STOPPED && m_recsPerConn != 0) {
        // get a new pipe input stream
        PipedInputStream pipeIn = null;
        synchronized (pipeXchange) {
            while (pipeXchange.isEmpty()) {
                if (chunker.isAlive()) {
                    try {
                        pipeXchange.wait(500);
                    } catch (final InterruptedException e) {
                        LOG.error("The thread was interrupted.", e);
                        break MAINLOOP;
                    }
                } else {
                    break MAINLOOP;
                }
            }

            // if an exception occured then just exit the BAL (Big Ass Loop)
            final Object o = pipeXchange.removeFirst();
            if (o instanceof Throwable) {
                break MAINLOOP;
            }

            // construct the other end of the pipe
            try {
                pipeIn = new PipedInputStream((PipedOutputStream) o);
            } catch (final IOException e) {
                LOG.error("An I/O exception occured construction a record reader.", e);
                break MAINLOOP;
            }

            // signal that we got the stream
            synchronized (o) {
                o.notify();
            }
        }

        // decrement the record count if greater than zero
        m_recsPerConn -= (m_recsPerConn > 0 ? 1 : 0);

        // convert the pipe input stream into a buffered input stream
        final InputStream stream = new BufferedInputStream(pipeIn);

        // Unmarshal the XML document
        Log eLog = null;
        boolean doCleanup = false;
        try {
            eLog = JaxbUtils.unmarshal(Log.class, new InputSource(stream));
            LOG.debug("Event record converted");
        } catch (final Exception e) {
            LOG.error("Could not unmarshall the XML record.", e);
            doCleanup = true;
        } finally {
            if (stream != null) {
                IOUtils.closeQuietly(stream);
            }
        }

        // clean up the data on the current pipe if necessary
        if (doCleanup) {
            /*
             * Cleanup a failed record. Need to read
             * the remaining bytes from the other thread
             * to synchronize up. The other thread might
             * be blocked writing.
             */
            try {
                while (stream.read() != -1) {
                    /* do nothing */;
                }
            } catch (final IOException e) {
                // do nothing
            }

            // start from the top!
            continue MAINLOOP;
        }

        // Now that we have a list of events, process them
        final Event[] events = eLog.getEvents().getEvent();

        // sort the events by time
        Arrays.sort(events, new Comparator<Event>() {
            @Override
            public int compare(final Event e1, final Event e2) {
                final boolean e1t = (e1.getTime() != null);
                final boolean e2t = (e2.getTime() != null);
                if (e1t && !e2t) {
                    return 1;
                } else if (!e1t && e2t) {
                    return -1;
                } else if (!e1t && !e2t) {
                    return 0;
                }

                Date de1 = e1.getTime();
                Date de2 = e2.getTime();

                if (de1 != null && de2 != null) {
                    return (int) (de1.getTime() - de2.getTime());
                } else if (de1 == null && de2 != null) {
                    return -1;
                } else if (de1 != null && de2 == null) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        // process the events
        if (events != null && events.length != 0) {
            final List<Event> okEvents = new ArrayList<Event>(events.length);

            /*
             * This synchronization loop will hold onto the lock
             * for a while. If the handlers are going to change
             * often, which is shouldn't then might want to consider
             * duplicating the handlers into an array before processing
             * the events.
             *
             * Doing the synchronization in the outer loop prevents spending
             * lots of cycles doing synchronization when it should not
             * normally be necesary.
             */
            synchronized (m_handlers) {
                for (final EventHandler hdl : m_handlers) {
                    /*
                     * get the handler and then have it process all
                     * the events in the document before moving to the
                     * next event handler.
                     */
                    for (final Event event : events) {
                        /*
                         * Process the event and log any errors,
                         *  but don't die on these errors
                         */
                        try {
                            LOG.debug("handling event: {}", event);

                            // shortcut and BOTH parts MUST execute!
                            if (hdl.processEvent(event)) {
                                if (!okEvents.contains(event)) {
                                    okEvents.add(event);
                                }
                            }
                        } catch (final Throwable t) {
                            LOG.warn("An exception occured while processing an event.", t);
                        }
                    }
                }
            }

            // Now process the good events and send a receipt message
            boolean hasReceipt = false;
            final EventReceipt receipt = new EventReceipt();

            for (final Event event : okEvents) {
                if (event.getUuid() != null) {
                    receipt.addUuid(event.getUuid());
                    hasReceipt = true;
                }
            }

            if (hasReceipt) {
                // Transform it to XML and send it to the socket in one call
                try {
                    final Writer writer = new BufferedWriter(
                            new OutputStreamWriter(m_connection.getOutputStream(), "UTF-8"));
                    JaxbUtils.marshal(receipt, writer);
                    writer.flush();

                    synchronized (m_handlers) {
                        for (final EventHandler hdl : m_handlers) {
                            /*
                             * Get the handler and then have it process all
                             * the events in the document before moving to
                             * the next event hander.
                             */
                            try {
                                hdl.receiptSent(receipt);
                            } catch (final Throwable t) {
                                LOG.warn("An exception occured while processing an event receipt.", t);
                            }
                        }
                    }

                    if (LOG.isDebugEnabled()) {
                        try {
                            final StringWriter swriter = new StringWriter();
                            JaxbUtils.marshal(receipt, swriter);

                            LOG.debug("Sent Event Receipt {");
                            LOG.debug(swriter.getBuffer().toString());
                            LOG.debug("}");
                        } catch (final Throwable e) {
                            LOG.error("An error occured during marshalling of event receipt for the log.", e);
                        }
                    }
                } catch (final IOException e) {
                    LOG.warn("Failed to send event-receipt XML document.", e);
                    break MAINLOOP;
                }
            }
        } else {
            LOG.debug("The agent sent an empty event stream");
        }
    }

    try {
        LOG.debug("stopping record handler");

        chunker.stop();

        LOG.debug("record handler stopped");
    } catch (final InterruptedException e) {
        LOG.warn("The thread was interrupted while trying to close the record handler.", e);
    }

    // regardless of any errors, be sure to release the socket.
    try {
        LOG.debug("closing connnection");

        m_connection.close();

        LOG.debug("connnection closed ");
    } catch (final IOException e) {
        LOG.warn("An I/O exception occured while closing the TCP/IP connection.", e);
    }

    LOG.debug("Thread exiting");
}

From source file:de.tudarmstadt.ukp.wikipedia.parser.mediawiki.ModularParser.java

private void getLineSpans(SpanManager sm, LinkedList<Span> lineSpans) {
    sm.manageList(lineSpans);/*  www.j a  v  a2  s  .  co m*/

    int start = 0;
    int end;

    while ((end = sm.indexOf(lineSeparator, start)) != -1) {
        lineSpans.add(new Span(start, end).trimTrail(sm));
        start = end + lineSeparator.length();
    }
    lineSpans.add(new Span(start, sm.length()).trimTrail(sm));

    while (!lineSpans.isEmpty() && lineSpans.getFirst().length() == 0) {
        lineSpans.removeFirst();
    }
    while (!lineSpans.isEmpty() && lineSpans.getLast().length() == 0) {
        lineSpans.removeLast();
    }
}

From source file:de.tudarmstadt.ukp.wikipedia.parser.mediawiki.ModularParser.java

private Table buildTable(SpanManager sm, ContentElementParsingParameters cepp, LinkedList<Span> lineSpans) {

    Table result = new Table();
    int col = -1;
    int row = 0;//from  w  w  w  .  ja  v  a2  s.  c  o m
    int subTables = 0;
    LinkedList<Span> tableDataSpans = new LinkedList<Span>();
    sm.manageList(tableDataSpans);

    if (calculateSrcSpans) {
        result.setSrcSpan(new SrcSpan(sm.getSrcPos(lineSpans.getFirst().getStart()), -1));
    }

    lineSpans.removeFirst();

    while (!lineSpans.isEmpty()) {
        Span s = lineSpans.removeFirst();

        int pos = s.nonWSCharPos(sm);
        char c0 = s.charAt(pos, sm);
        char c1 = s.charAt(pos + 1, sm);

        if (subTables == 0 && (c0 == '!' || c0 == '|')) {
            if (!tableDataSpans.isEmpty()) {
                lineSpans.addFirst(s);

                SrcSpan ei = null;
                if (calculateSrcSpans) {
                    ei = new SrcSpan(sm.getSrcPos(tableDataSpans.getFirst().getStart() - 1) + 1, -1);
                }

                TableElement te = new TableElement(parseSections(sm, cepp, tableDataSpans), row, col);
                te.setSrcSpan(ei);
                result.addTableElement(te);
                lineSpans.removeFirst();
            }

            col++;
            if (c1 == '-') {
                row++;
                col = -1;
                continue;
            } else if (c0 == '|' && c1 == '}') {
                sm.removeManagedList(tableDataSpans);

                if (calculateSrcSpans) {
                    result.getSrcSpan().setEnd(sm.getSrcPos(s.getEnd()));
                }

                return result;
            } else if (c0 == '|' && c1 == '+') {
                result.setTitleElement(
                        parseContentElement(sm, cepp, new Span(s.getStart() + pos + 2, s.getEnd()).trim(sm)));
                continue;
            } else {
                int multipleCols;
                if ((multipleCols = sm.indexOf("||", s.getStart() + pos + 1, s.getEnd())) != -1) {
                    lineSpans.addFirst(new Span(multipleCols + 1, s.getEnd()));
                    s.setEnd(multipleCols);
                }

                int optionTagPos = sm.indexOf("|", s.getStart() + pos + 1, s.getEnd());

                if (optionTagPos != -1) {
                    s.setStart(optionTagPos + 1).trim(sm);
                } else {
                    s.adjustStart(pos + 1).trim(sm);
                }
            }
        } else if (c0 == '|' && c1 == '}') {
            subTables--;
        } else if (c0 == '{' && c1 == '|') {
            subTables++;
        }

        tableDataSpans.addLast(s);
    }

    if (tableDataSpans.size() != 0) {

        SrcSpan ei = null;
        if (calculateSrcSpans) {
            ei = new SrcSpan(sm.getSrcPos(tableDataSpans.getFirst().getStart() - 1) + 1, -1);
        }

        TableElement te = new TableElement(parseSections(sm, cepp, tableDataSpans), row, col);
        te.setSrcSpan(ei);

        result.addTableElement(te);
    }

    sm.removeManagedList(tableDataSpans);

    if (calculateSrcSpans) {
        result.getSrcSpan().setEnd(-1);
    }

    return result;
}

From source file:org.opendatakit.aggregate.odktables.api.perf.AggregateSynchronizer.java

/**
 * Get all the files under the given folder, excluding those directories that
 * are the concatenation of folder and a member of excluding. If the member of
 * excluding is a directory, none of its children will be synched either.
 * <p>//from  www  . java  2s .co  m
 * If the folder doesn't exist it returns an empty list.
 * <p>
 * If the file exists but is not a directory, logs an error and returns an
 * empty list.
 * 
 * @param folder
 * @param excluding
 *          can be null--nothing will be excluded. Should be relative to the
 *          given folder.
 * @param relativeTo
 *          the path to which the returned paths will be relative. A null
 *          value makes them relative to the folder parameter. If it is non
 *          null, folder must start with relativeTo, or else the files in
 *          folder could not possibly be relative to relativeTo. In this case
 *          will throw an IllegalArgumentException.
 * @return the relative paths of the files under the folder--i.e. the paths
 *         after the folder parameter, not including the first separator
 * @throws IllegalArgumentException
 *           if relativeTo is not a substring of folder.
 */
private List<String> getAllFilesUnderFolder(File baseFolder, final Set<String> excludingNamedItemsUnderFolder) {
    String appName = ODKFileUtils.extractAppNameFromPath(baseFolder);

    // Return an empty list of the folder doesn't exist or is not a directory
    if (!baseFolder.exists()) {
        return new ArrayList<String>();
    } else if (!baseFolder.isDirectory()) {
        logger.error("[getAllFilesUnderFolder] folder is not a directory: " + baseFolder.getAbsolutePath());
        return new ArrayList<String>();
    }

    // construct the set of starting directories and files to process
    File[] partials = baseFolder.listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            if (excludingNamedItemsUnderFolder == null) {
                return true;
            } else {
                return !excludingNamedItemsUnderFolder.contains(pathname.getName());
            }
        }
    });

    if (partials == null) {
        return Collections.emptyList();
    }

    LinkedList<File> unexploredDirs = new LinkedList<File>();
    List<File> nondirFiles = new ArrayList<File>();

    // copy the starting set into a queue of unexploredDirs
    // and a list of files to be sync'd
    for (int i = 0; i < partials.length; ++i) {
        if (partials[i].isDirectory()) {
            unexploredDirs.add(partials[i]);
        } else {
            nondirFiles.add(partials[i]);
        }
    }

    while (!unexploredDirs.isEmpty()) {
        File exploring = unexploredDirs.removeFirst();
        File[] files = exploring.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                // we'll need to explore it
                unexploredDirs.add(f);
            } else {
                // we'll add it to our list of files.
                nondirFiles.add(f);
            }
        }
    }

    List<String> relativePaths = new ArrayList<String>();
    // we want the relative path, so drop the necessary bets.
    for (File f : nondirFiles) {
        // +1 to exclude the separator.
        relativePaths.add(ODKFileUtils.asRelativePath(appName, f));
    }
    return relativePaths;
}

From source file:uk.ac.diamond.scisoft.analysis.rcp.inspector.InspectionTab.java

final public int[] getOrder(int rank) {
    if (rank == 1)
        return new int[] { 0 };

    LinkedList<Integer> orders = new LinkedList<Integer>();
    for (int i = 0; i < rank; i++)
        orders.add(i);//  w  ww .j  ava2  s .c o  m

    int[] cOrder = new int[rank];
    int i = 0;
    for (PlotAxisProperty p : paxes) {
        if (!p.isInSet())
            continue;

        int d = p.getDimension();
        cOrder[i++] = d;
        orders.remove((Integer) d);
    }

    for (; i < rank; i++) {
        int d = orders.removeFirst();
        cOrder[i] = d;
    }
    return cOrder;
}

From source file:org.fusesource.mop.support.MethodCommandDefinition.java

@Override
public void executeCommand(MOP mop, LinkedList<String> argList) throws Exception {
    // lets inject fields
    for (Class<? extends Object> beanType = bean.getClass(); beanType != Object.class; beanType = beanType
            .getSuperclass()) {/* w w  w.  java 2s  . c  o m*/
        Field[] fields = beanType.getDeclaredFields();
        for (Field field : fields) {
            Lookup lookup = field.getAnnotation(Lookup.class);
            if (lookup != null) {
                Class<?> type = field.getType();
                Object value = mop.getContainer().lookup(type);
                if (value != null) {
                    field.setAccessible(true);
                    field.set(bean, value);
                }
            }
        }
    }

    Class<?>[] paramTypes = method.getParameterTypes();
    int size = paramTypes.length;
    Object[] args = new Object[size];
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();

    for (int i = 0; i < size; i++) {
        Class<?> paramType = paramTypes[i];
        if (MOP.class.isAssignableFrom(paramType)) {
            args[i] = mop;
        } else if (Iterable.class.isAssignableFrom(paramType)) {
            // lets assume its the command arguments
            args[i] = argList;
        } else {
            if (argList.isEmpty()) {
                // lets look and see if we should allow a null
                Annotation[] annotations = parameterAnnotations[i];
                if (isOptionalValue(annotations)) {
                    continue;
                }
                // TODO we need to find the name of the parameter to log better!
                throw new Exception("missing argument!");
            }

            // now lets extract the actual arguments
            if (Artifacts.class.isAssignableFrom(paramType)) {
                args[i] = mop.getArtifacts(argList);
            } else if (paramType == File.class) {
                args[i] = new File(argList.removeFirst());
            } else if (paramType == String.class) {
                args[i] = argList.removeFirst();
            } else {
                throw new Exception("Unable to inject type " + paramType.getName() + " from arguments "
                        + argList + " for method " + method);
            }
        }

    }

    if (bean instanceof ConfiguresMop) {
        ConfiguresMop configuresMop = (ConfiguresMop) bean;
        configuresMop.configure(mop);
    }
    try {
        method.invoke(bean, args);
    } catch (Exception e) {
        LOG.error("Failed to invoke " + method + " with args " + Arrays.asList(args) + " due to: " + e, e);
        throw e;
    }
}

From source file:org.opendatakit.sync.aggregate.AggregateSynchronizer.java

/**
 * Get all the files under the given folder, excluding those directories
 * that are the concatenation of folder and a member of excluding. If the
 * member of excluding is a directory, none of its children will be synched
 * either./*  w ww  .  java2 s.  co  m*/
 * <p>
 * If the folder doesn't exist it returns an empty list.
 * <p>
 * If the file exists but is not a directory, logs an error and returns an
 * empty list.
 * 
 * @param folder
 * @param excluding
 *            can be null--nothing will be excluded. Should be relative to
 *            the given folder.
 * @param relativeTo
 *            the path to which the returned paths will be relative. A null
 *            value makes them relative to the folder parameter. If it is
 *            non null, folder must start with relativeTo, or else the files
 *            in folder could not possibly be relative to relativeTo. In
 *            this case will throw an IllegalArgumentException.
 * @return the relative paths of the files under the folder--i.e. the paths
 *         after the folder parameter, not including the first separator
 * @throws IllegalArgumentException
 *             if relativeTo is not a substring of folder.
 */
private List<String> getAllFilesUnderFolder(File baseFolder, final Set<String> excludingNamedItemsUnderFolder) {

    String appName = ODKFileUtils.extractAppNameFromPath(baseFolder);

    // Return an empty list of the folder doesn't exist or is not a
    // directory
    if (!baseFolder.exists()) {
        return new ArrayList<String>();
    } else if (!baseFolder.isDirectory()) {
        log.e(LOGTAG, "[getAllFilesUnderFolder] folder is not a directory: " + baseFolder.getAbsolutePath());
        return new ArrayList<String>();
    }

    // construct the set of starting directories and files to process
    File[] partials = baseFolder.listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            if (excludingNamedItemsUnderFolder == null) {
                return true;
            } else {
                return !excludingNamedItemsUnderFolder.contains(pathname.getName());
            }
        }
    });

    if (partials == null) {
        return Collections.emptyList();
    }

    LinkedList<File> unexploredDirs = new LinkedList<File>();
    List<File> nondirFiles = new ArrayList<File>();

    // copy the starting set into a queue of unexploredDirs
    // and a list of files to be sync'd
    for (int i = 0; i < partials.length; ++i) {
        if (partials[i].isDirectory()) {
            unexploredDirs.add(partials[i]);
        } else {
            nondirFiles.add(partials[i]);
        }
    }

    while (!unexploredDirs.isEmpty()) {
        File exploring = unexploredDirs.removeFirst();
        File[] files = exploring.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                // we'll need to explore it
                unexploredDirs.add(f);
            } else {
                // we'll add it to our list of files.
                nondirFiles.add(f);
            }
        }
    }

    List<String> relativePaths = new ArrayList<String>();
    // we want the relative path, so drop the necessary bets.
    for (File f : nondirFiles) {
        // +1 to exclude the separator.
        relativePaths.add(ODKFileUtils.asRelativePath(appName, f));
    }
    return relativePaths;
}