/** {@inheritDoc} */
  @Override
  public void execute() throws NoSuchFileOrDirectory, ExecutionException {
    if (isTrace()) {
      Log.v(TAG, String.format("Deleting directory: %s", this.mPath)); // $NON-NLS-1$
    }

    TFile f = getConsole().buildRealFile(this.mPath);
    if (!f.exists()) {
      if (isTrace()) {
        Log.v(TAG, "Result: FAIL. NoSuchFileOrDirectory"); // $NON-NLS-1$
      }
      throw new NoSuchFileOrDirectory(this.mPath);
    }

    // Check that if the path exist, it need to be a folder. Otherwise something is
    // wrong
    if (f.exists() && !f.isDirectory()) {
      if (isTrace()) {
        Log.v(TAG, "Result: FAIL. ExecutionException"); // $NON-NLS-1$
      }
      throw new ExecutionException("the path exists but is not a folder"); // $NON-NLS-1$
    }

    // Delete the file
    if (!FileHelper.deleteFolder(f)) {
      if (isTrace()) {
        Log.v(TAG, "Result: FAIL. ExecutionException"); // $NON-NLS-1$
      }
      throw new ExecutionException("Failed to delete directory");
    }

    if (isTrace()) {
      Log.v(TAG, "Result: OK"); // $NON-NLS-1$
    }
  }
 /**
  * Method that checks if it is necessary to display a warning dialog because the privileged
  * extraction of a zip file.
  *
  * @param ctx The current context
  * @param task The task
  * @param fso The zip file
  * @hide
  */
 static void checkZipSecurityWarning(
     final Context ctx, final BackgroundAsyncTask task, FileSystemObject fso) {
   // WARNING! Extracting a ZIP file with relatives or absolutes path could break
   // the system and is need a security alert that the user can confirm prior to
   // make the extraction
   String ext = FileHelper.getExtension(fso);
   if (ConsoleBuilder.isPrivileged() && ext.compareToIgnoreCase("zip") == 0) { // $NON-NLS-1$
     AlertDialog dialog =
         DialogHelper.createYesNoDialog(
             ctx,
             R.string.confirm_overwrite,
             R.string.security_warning_extract,
             new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface alertDialog, int which) {
                 if (which == DialogInterface.BUTTON_POSITIVE) {
                   // Execute background task
                   task.execute(task);
                 }
               }
             });
     dialog.show();
   } else {
     // Execute background task
     task.execute(task);
   }
 }
  /**
   * Method that returns to previous activity.
   *
   * @param cancelled Indicates if the activity was cancelled
   * @param item The fso
   * @hide
   */
  void back(final boolean cancelled, FileSystemObject item, boolean isChecked) {
    Intent intent = new Intent();
    if (cancelled) {
      if (SearchActivity.this.mDrawingSearchResultTask != null
          && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
        SearchActivity.this.mDrawingSearchResultTask.cancel(true);
      }
      if (this.mRestoreState != null) {
        intent.putExtra(
            NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA, (Parcelable) this.mRestoreState);
      }
      setResult(RESULT_CANCELED, intent);
    } else {
      // Check that the bookmark exists
      try {
        FileSystemObject fso = item;
        if (!isChecked) {
          fso = CommandHelper.getFileInfo(this, item.getFullPath(), null);
        }
        if (fso != null) {
          if (FileHelper.isDirectory(fso)) {
            intent.putExtra(NavigationActivity.EXTRA_SEARCH_ENTRY_SELECTION, fso);
            intent.putExtra(
                NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA, (Parcelable) createSearchInfo());
            setResult(RESULT_OK, intent);
          } else {
            // Open the file here, so when focus back to the app, the search activity
            // its in top of the stack
            IntentsActionPolicy.openFileSystemObject(this, fso, false, null, null);
            return;
          }
        } else {
          // The fso not exists, delete the fso from the search
          try {
            removeItem(item);
          } catch (Exception ex) {
            /** NON BLOCK* */
          }
        }

      } catch (Exception e) {
        // Capture the exception
        ExceptionUtil.translateException(this, e);
        if (e instanceof NoSuchFileOrDirectory || e instanceof FileNotFoundException) {
          // The fso not exists, delete the fso from the search
          try {
            removeItem(item);
          } catch (Exception ex) {
            /** NON BLOCK* */
          }
        }
        return;
      }
    }
    finish();
  }
 /**
  * Method that returns the supported compression modes
  *
  * @param ctx The current context
  * @param fsos The list of file system objects to compress
  * @return String[] An array with the compression mode labels
  */
 private static String[] getSupportedCompressionModesLabels(
     Context ctx, List<FileSystemObject> fsos) {
   String[] labels = ctx.getResources().getStringArray(R.array.compression_modes_labels);
   if (fsos.size() > 1 || (fsos.size() == 1 && FileHelper.isDirectory(fsos.get(0)))) {
     // If more that a file is requested, compression is not available
     // The same applies if the unique item is a folder
     ArrayList<String> validLabels = new ArrayList<String>();
     CompressionMode[] values = CompressionMode.values();
     int cc = values.length;
     for (int i = 0; i < cc; i++) {
       if (values[i].mArchive) {
         validLabels.add(labels[i]);
       }
     }
     labels = validLabels.toArray(new String[] {});
   }
   return labels;
 }
  /** {@inheritDoc} */
  @Override
  public void onTextChanged(String newValue, List<String> currentFilterData) {
    String value = newValue;

    // Check if directory is valid
    if (value.length() == 0) {
      if (this.mOnValidationListener != null) {
        this.mOnValidationListener.onVoidValue();
      }
    } else {
      boolean relative = FileHelper.isRelativePath(value);
      if (relative) {
        if (this.mOnValidationListener != null) {
          this.mOnValidationListener.onInvalidValue();
        }
      } else {
        if (this.mOnValidationListener != null) {
          this.mOnValidationListener.onValidValue();
        }
      }
    }

    // Ensure data
    if (!value.startsWith(File.separator)) {
      currentFilterData.clear();
      this.mLastParent = ""; // $NON-NLS-1$
      return;
    }

    // Get the new parent
    String newParent = FileHelper.getParentDir(new File(value));
    if (!newParent.endsWith(File.separator)) {
      newParent += File.separator;
    }
    if (value.compareTo(File.separator) == 0) {
      newParent = File.separator;
      currentFilterData.clear();
    } else if (value.endsWith(File.separator)) {
      // Force the change of parent
      newParent = new File(value, "a").getParent(); // $NON-NLS-1$
      if (!newParent.endsWith(File.separator)) {
        newParent += File.separator;
      }
      currentFilterData.clear();
    } else {
      value = newParent;
    }

    // If a new path is detected, then load the new data
    if (newParent.compareTo(this.mLastParent) != 0 || currentFilterData.isEmpty()) {
      this.mLastParent = newParent;
      currentFilterData.clear();
      try {
        List<String> newData = CommandHelper.quickFolderSearch(getContext(), value, null);
        currentFilterData.addAll(newData);
      } catch (Throwable ex) {
        Log.e(TAG, "Quick folder search failed", ex); // $NON-NLS-1$
        currentFilterData.clear();
      }
    }
  }