// ------------------------------------------------------------------------
  // Operation(s)
  // ------------------------------------------------------------------------
  @Override
  public void run(IProgressMonitor monitor) {
    try {
      monitor.worked(1);
      String root = null;
      List<TracePackageElement> resultElementList = new ArrayList<>();
      SubMonitor subMonitor = SubMonitor.convert(monitor, fProfile.getChildren().length * 2);

      List<RemoteImportConnectionNodeElement> connectionNodes =
          fProfile.getConnectionNodeElements();
      for (RemoteImportConnectionNodeElement connectionNode : connectionNodes) {
        RemoteSystemProxy proxy = connectionNode.getRemoteSystemProxy();
        // create new element to decouple from input element
        RemoteImportConnectionNodeElement outputConnectionNode =
            new RemoteImportConnectionNodeElement(
                null, connectionNode.getName(), connectionNode.getURI());
        resultElementList.add(outputConnectionNode);
        for (TracePackageElement element : connectionNode.getChildren()) {
          if (element instanceof RemoteImportTraceGroupElement) {
            ModalContext.checkCanceled(monitor);
            RemoteImportTraceGroupElement traceGroup = (RemoteImportTraceGroupElement) element;
            root = traceGroup.getRootImportPath();
            TracePackageElement[] traceElements = traceGroup.getChildren();
            fTemplatePatternsToTraceElements = generatePatterns(traceElements);
            IRemoteFileService fs =
                proxy.getRemoteConnection().getService(IRemoteFileService.class);
            if (fs == null) {
              continue;
            }

            final IFileStore remoteFolder = fs.getResource(root);

            // make sure that remote directory is read and not cached
            int recursionLevel = 0;
            // create new element to decouple from input element
            RemoteImportTraceGroupElement outputTraceGroup =
                new RemoteImportTraceGroupElement(
                    outputConnectionNode, traceGroup.getRootImportPath());
            outputTraceGroup.setRecursive(traceGroup.isRecursive());
            generateElementsFromArchive(
                outputTraceGroup,
                outputTraceGroup,
                remoteFolder,
                recursionLevel,
                subMonitor.newChild(1));
            filterElements(outputTraceGroup);
          }
        }
      }
      setResultElements(resultElementList.toArray(new TracePackageElement[0]));
      setStatus(Status.OK_STATUS);
    } catch (InterruptedException e) {
      setStatus(Status.CANCEL_STATUS);
    } catch (Exception e) {
      setStatus(
          new Status(
              IStatus.ERROR,
              Activator.PLUGIN_ID,
              NLS.bind(
                  RemoteMessages.RemoteGenerateManifest_GenerateProfileManifestError,
                  fProfile.getText()),
              e));
    }
  }
  /**
   * Scan traceFolder for files that match the patterns specified in the template file. When there
   * is a match, the trace package element is used to determine the trace name and trace type.
   *
   * @param traceGroup The parent trace group element
   * @param parentElement The immediate parent trace group or folder element
   * @param traceFolder The folder to scan
   * @param recursionLevel The recursion level (needed to find directory traces under the
   *     traceFolder
   * @param monitor The progress monitor
   * @throws CoreException Thrown by the file system implementation
   * @throws InterruptedException Thrown if operation was cancelled
   */
  private void generateElementsFromArchive(
      final RemoteImportTraceGroupElement traceGroup,
      final TracePackageElement parentElement,
      final IFileStore traceFolder,
      final int recursionLevel,
      IProgressMonitor monitor)
      throws CoreException, InterruptedException {

    int localRecursionLevel = recursionLevel + 1;
    IFileStore[] sources = traceFolder.childStores(EFS.NONE, monitor);

    for (int i = 0; i < sources.length; i++) {
      ModalContext.checkCanceled(monitor);
      SubMonitor subMonitor = SubMonitor.convert(monitor, sources.length);

      IFileStore fileStore = sources[i];
      IPath fullArchivePath = TmfTraceCoreUtils.newSafePath(fileStore.toURI().getPath());

      IFileInfo sourceInfo = fileStore.fetchInfo();
      if (!sourceInfo.isDirectory()) {

        String rootPathString = traceGroup.getRootImportPath();
        IPath rootPath = TmfTraceCoreUtils.newSafePath(rootPathString);
        IPath relativeTracePath = Path.EMPTY;
        if (rootPath.isPrefixOf(fullArchivePath)) {
          relativeTracePath = fullArchivePath.makeRelativeTo(rootPath);
        }
        Entry<Pattern, TracePackageTraceElement> matchingTemplateEntry =
            getMatchingTemplateElement(relativeTracePath);
        if (matchingTemplateEntry != null) {
          TracePackageTraceElement matchingTemplateElement = matchingTemplateEntry.getValue();
          String traceType = matchingTemplateElement.getTraceType();

          // If a single file is part of a directory trace, use the parent directory instead
          TracePackageElement parent = parentElement;
          if (matchesDirectoryTrace(relativeTracePath, matchingTemplateEntry)) {
            fullArchivePath = fullArchivePath.removeLastSegments(1);
            fDirectoryTraces.add(fullArchivePath);
            fileStore = fileStore.getParent();
            parent = parentElement.getParent();
            // Let the auto-detection choose the best trace type
            traceType = null;
          } else if ((localRecursionLevel > 1) && (!traceGroup.isRecursive())) {
            // Don't consider file traces on level 2 if it's not recursive
            continue;
          }
          String traceName = fullArchivePath.lastSegment();
          String fileName = fileStore.getName();
          // create new elements to decouple from input elements
          TracePackageTraceElement traceElement =
              new TracePackageTraceElement(parent, traceName, traceType);
          RemoteImportTraceFilesElement tracePackageFilesElement =
              new RemoteImportTraceFilesElement(traceElement, fileName, fileStore);
          tracePackageFilesElement.setVisible(false);
        }
      } else {
        if (traceGroup.isRecursive() || localRecursionLevel < 2) {
          RemoteImportFolderElement folder =
              new RemoteImportFolderElement(parentElement, fileStore.getName());
          generateElementsFromArchive(
              traceGroup, folder, fileStore, localRecursionLevel, subMonitor);
        }
      }
    }
  }