'Attempt to extract an association from the response, given
the association response message and the established
association session.
@param assoc_response: The association response message from
the server
@type assoc_response: openid.message.Message
@param assoc_session: The association session object that was
used when making the request
@type assoc_session: depends on the session type of the request
@raises ProtocolError: when data is malformed
@raises KeyError: when a field is missing
@rtype: openid.association.Association'

def _extractAssociation(self, assoc_response, assoc_session):

    assoc_type = assoc_response.getArg(OPENID_NS, 'assoc_type', no_default)
    assoc_handle = assoc_response.getArg(OPENID_NS, 'assoc_handle', no_default)
    expires_in_str = assoc_response.getArg(OPENID_NS, 'expires_in', no_default)
    try:
        expires_in = int(expires_in_str)
    except ValueError as why:
        raise ProtocolError(('Invalid    expires_in    field:    %s' % (why[0],)))
    if assoc_response.isOpenID1():
        session_type = self._getOpenID1SessionType(assoc_response)
    else:
        session_type = assoc_response.getArg(OPENID2_NS, 'session_type', no_default)
    if (assoc_session.session_type != session_type):
        if (assoc_response.isOpenID1() and (session_type == 'no-encryption')):
            assoc_session = PlainTextConsumerSession()
        else:
            fmt = 'Session    type    mismatch.    Expected    %r,    got    %r'
            message = (fmt % (assoc_session.session_type, session_type))
            raise ProtocolError(message)
    if (assoc_type not in assoc_session.allowed_assoc_types):
        fmt = 'Unsupported    assoc_type    for    session    %s    returned:    %s'
        raise ProtocolError((fmt % (assoc_session.session_type, assoc_type)))
    try:
        secret = assoc_session.extractSecret(assoc_response)
    except ValueError as why:
        fmt = 'Malformed    response    for    %s    session:    %s'
        raise ProtocolError((fmt % (assoc_session.session_type, why[0])))
    return Association.fromExpiresIn(expires_in, assoc_handle, secret, assoc_type)
