--- a/Allura/allura/model/session.py
+++ b/Allura/allura/model/session.py
@@ -1,6 +1,4 @@
 import logging
-import urllib
-from itertools import chain
 
 from pylons import c
 
@@ -22,17 +20,7 @@
     @property
     def db(self):
         try:
-            # Our MagicalC makes sure allura.project is set in the environ when
-            # c.project is set
-            p = environ.get('allura.project', None)
-            if p is None:
-                # But if we're not using MagicalC, as in paster shell....
-                try:
-                    p = getattr(c, 'project', None)
-                except TypeError:
-                     # running without MagicalC, inside a request (likely EasyWidgets)
-                    return None
-            if p is None: return None
+            p = self.project
             if p.database_uri:
                 scheme, rest = p.database_uri.split('://')
                 host, database = rest.split('/', 1)
@@ -40,6 +28,21 @@
             return getattr(self.main_session.bind.conn, p.database)
         except (KeyError, AttributeError), ex:
             return None
+
+    @property
+    def project(self):
+        # Our MagicalC makes sure allura.project is set in the environ when
+        # c.project is set
+        p = environ.get('allura.project', None)
+        if p is None:
+            # But if we're not using MagicalC, as in paster shell....
+            try:
+                p = getattr(c, 'project', None)
+            except TypeError:
+                 # running without MagicalC, inside a request (likely EasyWidgets)
+                return None
+        if p is None: return None
+        return p
 
     def _impl(self, cls):
         db = self.db
@@ -53,37 +56,48 @@
     def __init__(self, session):
         SessionExtension.__init__(self, session)
         self.objects_added = []
+        self.objects_modified = []
         self.objects_deleted = []
 
     def before_flush(self, obj=None):
         if obj is None:
-            self.objects_added = list(
-                chain(self.session.uow.new,
-                      self.session.uow.dirty))
+            self.objects_added = list(self.session.uow.new)
+            self.objects_modified = list(self.session.uow.dirty)
             self.objects_deleted = list(self.session.uow.deleted)
         else: # pragma no cover
             st = state(obj)
-            if st.status in (st.new, st.dirty):
+            if st.status == st.new:
                 self.objects_added = [ obj ]
+            elif st.status == st.dirty:
+                self.objects_modified = [ obj ]
             elif st.status == st.deleted:
                 self.objects_deleted = [ obj ]
 
     def after_flush(self, obj=None):
         if not getattr(self.session, 'disable_artifact_index', False):
             from .artifact import ArtifactLink
+            from .stats import CPA
             if self.objects_deleted:
                 search.remove_artifacts(self.objects_deleted)
                 for obj in self.objects_deleted:
                     ArtifactLink.remove(obj)
-            if self.objects_added:
-                search.add_artifacts(self.objects_added)
-                for obj in self.objects_added:
+            to_update = self.objects_added + self.objects_modified
+            if to_update:
+                search.add_artifacts(to_update)
+                for obj in to_update:
                     try:
                         ArtifactLink.add(obj)
                     except:
                         log.exception('Error adding ArtifactLink for %s', obj)
                 session(ArtifactLink).flush()
+            for obj in self.objects_added:
+                CPA.post('create', obj)
+            for obj in self.objects_modified:
+                CPA.post('modify', obj)
+            for obj in self.objects_deleted:
+                CPA.post('delete', obj)
         self.objects_added = []
+        self.objects_modified = []
         self.objects_deleted = []
 
 main_doc_session = Session.by_name('main')