public void dispose() { if (dynamicFacts != null) { // first we check for facts that were inserted into the working memory // using the old API and setting a per instance dynamic flag and remove the // session from the listeners list in the bean for (InternalFactHandle handle : dynamicFacts) { removePropertyChangeListener(handle, false); } dynamicFacts = null; } for (ObjectTypeConf conf : this.typeConfReg.values()) { // then, we check if any of the object types were configured using the // @propertyChangeSupport annotation, and clean them up if (conf.isDynamic() && conf.isSupportsPropertyChangeListeners()) { // it is enough to iterate the facts on the concrete object type nodes // only, as the facts will always be in their concrete object type nodes // even if they were also asserted into higher level OTNs as well ObjectTypeNode otn = conf.getConcreteObjectTypeNode(); final ObjectHashSet memory = ((ObjectTypeNodeMemory) this.getInternalWorkingMemory().getNodeMemory(otn)).memory; Iterator it = memory.iterator(); for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next()) { InternalFactHandle handle = (InternalFactHandle) entry.getValue(); removePropertyChangeListener(handle, false); } } } }