protected void assertQueryType11(QueryTypeImpl data, boolean validate) throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    XMLStreamWriter writer = XMLUtils.createWriter(out);
    XMLUtils.startXmlDocument(writer);
    XMLConverter.writeQuery(writer, CmisVersion.CMIS_1_1, data);
    XMLUtils.endXmlDocument(writer);

    byte[] xml = out.toByteArray();

    if (validate) {
      validate(xml, CmisVersion.CMIS_1_1);
    }

    XMLStreamReader parser = XMLUtils.createParser(new ByteArrayInputStream(xml));
    XMLUtils.findNextStartElemenet(parser);
    QueryTypeImpl result = XMLConverter.convertQuery(parser);
    parser.close();

    assertNotNull(result);
    assertDataObjectsEquals("QueryType", data, result, null);
    assertNull(result.getExtensions());
  }
  @Test
  public void testQueryType() throws Exception {

    // run the test a few times with different values
    for (int i = 0; i < 10; i++) {
      QueryTypeImpl query = new QueryTypeImpl();

      query.setStatement(randomString());
      query.setSearchAllVersions(randomBoolean());
      query.setIncludeAllowableActions(randomBoolean());
      query.setIncludeRelationships(randomEnum(IncludeRelationships.class));
      query.setRenditionFilter(randomString());
      query.setMaxItems(randomInteger());
      query.setSkipCount(randomInteger());

      assertQueryType10(query, true);
      assertQueryType11(query, true);
    }
  }
    public void serve(
        CallContext context,
        CmisService service,
        String repositoryId,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception {
      assert context != null;
      assert service != null;
      assert repositoryId != null;
      assert request != null;
      assert response != null;

      // get parameters
      String statement = null;
      Boolean searchAllVersions = null;
      Boolean includeAllowableActions = null;
      IncludeRelationships includeRelationships = null;
      String renditionFilter = null;
      BigInteger maxItems = null;
      BigInteger skipCount = null;

      int statusCode = 0;

      if (Dispatcher.METHOD_POST.equals(request.getMethod())) {
        // POST -> read from stream

        QueryTypeImpl queryType = null;
        XMLStreamReader parser = null;
        try {
          parser = XMLUtils.createParser(request.getInputStream());
          XMLUtils.findNextStartElemenet(parser);
          queryType = XMLConverter.convertQuery(parser);
        } catch (XMLStreamException e) {
          throw new CmisInvalidArgumentException("Invalid query request!", e);
        } finally {
          if (parser != null) {
            try {
              parser.close();
            } catch (XMLStreamException e2) {
              // ignore
            }
          }
        }

        statement = queryType.getStatement();
        searchAllVersions = queryType.getSearchAllVersions();
        includeAllowableActions = queryType.getIncludeAllowableActions();
        includeRelationships = queryType.getIncludeRelationships();
        renditionFilter = queryType.getRenditionFilter();
        maxItems = queryType.getMaxItems();
        skipCount = queryType.getSkipCount();

        statusCode = HttpServletResponse.SC_CREATED;
      } else if (Dispatcher.METHOD_GET.equals(request.getMethod())) {
        // GET -> parameters
        statement = getStringParameter(request, Constants.PARAM_Q);
        searchAllVersions = getBooleanParameter(request, Constants.PARAM_SEARCH_ALL_VERSIONS);
        includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
        includeRelationships =
            getEnumParameter(request, Constants.PARAM_RELATIONSHIPS, IncludeRelationships.class);
        // since CMIS 1.1
        renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
        maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
        skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);

        statusCode = HttpServletResponse.SC_OK;
      } else {
        throw new CmisRuntimeException("Invalid HTTP method!");
      }

      // execute
      if (stopBeforeService(service)) {
        return;
      }

      ObjectList results =
          service.query(
              repositoryId,
              statement,
              searchAllVersions,
              includeAllowableActions,
              includeRelationships,
              renditionFilter,
              maxItems,
              skipCount,
              null);

      if (stopAfterService(service)) {
        return;
      }

      if (results == null) {
        throw new CmisRuntimeException("Results are null!");
      }

      // set headers
      UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);

      UrlBuilder pagingUrl = compileUrlBuilder(baseUrl, RESOURCE_QUERY, null);
      pagingUrl.addParameter(Constants.PARAM_Q, statement);
      pagingUrl.addParameter(Constants.PARAM_SEARCH_ALL_VERSIONS, searchAllVersions);
      pagingUrl.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
      pagingUrl.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);

      UrlBuilder location = new UrlBuilder(pagingUrl);
      location.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
      location.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);

      response.setStatus(statusCode);
      response.setContentType(Constants.MEDIATYPE_FEED);

      // The Content-Location header is optional (CMIS specification
      // 3.7.2.1).
      // Since it can cause problems with long query statements it is
      // deactivated.
      // response.setHeader("Content-Location", location.toString());

      // The Location header is not optional (CMIS specification 3.7.2.1).
      response.setHeader("Location", location.toString());

      // write XML
      AtomFeed feed = new AtomFeed();
      feed.startDocument(response.getOutputStream(), getNamespaces(service));
      feed.startFeed(true);

      // write basic Atom feed elements
      GregorianCalendar now = new GregorianCalendar();
      feed.writeFeedElements("query", null, "", "Query", now, null, results.getNumItems());

      // write links
      feed.writeServiceLink(baseUrl.toString(), repositoryId);

      feed.writePagingLinks(
          pagingUrl, maxItems, skipCount, results.getNumItems(), results.hasMoreItems(), PAGE_SIZE);

      CmisVersion cmisVersion = context.getCmisVersion();
      if (results.getObjects() != null) {
        AtomEntry entry = new AtomEntry(feed.getWriter());
        int idCounter = 0;
        for (ObjectData result : results.getObjects()) {
          if (result == null) {
            continue;
          }
          idCounter++;
          writeQueryResultEntry(entry, result, "id-" + idCounter, now, cmisVersion);
        }
      }

      // write extensions
      feed.writeExtensions(results);

      // we are done
      feed.endFeed();
      feed.endDocument();
    }