class AttributeQueryRequestRunnable implements Runnable {

    @Override
    public void run() {
        counter.dec();

        // see https://github.com/google/guice/wiki/CustomScopes for details on this work

        addSessionIdToLoggingContext(sessionId);

        try {
            timeoutEvaluator.hasAttributeQueryTimedOut(attributeQueryContainerDto);
        } catch (AttributeQueryTimeoutException e) {
            auditAndLogTimeoutException(sessionId, attributeQueryContainerDto, e, "Matching service attribute timed out before even being sent.");
            return;
        }
        try {
            Element response = executeAttributeQueryRequest.execute(sessionId, attributeQueryContainerDto);
            timeoutEvaluator.hasAttributeQueryTimedOut(attributeQueryContainerDto);
            final String base64EncodedSamlResponse = Base64.encodeAsString(XmlUtils.writeToString(response).getBytes());
            hubMatchingServiceResponseReceiverProxy.notifyHubOfAResponseFromMatchingService(
                    sessionId,
                    base64EncodedSamlResponse);
        } catch (AttributeQueryTimeoutException e) {
            auditAndLogTimeoutException(sessionId, attributeQueryContainerDto, e, "Matching service attribute query has timed out, therefore not sending failure notification to saml engine.");
        } catch (Exception e) {
            logAndAuditMessageError(e, attributeQueryContainerDto, sessionId);
            checkTimeoutAndForwardErrorResponse(sessionId, attributeQueryContainerDto);
        }
    }

    public  AttributeQueryRequestRunnable(SessionId sessionId,
                                         AttributeQueryContainerDto attributeQueryContainerDto,
                                         ExecuteAttributeQueryRequest executeAttributeQueryRequest,
                                         @MatchingServiceRequestExecutorBacklog Counter counter,
                                         TimeoutEvaluator timeoutEvaluator,
                                         HubMatchingServiceResponseReceiverProxy hubMatchingServiceResponseReceiverProxy,
                                         ServiceInfoConfiguration serviceInfo,
                                         EventSinkProxy eventSinkProxy,
                                         EventEmitter eventEmitter);

}