protected void assertQueryResultsEqual(TupleQueryResult expected, TupleQueryResult output)
     throws QueryEvaluationException, TupleQueryResultHandlerException,
         QueryResultHandlerException, UnsupportedEncodingException {
   MutableTupleQueryResult r1 = new MutableTupleQueryResult(expected);
   MutableTupleQueryResult r2 = new MutableTupleQueryResult(output);
   if (!QueryResults.equals(r1, r2)) {
     r1.beforeFirst();
     r2.beforeFirst();
     assertEquals(toString(r1), toString(r2));
     r2.beforeFirst();
     fail(toString(r2));
   }
 }
  private void compareTupleQueryResults(
      TupleQueryResult queryResult, TupleQueryResult expectedResult) throws Exception {
    // Create MutableTupleQueryResult to be able to re-iterate over the
    // results
    MutableTupleQueryResult queryResultTable = new MutableTupleQueryResult(queryResult);
    MutableTupleQueryResult expectedResultTable = new MutableTupleQueryResult(expectedResult);

    boolean resultsEqual;
    if (laxCardinality) {
      resultsEqual = QueryResultUtil.isSubset(queryResultTable, expectedResultTable);
    } else {
      resultsEqual = QueryResultUtil.equals(queryResultTable, expectedResultTable);

      if (checkOrder) {
        // also check the order in which solutions occur.
        queryResultTable.beforeFirst();
        expectedResultTable.beforeFirst();

        while (queryResultTable.hasNext()) {
          BindingSet bs = queryResultTable.next();
          BindingSet expectedBs = expectedResultTable.next();

          if (!bs.equals(expectedBs)) {
            resultsEqual = false;
            break;
          }
        }
      }
    }

    if (!resultsEqual) {
      queryResultTable.beforeFirst();
      expectedResultTable.beforeFirst();

      /*
       * StringBuilder message = new StringBuilder(128);
       * message.append("\n============ "); message.append(getName());
       * message.append(" =======================\n");
       * message.append("Expected result: \n"); while
       * (expectedResultTable.hasNext()) {
       * message.append(expectedResultTable.next()); message.append("\n");
       * } message.append("============="); StringUtil.appendN('=',
       * getName().length(), message);
       * message.append("========================\n");
       * message.append("Query result: \n"); while
       * (queryResultTable.hasNext()) {
       * message.append(queryResultTable.next()); message.append("\n"); }
       * message.append("============="); StringUtil.appendN('=',
       * getName().length(), message);
       * message.append("========================\n");
       */

      List<BindingSet> queryBindings = Iterations.asList(queryResultTable);

      List<BindingSet> expectedBindings = Iterations.asList(expectedResultTable);

      List<BindingSet> missingBindings = new ArrayList<BindingSet>(expectedBindings);
      missingBindings.removeAll(queryBindings);

      List<BindingSet> unexpectedBindings = new ArrayList<BindingSet>(queryBindings);
      unexpectedBindings.removeAll(expectedBindings);

      StringBuilder message = new StringBuilder(128);
      message.append("\n============ ");
      message.append(getName());
      message.append(" =======================\n");

      if (!missingBindings.isEmpty()) {

        message.append("Missing bindings: \n");
        for (BindingSet bs : missingBindings) {
          message.append(bs);
          message.append("\n");
        }

        message.append("=============");
        StringUtil.appendN('=', getName().length(), message);
        message.append("========================\n");
      }

      if (!unexpectedBindings.isEmpty()) {
        message.append("Unexpected bindings: \n");
        for (BindingSet bs : unexpectedBindings) {
          message.append(bs);
          message.append("\n");
        }

        message.append("=============");
        StringUtil.appendN('=', getName().length(), message);
        message.append("========================\n");
      }

      if (checkOrder && missingBindings.isEmpty() && unexpectedBindings.isEmpty()) {
        message.append("Results are not in expected order.\n");
        message.append(" =======================\n");
        message.append("query result: \n");
        for (BindingSet bs : queryBindings) {
          message.append(bs);
          message.append("\n");
        }
        message.append(" =======================\n");
        message.append("expected result: \n");
        for (BindingSet bs : expectedBindings) {
          message.append(bs);
          message.append("\n");
        }
        message.append(" =======================\n");

        System.out.print(message.toString());
      }

      logger.error(message.toString());
      fail(message.toString());
    }
    /*
     * debugging only: print out result when test succeeds else {
     * queryResultTable.beforeFirst();
     *
     * List<BindingSet> queryBindings = Iterations.asList(queryResultTable);
     * StringBuilder message = new StringBuilder(128);
     *
     * message.append("\n============ "); message.append(getName());
     * message.append(" =======================\n");
     *
     * message.append(" =======================\n");
     * message.append("query result: \n"); for (BindingSet bs:
     * queryBindings) { message.append(bs); message.append("\n"); }
     *
     * System.out.print(message.toString()); }
     */
  }