@NotNull
  @Override
  public Set<CustomTaskState> getAvailableTaskStates(@NotNull Task task) throws Exception {
    final Hashtable<String, ?> response = new BugzillaXmlRpcRequest("Bug.fields")
      .withParameter("names", newVector("bug_status", "resolution"))
      .requireAuthentication(true)
      .execute();
    final Vector<Hashtable<String, ?>> fields = (Vector<Hashtable<String, ?>>)response.get("fields");
    final Hashtable<String, ?> statusesInfo = fields.get(0);
    final Hashtable<String, ?> resolutionsInfo = fields.get(1);
    final List<String> resolutions = extractNotEmptyNames((Vector<Hashtable<String, ?>>)resolutionsInfo.get("values"));

    class Status {
      final boolean isOpen;
      final String name;
      final Iterable<String> canChangeTo;

      Status(String name, boolean isOpen, Iterable<String> canChangeTo) {
        this.isOpen = isOpen;
        this.name = name;
        this.canChangeTo = canChangeTo;
      }
    }

    final Map<String, Status> statuses = new HashMap<>();
    for (Hashtable<String, ?> statusInfo : (Vector<Hashtable<String, ?>>)statusesInfo.get("values")) {
      final String name = (String)statusInfo.get("name");
      if (StringUtil.isEmpty(name)) {
        continue;
      }

      final List<String> targetStateNames = extractNotEmptyNames((Vector<Hashtable<String, ?>>)statusInfo.get("can_change_to"));
      statuses.put(name, new Status(name, (Boolean)statusInfo.get("is_open"), targetStateNames));
    }
    final String currentState = getCustomStateName(task);
    if (currentState != null) {
      final Status status = statuses.get(currentState);
      if (status != null) {
        final Set<CustomTaskState> result = new HashSet<>();
        for (String targetStatusName : status.canChangeTo) {
          final Status targetStatus = statuses.get(targetStatusName);
          if (targetStatus != null) {
            if (targetStatus.isOpen) {
              result.add(new CustomTaskState(targetStatusName, targetStatusName));
            }
            else {
              for (String resolution : resolutions) {
                result.add(new CustomTaskState(targetStatusName + ":" + resolution, targetStatusName + " (" + resolution + ")"));
              }
            }
          }
        }
        return result;
      }
    }
    return Collections.emptySet();
  }
@NotNull
  @Override
  public Set<CustomTaskState> getAvailableTaskStates(@NotNull Task task)