/**
   * @param sourceStore the file to be copied
   * @param sourceRoot the source root
   * @param destinationRoot the destination root
   * @param monitor the progress monitor
   * @return true if the file is successfully copied, false if the operation did not go through for
   *     any reason
   */
  protected boolean copyFile(
      IFileStore sourceStore,
      IFileStore sourceRoot,
      IFileStore destinationRoot,
      IProgressMonitor monitor) {
    if (sourceStore == null) {
      return false;
    }

    boolean success = true;
    IFileStore[] sourceStores = null, targetStores = null;
    try {
      if (sourceStore.equals(sourceRoot)) {
        // copying the whole source
        sourceStores = sourceRoot.childStores(EFS.NONE, monitor);
        targetStores = new IFileStore[sourceStores.length];
        for (int i = 0; i < targetStores.length; ++i) {
          targetStores[i] = destinationRoot.getChild(sourceStores[i].getName());
        }
      } else if (sourceRoot.isParentOf(sourceStore)) {
        // finds the relative path of the file to be copied and maps to
        // the destination target
        sourceStores = new IFileStore[1];
        sourceStores[0] = sourceStore;

        targetStores = new IFileStore[1];
        String sourceRootPath = sourceRoot.toString();
        String sourcePath = sourceStore.toString();
        int index = sourcePath.indexOf(sourceRootPath);
        if (index > -1) {
          String relativePath = sourcePath.substring(index + sourceRootPath.length());
          targetStores[0] = destinationRoot.getFileStore(new Path(relativePath));
          // makes sure the parent folder is created on the destination side
          IFileStore parent = getFolderStore(targetStores[0]);
          if (parent != targetStores[0]) {
            parent.mkdir(EFS.NONE, monitor);
          }
        }
      }
      if (sourceStores == null) {
        // the file to be copied is not a child of the source root;
        // cannot copy
        success = false;
        sourceStores = new IFileStore[0];
        targetStores = new IFileStore[0];
      }

      for (int i = 0; i < sourceStores.length; ++i) {
        success = copyFile(sourceStores[i], targetStores[i], monitor) && success;
      }
    } catch (CoreException e) {
      // TODO: report the error
      success = false;
    }
    return success;
  }
  private static String validateDestination(IAdaptable destination, IFileStore[] sourceStores) {
    IFileStore destinationStore = getFolderStore(destination);
    IFileStore sourceParentStore;
    for (IFileStore sourceStore : sourceStores) {
      sourceParentStore = sourceStore.getParent();
      if (destinationStore.equals(sourceStore)
          || (sourceParentStore != null && destinationStore.equals(sourceParentStore))) {
        return "The source is already contained in the destination";
      }

      if (sourceStore.isParentOf(destinationStore)) {
        return "Destination cannot be a descendent of the source";
      }
    }
    return null;
  }