'Respond to this request.
@param allow: Allow this user to claim this identity, and allow the
consumer to have this information?
@type allow: bool
@param server_url: DEPRECATED.  Passing C{op_endpoint} to the
L{Server} constructor makes this optional.
When an OpenID 1.x immediate mode request does not succeed,
it gets back a URL where the request may be carried out
in a not-so-immediate fashion.  Pass my URL in here (the
fully qualified address of this server\'s endpoint, i.e.
C{http://example.com/server}), and I will use it as a base for the
URL for a new request.
Optional for requests where C{CheckIDRequest.immediate} is C{False}
or C{allow} is C{True}.
@type server_url: str
@param identity: The OP-local identifier to answer with.  Only for use
when the relying party requested identifier selection.
@type identity: str or None
@param claimed_id: The claimed identifier to answer with, for use
with identifier selection in the case where the claimed identifier
and the OP-local identifier differ, i.e. when the claimed_id uses
delegation.
If C{identity} is provided but this is not, C{claimed_id} will
default to the value of C{identity}.  When answering requests
that did not ask for identifier selection, the response
C{claimed_id} will default to that of the request.
This parameter is new in OpenID 2.0.
@type claimed_id: str or None
@returntype: L{OpenIDResponse}
@change: Version 2.0 deprecates C{server_url} and adds C{claimed_id}.
@raises NoReturnError: when I do not have a return_to.'

def answer(self, allow, server_url=None, identity=None, claimed_id=None):

    assert (self.message is not None)
    if (not self.return_to):
        raise NoReturnToError
    if (not server_url):
        if ((not self.message.isOpenID1()) and (not self.op_endpoint)):
            raise RuntimeError(('%s    should    be    constructed    with    op_endpoint    to    respond    to    OpenID    2.0    messages.' % (self,)))
        server_url = self.op_endpoint
    if allow:
        mode = 'id_res'
    elif self.message.isOpenID1():
        if self.immediate:
            mode = 'id_res'
        else:
            mode = 'cancel'
    elif self.immediate:
        mode = 'setup_needed'
    else:
        mode = 'cancel'
    response = OpenIDResponse(self)
    if (claimed_id and self.message.isOpenID1()):
        namespace = self.message.getOpenIDNamespace()
        raise VersionError(('claimed_id    is    new    in    OpenID    2.0    and    not    available    for    %s' % (namespace,)))
    if allow:
        if (self.identity == IDENTIFIER_SELECT):
            if (not identity):
                raise ValueError('This    request    uses    IdP-driven    identifier    selection.You    must    supply    an    identifier    in    the    response.')
            response_identity = identity
            response_claimed_id = (claimed_id or identity)
        elif self.identity:
            if (identity and (self.identity != identity)):
                normalized_request_identity = urinorm(self.identity)
                normalized_answer_identity = urinorm(identity)
                if (normalized_request_identity != normalized_answer_identity):
                    raise ValueError(('Request    was    for    identity    %r,    cannot    reply    with    identity    %r' % (self.identity, identity)))
            response_identity = self.identity
            response_claimed_id = self.claimed_id
        else:
            if identity:
                raise ValueError(('This    request    specified    no    identity    and    you    supplied    %r' % (identity,)))
            response_identity = None
        if (self.message.isOpenID1() and (response_identity is None)):
            raise ValueError('Request    was    an    OpenID    1    request,    so    response    must    include    an    identifier.')
        response.fields.updateArgs(OPENID_NS, {'mode': mode, 'return_to': self.return_to, 'response_nonce': mkNonce()})
        if server_url:
            response.fields.setArg(OPENID_NS, 'op_endpoint', server_url)
        if (response_identity is not None):
            response.fields.setArg(OPENID_NS, 'identity', response_identity)
            if self.message.isOpenID2():
                response.fields.setArg(OPENID_NS, 'claimed_id', response_claimed_id)
    else:
        response.fields.setArg(OPENID_NS, 'mode', mode)
        if self.immediate:
            if (self.message.isOpenID1() and (not server_url)):
                raise ValueError('setup_url    is    required    for    allow=False    in    OpenID    1.x    immediate    mode.')
            setup_request = self.__class__(self.identity, self.return_to, self.trust_root, immediate=False, assoc_handle=self.assoc_handle, op_endpoint=self.op_endpoint, claimed_id=self.claimed_id)
            setup_request.message = self.message
            setup_url = setup_request.encodeToURL(server_url)
            response.fields.setArg(OPENID_NS, 'user_setup_url', setup_url)
    return response
