@Override
  public DaemonTaskResult executeTask(Log log, DaemonTask task) {

    try {
      switch (task.getMethod()) {
        case Retrieve:
          // Request all torrents from server
          JSONObject result = makeBitfluRequest(log, RPC_TORRENT_LIST);
          return new RetrieveTaskSuccessResult(
              (RetrieveTask) task, parseJsonRetrieveTorrents(result.getJSONArray(JSON_ROOT)), null);
        case GetStats:
          return new GetStatsTaskSuccessResult((GetStatsTask) task, false, -1);
        case Pause:
          makeBitfluRequest(log, RPC_PAUSE_TORRENT + task.getTargetTorrent().getUniqueID());
          return new DaemonTaskSuccessResult(task);
        case Resume:
          makeBitfluRequest(log, RPC_RESUME_TORRENT + task.getTargetTorrent().getUniqueID());
          return new DaemonTaskSuccessResult(task);
        case Remove:
          // Remove a torrent
          RemoveTask removeTask = (RemoveTask) task;
          String removeUriBase = RPC_CANCEL_TORRENT;

          if (removeTask.includingData()) {
            removeUriBase = RPC_REMOVE_TORRENT;
          }
          makeBitfluRequest(log, removeUriBase + task.getTargetTorrent().getUniqueID());
          return new DaemonTaskSuccessResult(task);
        case GetFileList:
          JSONObject jfiles =
              makeBitfluRequest(log, RPC_TORRENT_FILES + task.getTargetTorrent().getUniqueID());
          return new GetFileListTaskSuccessResult(
              (GetFileListTask) task, parseJsonShowFilesTorrent(jfiles.getJSONArray(JSON_ROOT)));
        case AddByUrl:
          String url = URLEncoder.encode(((AddByUrlTask) task).getUrl(), "UTF-8");
          makeBitfluRequest(log, RPC_START_DOWNLOAD + url);
          return new DaemonTaskSuccessResult(task);
        case AddByMagnetUrl:
          String magnet = URLEncoder.encode(((AddByMagnetUrlTask) task).getUrl(), "UTF-8");
          makeBitfluRequest(log, RPC_START_DOWNLOAD + magnet);
          return new DaemonTaskSuccessResult(task);
        default:
          return new DaemonTaskFailureResult(
              task,
              new DaemonException(
                  ExceptionType.MethodUnsupported,
                  task.getMethod() + " is not supported by " + getType()));
      }
    } catch (JSONException e) {
      return new DaemonTaskFailureResult(
          task, new DaemonException(ExceptionType.ParsingFailed, e.toString()));
    } catch (DaemonException e) {
      return new DaemonTaskFailureResult(task, e);
    } catch (UnsupportedEncodingException e) {
      return new DaemonTaskFailureResult(
          task, new DaemonException(ExceptionType.MethodUnsupported, e.toString()));
    }
  }
  @Override
  public DaemonTaskResult executeTask(DaemonTask task) {

    try {
      switch (task.getMethod()) {
        case Retrieve:
          Object result = makeVuzeCall(DaemonMethod.Retrieve, "getDownloads");
          return new RetrieveTaskSuccessResult(
              (RetrieveTask) task, onTorrentsRetrieved(result), null);

        case GetFileList:

          // Retrieve a listing of the files in some torrent
          Object fresult =
              makeVuzeCall(
                  DaemonMethod.GetFileList,
                  "getDiskManagerFileInfo",
                  task.getTargetTorrent(),
                  new Object[] {});
          return new GetFileListTaskSuccessResult(
              (GetFileListTask) task, onTorrentFilesRetrieved(fresult, task.getTargetTorrent()));

        case AddByFile:
          byte[] bytes;
          FileInputStream in = null;
          try {
            // Request to add a torrent by local .torrent file
            String file = ((AddByFileTask) task).getFile();
            in = new FileInputStream(new File(URI.create(file)));
            bytes = new byte[in.available()];
            in.read(bytes, 0, in.available());
            in.close();
          } catch (FileNotFoundException e) {
            return new DaemonTaskFailureResult(
                task, new DaemonException(ExceptionType.FileAccessError, e.toString()));
          } catch (IllegalArgumentException e) {
            return new DaemonTaskFailureResult(
                task, new DaemonException(ExceptionType.FileAccessError, "Invalid local URI"));
          } catch (Exception e) {
            return new DaemonTaskFailureResult(
                task, new DaemonException(ExceptionType.FileAccessError, e.toString()));
          } finally {
            try {
              if (in != null) in.close();
            } catch (IOException e) {
              // Ignore; it was already closed or never opened
            }
          }
          makeVuzeCall(
              DaemonMethod.AddByFile,
              "createFromBEncodedData[byte[]]",
              new String[] {Base16Encoder.encode(bytes)});
          return new DaemonTaskSuccessResult(task);

        case AddByUrl:

          // Request to add a torrent by URL
          String url = ((AddByUrlTask) task).getUrl();
          makeVuzeCall(DaemonMethod.AddByUrl, "addDownload[URL]", new URL[] {new URL(url)});
          return new DaemonTaskSuccessResult(task);

        case Remove:

          // Remove a torrent
          RemoveTask removeTask = (RemoveTask) task;
          if (removeTask.includingData()) {
            makeVuzeCall(
                DaemonMethod.Remove,
                "remove[boolean,boolean]",
                task.getTargetTorrent(),
                new String[] {"true", "true"});
          } else {
            makeVuzeCall(DaemonMethod.Remove, "remove", task.getTargetTorrent(), new Object[] {});
          }
          return new DaemonTaskSuccessResult(task);

        case Pause:

          // Pause a torrent
          makeVuzeCall(DaemonMethod.Pause, "stop", task.getTargetTorrent(), new Object[] {});
          return new DaemonTaskSuccessResult(task);

        case PauseAll:

          // Resume all torrents
          makeVuzeCall(DaemonMethod.ResumeAll, "stopAllDownloads");
          return new DaemonTaskSuccessResult(task);

        case Resume:

          // Resume a torrent
          makeVuzeCall(DaemonMethod.Start, "restart", task.getTargetTorrent(), new Object[] {});
          return new DaemonTaskSuccessResult(task);

        case ResumeAll:

          // Resume all torrents
          makeVuzeCall(DaemonMethod.ResumeAll, "startAllDownloads");
          return new DaemonTaskSuccessResult(task);

        case SetFilePriorities:

          // For each of the chosen files belonging to some torrent, set the priority
          SetFilePriorityTask prioTask = (SetFilePriorityTask) task;
          // One at a time; Vuze doesn't seem to support setting the isPriority or isSkipped on (a
          // subset of) all files at once
          for (TorrentFile forFile : prioTask.getForFiles()) {
            if (prioTask.getNewPriority() == Priority.Off) {
              makeVuzeCall(
                  DaemonMethod.SetFilePriorities,
                  "setSkipped[boolean]",
                  Long.parseLong(forFile.getKey()),
                  new String[] {"true"});
            } else if (prioTask.getNewPriority() == Priority.High) {
              makeVuzeCall(
                  DaemonMethod.SetFilePriorities,
                  "setSkipped[boolean]",
                  Long.parseLong(forFile.getKey()),
                  new String[] {"false"});
              makeVuzeCall(
                  DaemonMethod.SetFilePriorities,
                  "setPriority[boolean]",
                  Long.parseLong(forFile.getKey()),
                  new String[] {"true"});
            } else {
              makeVuzeCall(
                  DaemonMethod.SetFilePriorities,
                  "setSkipped[boolean]",
                  Long.parseLong(forFile.getKey()),
                  new String[] {"false"});
              makeVuzeCall(
                  DaemonMethod.SetFilePriorities,
                  "setPriority[boolean]",
                  Long.parseLong(forFile.getKey()),
                  new String[] {"false"});
            }
          }
          return new DaemonTaskSuccessResult(task);

        case SetTransferRates:

          // Request to set the maximum transfer rates
          SetTransferRatesTask ratesTask = (SetTransferRatesTask) task;
          makeVuzeCall(
              DaemonMethod.SetTransferRates,
              "setBooleanParameter[String,boolean]",
              new Object[] {"Auto Upload Speed Enabled", false});
          makeVuzeCall(
              DaemonMethod.SetTransferRates,
              "setCoreIntParameter[String,int]",
              new Object[] {
                "Max Upload Speed KBs",
                (ratesTask.getUploadRate() == null ? 0 : ratesTask.getUploadRate().intValue())
              });
          makeVuzeCall(
              DaemonMethod.SetTransferRates,
              "setCoreIntParameter[String,int]",
              new Object[] {
                "Max Download Speed KBs",
                (ratesTask.getDownloadRate() == null ? 0 : ratesTask.getDownloadRate().intValue())
              });
          return new DaemonTaskSuccessResult(task);

        default:
          return new DaemonTaskFailureResult(
              task,
              new DaemonException(
                  ExceptionType.MethodUnsupported,
                  task.getMethod() + " is not supported by " + getType()));
      }
    } catch (DaemonException e) {
      return new DaemonTaskFailureResult(task, e);
    } catch (IOException e) {
      return new DaemonTaskFailureResult(
          task, new DaemonException(ExceptionType.ConnectionError, e.toString()));
    }
  }