public PropertyEvent getLastEvent(Object obj, Property prop) {
   if (prop.isCollection()) {
     LinkedList lst = (LinkedList) m_collectionEvents.get(getKey(obj, prop));
     if (lst == null) {
       return null;
     }
     return (PropertyEvent) lst.getLast();
   }
   return (PropertyEvent) m_setEvents.get(getKey(obj, prop));
 }
  public Collection getCurrentEvents(Object obj, Property prop) {
    if (!prop.isCollection()) {
      throw new IllegalArgumentException();
    }

    List evs = (List) m_collectionEvents.get(getKey(obj, prop));
    if (evs == null) {
      return Collections.EMPTY_LIST;
    }
    return evs;
  }
  public Collection getReachablePropertyEvents(Object obj) {
    ArrayList result = new ArrayList();

    ObjectType ot = m_ssn.getObjectType(obj);
    for (Iterator it = ot.getProperties().iterator(); it.hasNext(); ) {
      Property prop = (Property) it.next();
      if (prop.isCollection()) {
        result.addAll(getCurrentEvents(obj, prop));
      } else {
        Event e = getLastEvent(obj, prop);
        if (e != null) {
          result.add(e);
        }
      }
    }

    return result;
  }
  public PropertyEvent getLastEvent(Object obj, Property prop, Object arg) {
    if (!prop.isCollection()) {
      throw new IllegalArgumentException();
    }

    List events = (List) m_collectionEvents.get(getKey(obj, prop));

    if (events == null) {
      return null;
    }

    for (int i = events.size() - 1; i >= 0; i--) {
      PropertyEvent old = (PropertyEvent) events.get(i);
      if (old.getArgument().equals(arg)) {
        return old;
      }
    }

    return null;
  }