docs: def getAssociation(self, assoc_handle, dumb, checkExpiration=True):
          """Get the association with the specified handle.
  
          @type assoc_handle: str
  
          @param dumb: Is this association used with dumb mode?
          @type dumb: bool
  
          @returns: the association, or None if no valid association with that
              handle was found.
          @returntype: L{openid.association.Association}
          """
          # Hmm.  We've created an interface that deals almost entirely with
          # assoc_handles.  The only place outside the Signatory that uses this
          # (and thus the only place that ever sees Association objects) is
          # when creating a response to an association request, as it must have
          # the association's secret.
  
          if assoc_handle is None:
              raise ValueError("assoc_handle must not be None")
  
          if dumb:
              key = self._dumb_key
          else:
              key = self._normal_key
          assoc = self.store.getAssociation(key, assoc_handle)
          if assoc is not None and assoc.expiresIn <= 0:
              logging.info("requested %sdumb key %r is expired (by %s seconds)" %
                          ((not dumb) and 'not-' or '',
                           assoc_handle, assoc.expiresIn))
              if checkExpiration:
                  self.store.removeAssociation(key, assoc_handle)
                  assoc = None
          return assoc