public Statement getStatement(
      String stateIRI,
      Map<String, String> accept,
      AuthCredentials authCredentials,
      SwordConfiguration swordConfig)
      throws SwordServerException, SwordError, SwordAuthException {
    SwordContext sc = null;
    try {
      SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;

      SwordAuthenticator auth = new SwordAuthenticator();
      sc = auth.authenticate(authCredentials);
      Context context = sc.getContext();

      if (log.isDebugEnabled()) {
        log.debug(LogManager.getHeader(context, "sword_get_statement", ""));
      }

      // log the request
      String un = authCredentials.getUsername() != null ? authCredentials.getUsername() : "NONE";
      String obo =
          authCredentials.getOnBehalfOf() != null ? authCredentials.getOnBehalfOf() : "NONE";
      log.info(
          LogManager.getHeader(
              context, "sword_get_statement", "username="******",on_behalf_of=" + obo));

      // first thing is to figure out what we're being asked to work on
      SwordUrlManager urlManager = config.getUrlManager(context, config);
      Item item = urlManager.getItem(context, stateIRI);
      if (item == null) {
        throw new SwordError(404);
      }

      // find out if we are allowed to read the item's statement
      AuthorizeManager.authorizeAction(context, item, Constants.READ);

      // find out, now we know what we're being asked for, whether this is allowed
      WorkflowManagerFactory.getInstance().retrieveStatement(context, item);

      String suffix = urlManager.getTypeSuffix(context, stateIRI);
      SwordStatementDisseminator disseminator = null;

      if (suffix != null) {
        Map<Float, List<String>> analysed = new HashMap<Float, List<String>>();
        List<String> list = new ArrayList<String>();
        list.add(suffix);
        analysed.put((float) 1.0, list);
        disseminator = SwordDisseminatorFactory.getStatementInstance(analysed);
      } else {
        // we rely on the content negotiation to do the work
        String acceptContentType = this.getHeader(accept, "Accept", null);

        // we extract from the Accept header the ordered list of content types
        TreeMap<Float, List<String>> analysed = this.analyseAccept(acceptContentType);

        // the meat of this is done by the package disseminator
        disseminator = SwordDisseminatorFactory.getStatementInstance(analysed);
      }

      Statement statement = disseminator.disseminate(context, item);
      return statement;
    } catch (AuthorizeException e) {
      throw new SwordAuthException();
    } catch (SQLException e) {
      throw new SwordServerException(e);
    } catch (DSpaceSwordException e) {
      throw new SwordServerException(e);
    } finally {
      if (sc != null) {
        sc.abort();
      }
    }
  }