private StoryList retrieveStoriesByQuery(QueryFilter filter)
      throws IOException, ConnectorException, TransformerException, URISyntaxException {
    RallyRestApi restApi = new RallyRestApi(new URI(RALLY_SERVER_URL), username, password);

    QueryRequest storyQuery = new QueryRequest("HierarchicalRequirement");
    QueryRequest defectQuery = new QueryRequest("Defect");

    StoryList stories = objFactory.createStoryList();

    try {
      defectQuery.setQueryFilter(filter);
      storyQuery.setQueryFilter(filter);

      QueryResponse storyResp = restApi.query(storyQuery);
      QueryResponse defectResp = restApi.query(defectQuery);

      if (storyResp.wasSuccessful()) {
        List<StoryType> storyList = getStoryList(storyResp.getResults());
        stories.getStory().addAll(storyList);
      }

      if (defectResp.wasSuccessful()) {
        List<StoryType> defectList = getStoryList(defectResp.getResults());
        stories.getStory().addAll(defectList);
      }
    } finally {
      restApi.close();
    }
    return stories;
  }
  @Override
  public TaskList retrieveTasks(StoryList stories)
      throws IOException, ClientProtocolException, ConnectorException, TransformerException,
          URISyntaxException {
    RallyRestApi restApi = new RallyRestApi(new URI(RALLY_SERVER_URL), username, password);
    QueryRequest taskQuery = new QueryRequest("Task");

    TaskList taskList = objFactory.createTaskList();
    try {
      for (StoryType story : stories.getStory()) {
        String storyID = story.getIdentifier();
        Link storyLink = findLinkByRel(story, RALLY_OBJECT_URL_REL);
        if (storyLink != null) {
          storyLink.setRel(RALLY_PARENT_URL_REL);
        }

        NDC.push("retrieving tasks for " + storyID);
        logger.debug(NDC.peek());
        QueryFilter filter = new QueryFilter("WorkProduct.FormattedID", "=", storyID);
        taskQuery.setQueryFilter(filter);
        QueryResponse query = restApi.query(taskQuery);
        if (query.wasSuccessful()) {
          for (JsonElement e : query.getResults()) {
            if (e == null) continue;
            TaskType task = objFactory.createTaskType();
            JsonObject jsonTask = e.getAsJsonObject();
            String taskName = jsonTask.get("Name").getAsString();

            task.setParentIdentifier(storyID);
            task.setDescription(fixDescription(getValueOrDefault(jsonTask.get("Description"), "")));
            if (!jsonTask.get("Owner").isJsonNull()) {
              task.setOwner(
                  getValueOrDefault(
                      jsonTask.get("Owner").getAsJsonObject().get("_refObjectName"), ""));
            }
            task.setFullName(taskName);
            task.setShortName((taskName.length() > 30) ? taskName.substring(0, 30) : taskName);
            task.setIdentifier(jsonTask.get("FormattedID").getAsString());
            task.setDetailedEstimate(getValueOrDefault(jsonTask.get("Estimate"), new Double(0.0)));
            task.setTodoRemaining(getValueOrDefault(jsonTask.get("Estimate"), new Double(0.0)));
            task.setEffortApplied(getValueOrDefault(jsonTask.get("Actuals"), new Double(0.0)));
            task.setDescription(fixDescription(getValueOrDefault(jsonTask.get("Description"), "")));
            addLink(story, jsonTask.get("_ref").getAsString(), RALLY_OBJECT_URL_REL);

            addLink(task, jsonTask.get("_ref").getAsString(), RALLY_OBJECT_URL_REL);
            addLink(task, storyLink);
            taskList.getTask().add(task);
          }
        }
      }
    } finally {
      NDC.pop();
      restApi.close();
    }
    return taskList;
  }