private Set<FileInfo> filterServeOnlyFiles(Set<FileInfo> filesToRequest) {
    Set<FileInfo> filteredFilesToRequest = new LinkedHashSet<FileInfo>();
    Set<String> cachedFiles = filesCache.getAllFileNames();

    for (FileInfo fileInfo : filesToRequest) {
      if (!fileInfo.isServeOnly()
          || !cachedFiles.contains(fileInfo.getFileName())
          || filesCache.getFileInfo(fileInfo.getFileName()).getTimestamp()
              < fileInfo.getTimestamp()) {
        filteredFilesToRequest.add(fileInfo);
      }
    }
    return filteredFilesToRequest;
  }
  public void uploadFiles(String id, String data) {
    Collection<FileInfo> filesData =
        gson.fromJson(data, new TypeToken<Collection<FileInfo>>() {}.getType());

    for (FileInfo f : filesData) {
      String path = f.getFileName();
      try {
        // Big hack, don't ask my why, but this works on fks.sk
        // Problem is that gson.fromJson mess up encoding.
        CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
        CharsetDecoder decoder = Charset.forName("ISO-8859-1").newDecoder();

        ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(f.getData()));
        CharBuffer cbuf = decoder.decode(bbuf);

        String utf = cbuf.toString();
        f.setData(utf);
        filesCache.addFile(path, f);
      } catch (IOException e) {
      }
    }
  }
  public void startSession(String id, PrintWriter writer) {
    SlaveBrowser browser = capturedBrowsers.getBrowser(id);
    Lock lock = locks.get(id);
    String sessionId = UUID.randomUUID().toString();

    if (lock.tryLock(sessionId)) {
      writer.write(sessionId);
    } else {
      // session is probably staled
      if ((!browser.isCommandRunning() && browser.peekCommand() == null)
          || ((new Date().getTime() - lock.getLastHeartBeat()) > HEARTBEAT_TIMEOUT)) {
        lock.forceUnlock();
        SlaveBrowser slaveBrowser = capturedBrowsers.getBrowser(id);

        slaveBrowser.clearCommandRunning();
        slaveBrowser.clearResponseQueue();
        filesCache.clear();
        writer.write(lock.tryLock(sessionId) ? sessionId : "FAILED");
      } else {
        writer.write("FAILED");
      }
    }
    writer.flush();
  }