/**
     * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
     */
    public DNSLookupContinuation checkSPF(SPFSession spfData)
        throws PermErrorException, TempErrorException, NeutralException, NoneException {

      String currentResult = spfData.getCurrentResult();

      restoreSession(spfData);

      if (currentResult == null) {
        throw new TempErrorException("included checkSPF returned null");
      } else if (currentResult.equals(SPF1Constants.PASS)) {
        // TODO this won't work asynchronously
        spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.TRUE);
      } else if (currentResult.equals(SPF1Constants.FAIL)
          || currentResult.equals(SPF1Constants.SOFTFAIL)
          || currentResult.equals(SPF1Constants.NEUTRAL)) {
        // TODO this won't work asynchronously
        spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE);
      } else {
        throw new TempErrorException("included checkSPF returned an Illegal result");
      }

      return null;
    }
 /**
  * throttle should be true only when the caller thread is the client and not the worker thread. We
  * could even remove the throttle parameter and check the currentThread. This way the worker is
  * never "blocked" while outside callers will be blocked if our queue is too big (so this is not
  * fully "asynchronous").
  */
 private synchronized void invokeAsynchService(
     SPFSession session, FutureSPFResult result, DNSLookupContinuation cont, boolean throttle) {
   while (throttle && results.size() > 50) {
     try {
       this.wait(100);
     } catch (InterruptedException e) {
     }
   }
   int nextId = nextId();
   sessions.put(new Integer(nextId), session);
   results.put(new Integer(nextId), result);
   session.setAttribute(ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION, cont);
   dnsProbe.getRecordsAsynch(cont.getRequest(), nextId, responseQueue);
 }