'facade to attributes.get_state_history(), including
caching of results.'

def get_attribute_history(self, state, key, passive=attributes.PASSIVE_NO_INITIALIZE):

    hashkey = ('history', state, key)
    if (hashkey in self.attributes):
        (history, state_history, cached_passive) = self.attributes[hashkey]
        if ((not (cached_passive & attributes.SQL_OK)) and (passive & attributes.SQL_OK)):
            impl = state.manager[key].impl
            history = impl.get_history(state, state.dict, (attributes.PASSIVE_OFF | attributes.LOAD_AGAINST_COMMITTED))
            if (history and impl.uses_objects):
                state_history = history.as_state()
            else:
                state_history = history
            self.attributes[hashkey] = (history, state_history, passive)
    else:
        impl = state.manager[key].impl
        history = impl.get_history(state, state.dict, (passive | attributes.LOAD_AGAINST_COMMITTED))
        if (history and impl.uses_objects):
            state_history = history.as_state()
        else:
            state_history = history
        self.attributes[hashkey] = (history, state_history, passive)
    return state_history
