def _getAuthHeaders(self):
        """
        Get authentication headers. If we have valid header data already,
        they immediately return it.
        If not, then get new authentication data. If we are currently in
        the process of getting the
        header data, put this request into a queue to be handled when the
        data are received.

        @returns: A deferred that will eventually be called back with the
                  header data
        """
        def _handleAuthBody(body):
            self.msg("_handleAuthBody: %(body)s", body=body)

            try:
                body_parsed = json.loads(body)
                access_token = body_parsed['access']['token']

                tenant_id = access_token['tenant']['id'].encode('ascii')
                auth_token = access_token['id'].encode('ascii')

                self.auth_headers["X-Tenant-Id"] = tenant_id
                self.auth_headers["X-Auth-Token"] = auth_token

                self._state = self.AUTHENTICATED

                self.msg("_handleAuthHeaders: found token %(token)s"
                         " tenant id %(tenant_id)s",
                         token=self.auth_headers["X-Auth-Token"],
                         tenant_id=self.auth_headers["X-Tenant-Id"])

                # Callback all queued auth headers requests
                while not self._headers_requests.empty():
                    self._headers_requests.get().callback(self.auth_headers)

            except ValueError:
                # We received a bad response
                return fail(MalformedJSONError("Malformed keystone"
                                               " response received."))

        def _handleAuthResponse(response):
            if response.code == httplib.OK:
                self.msg("_handleAuthResponse: %(response)s accepted",
                         response=response)
                body = Deferred()
                response.deliverBody(StringIOReceiver(body))
                body.addCallback(_handleAuthBody)
                return body
            else:
                self.msg("_handleAuthResponse: %(response)s rejected",
                         response=response)
                return fail(
                    KeystoneAuthenticationError("Keystone"
                                                " authentication credentials"
                                                " rejected"))

        self.msg("_getAuthHeaders: state is %(state)s", state=self._state)

        if self._state == self.AUTHENTICATED:
            # We are authenticated, immediately succeed with the current
            # auth headers
            self.msg("_getAuthHeaders: succeed with %(headers)s",
                     headers=self.auth_headers)

            return succeed(self.auth_headers)
        elif (self._state == self.NOT_AUTHENTICATED or
              self._state == self.AUTHENTICATING):
            # We cannot satisfy the auth header request immediately,
            # put it in a queue
            self.msg("_getAuthHeaders: defer, place in queue")
            auth_headers_deferred = Deferred()
            self._headers_requests.put(auth_headers_deferred)

            if self._state == self.NOT_AUTHENTICATED:
                self.msg("_getAuthHeaders: not authenticated, start"
                         " authentication process")
                # We are not authenticated, and not in the process of
                # authenticating.
                # Set our state to AUTHENTICATING and begin the
                # authentication process
                self._state = self.AUTHENTICATING

                d = self.agent.request('POST',
                                       self.auth_url,
                                       Headers({
                                           "Content-type": ["application/json"]
                                       }),
                                       self._getAuthRequestBodyProducer())
                d.addCallback(_handleAuthResponse)
                d.addErrback(auth_headers_deferred.errback)

            return auth_headers_deferred
        else:
            # Bad state, fail
            return fail(RuntimeError("Invalid state encountered."))
Get authentication headers. If we have valid header data already,
        they immediately return it.
        If not, then get new authentication data. If we are currently in
        the process of getting the
        header data, put this request into a queue to be handled when the
        data are received.

        @returns: A deferred that will eventually be called back with the
                  header data