@Override
  public void synchronizeScriptPath(ITernScriptPath path, String... forced) {
    TernDoc doc = new TernDoc();
    writeLock.lock();
    try {
      // make sure we do not send duplicate files
      Set<String> requestedFiles = new HashSet<String>(sentFiles.keySet());
      Set<String> perPath = new HashSet<String>();
      syncedFilesPerPath.put(path, perPath);

      requestedFiles.removeAll(Arrays.asList(forced));

      long totalSize = 0;
      for (String file : requestedFiles) {
        totalSize += sentFiles.get(file).length();
      }

      for (ITernScriptResource resource : path.getScriptResources()) {
        // limit the number of files being sent to the Tern server
        if (totalSize >= MAX_ALLOWED_SIZE) {
          sizeExceeded();
          break;
        }
        ITernFile file = resource.getFile();
        if (file == null) {
          continue;
        }
        String name = file.getFullName(getProject());
        perPath.add(name);
        if (!requestedFiles.contains(name)) {
          try {
            TernFile tf = file.toTernServerFile(getProject());
            doc.addFile(tf);
            totalSize += tf.getText().length();
            requestedFiles.add(name);
          } catch (IOException e) {
            getProject().handleException(e);
          }
        }
      }
      // perform actual synchronization with the server
      sendFiles(doc);
    } finally {
      writeLock.unlock();
    }
  }
  @Override
  public void ensureSynchronized() {
    TernDoc doc = new TernDoc();
    writeLock.lock();
    try {
      if (project.getTernServer() != targetServer) {
        targetServer = project.getTernServer();
        cleanIndexedFiles();
      }
      syncedFilesPerPath.clear();

      Set<String> synced = new HashSet<String>(sentFiles.keySet());
      Set<String> toRefreshLocal = new HashSet<String>();
      synchronized (toRefresh) {
        toRefreshLocal.addAll(toRefresh);
        toRefresh.clear();
      }
      synced.removeAll(toRefreshLocal);

      long totalSize = 0;
      for (String file : synced) {
        totalSize += sentFiles.get(file).length();
      }

      for (ITernScriptPath path : getProject().getScriptPaths()) {
        Set<String> perPath = new HashSet<String>();
        syncedFilesPerPath.put(path, perPath);
        for (ITernScriptResource resource : path.getScriptResources()) {
          // limit the size of content being sent to the Tern server
          if (totalSize >= MAX_ALLOWED_SIZE) {

            sendFiles(doc);
            totalSize = 0;
            doc = new TernDoc();
          }
          ITernFile file = resource.getFile();
          if (file == null) {
            continue;
          }
          String name = file.getFullName(getProject());
          perPath.add(name);
          if (!synced.contains(name)) {
            try {
              TernFile tf = file.toTernServerFile(getProject());
              doc.addFile(tf);
              synced.add(name);
              //					System.out.println(name);
              totalSize += tf.getText().length();
            } catch (IOException e) {
              getProject().handleException(e);
            }
          }
        }
      }

      toRefreshLocal.removeAll(synced);
      for (String toRemove : toRefreshLocal) {
        doc.delFile(toRemove);
      }

      // perform actual synchronization with the server
      sendFiles(doc);
    } finally {
      writeLock.unlock();
    }
  }