@SuppressWarnings("unchecked")
  public <E> E doSession(
      Object session,
      String sessionMethodName,
      Object[] parameterList,
      String expectedJSONObjectFileName,
      String expectedJSONArrayFileName,
      String expectedXMLFileName,
      ExpectedExceptionObject expectedException)
      throws TestException, IOException, JSONException {

    E actualResult = null;

    Class<?>[] parameterClassList = new Class<?>[parameterList.length];
    for (int i = 0; i < parameterList.length; i++) {
      parameterClassList[i] = parameterList[i].getClass();
    }

    Method method = null;
    try {
      method = session.getClass().getMethod(sessionMethodName, parameterClassList);
    } catch (NoSuchMethodException | SecurityException e) {
      e.printStackTrace();
      throw new Error(e);
    }

    try {
      actualResult = (E) method.invoke(session, parameterList);
      System.out.println("--- Result ---");
      System.out.println(JsonService.getJsonStringFromJavaObject(actualResult));
      System.out.println("--------------");
      if (null != expectedException) {
        throw new TestNoExceptionException(expectedException.getExpectedClass().toString());
      }
    } catch (IllegalArgumentException | IllegalAccessException e) {
      e.printStackTrace();
      throw new Error(e);
    } catch (InvocationTargetException e) {

      Throwable targetException = e.getTargetException();

      // There was an exception but was not defined the expected OR it was not the expected !!!!
      if (null == expectedException
          || !targetException.getClass().equals(expectedException.getExpectedClass())) {
        throw new TestNotExpectedExceptionException(
            expectedException.getClass().getSimpleName(),
            targetException.getClass().getSimpleName());

        // The exception was the expected but probably the message was different
      } else {

        String expectedMessage = expectedException.getExactMessage();

        // The exact message was specified but it not the same as the catched
        if (null != expectedMessage && !expectedMessage.equals(targetException.getMessage())) {
          throw new TestNotExpectedExceptionMessageException(
              expectedMessage, targetException.getLocalizedMessage());
        }
      }
    }

    // --------------------
    // Compare XML the DB
    // --------------------
    if (null != expectedXMLFileName) {
      try {
        String difference = CompareXMLToDB.getDifference(expectedXMLFileName, conn, database);
        if (null != difference) {
          throw new TestCompareXMLToDBException(expectedXMLFileName, difference);
        }
      } catch (ParserConfigurationException | SAXException | IOException | SQLException e) {
        // e.printStackTrace();
        throw new TestCompareXMLToDBFormatException(e.getLocalizedMessage());
      }
    }

    // ---------------------------------
    // Compare JSONObject to the result
    // ---------------------------------
    if (null != expectedJSONObjectFileName) {
      CompareJSONToResult.doCompareAsJSONObject(expectedJSONObjectFileName, actualResult);

      // ---------------------------------
      // Compare JSONArray to the result
      // ---------------------------------
    } else if (null != expectedJSONArrayFileName) {
      CompareJSONToResult.doCompareAsJSONArray(expectedJSONArrayFileName, actualResult);
    }

    return actualResult;
  }