/**
   * Return the query specified in the request, shorn of all duplicate classes in the view. Note, it
   * is the users responsibility to ensure that there are only SequenceFeatures in the view.
   *
   * @return A query.
   */
  protected PathQuery getQuery() {
    String xml = getRequiredParameter(XML_PARAM);
    PathQueryBuilder builder = getQueryBuilder(xml);
    PathQuery pq = builder.getQuery();

    List<String> newView = new ArrayList<String>();
    Set<ClassDescriptor> seenTypes = new HashSet<ClassDescriptor>();

    for (String viewPath : pq.getView()) {
      Path p;
      try {
        p = new Path(pq.getModel(), viewPath);
      } catch (PathException e) {
        throw new BadRequestException("Query is invalid", e);
      }
      ClassDescriptor cd = p.getLastClassDescriptor();
      if (!seenTypes.contains(cd)) {
        newView.add(viewPath);
      }
      seenTypes.add(cd);
    }
    if (!newView.equals(pq.getView())) {
      pq.clearView();
      pq.addViews(newView);
    }

    return pq;
  }
  /**
   * Get the pathquery to use for this request.
   *
   * @param request The http request.
   * @return A pathquery
   */
  protected PathQuery getQuery(HttpServletRequest request) {
    String xml = request.getParameter(XML_PARAM);

    if (StringUtils.isEmpty(xml)) {
      throw new BadRequestException("query is blank");
    }

    PathQueryBuilder builder = getQueryBuilder(xml);
    PathQuery pq = builder.getQuery();
    if (pq.getView().size() != 1) {
      throw new BadRequestException(
          "Queries to the query-to-list service can only have one output column");
    }

    if (!pq.getView().get(0).endsWith(".id")) {
      throw new BadRequestException(
          "Queries to the query-to-list service must have ids in their view");
    }
    return pq;
  }