Index: django/contrib/comments/moderation.py
===================================================================
--- django/contrib/comments/moderation.py	(revision 10767)
+++ django/contrib/comments/moderation.py	(working copy)
@@ -2,8 +2,6 @@
 A generic comment-moderation system which allows configuration of
 moderation options on a per-model basis.
 
-Originally part of django-comment-utils, by James Bennett.
-
 To use, do two things:
 
 1. Create or import a subclass of ``CommentModerator`` defining the
@@ -41,7 +39,7 @@
 
     moderator.register(Entry, EntryModerator)
 
-This sample class would apply several moderation steps to each new
+This sample class would apply two moderation steps to each new
 comment submitted on an Entry:
 
 * If the entry's ``enable_comments`` field is set to ``False``, the
@@ -54,19 +52,13 @@
 configurability, see the documentation for the ``CommentModerator``
 class.
 
-Several example subclasses of ``CommentModerator`` are provided in
-`django-comment-utils`_, both to provide common moderation options and to
-demonstrate some of the ways subclasses can customize moderation
-behavior.
-
-.. _`django-comment-utils`: http://code.google.com/p/django-comment-utils/
 """
 
 import datetime
 
 from django.conf import settings
 from django.core.mail import send_mail
-from django.db.models import signals
+from django.contrib.comments import signals
 from django.db.models.base import ModelBase
 from django.template import Context, loader
 from django.contrib import comments
@@ -145,9 +137,10 @@
     Most common moderation needs can be covered by changing these
     attributes, but further customization can be obtained by
     subclassing and overriding the following methods. Each method will
-    be called with two arguments: ``comment``, which is the comment
-    being submitted, and ``content_object``, which is the object the
-    comment will be attached to::
+    be called with three arguments: ``comment``, which is the comment
+    being submitted, ``content_object``, which is the object the
+    comment will be attached to, and ``request``, which is the
+    ``HttpRequest`` in which the comment is being submitted::
 
     ``allow``
         Should return ``True`` if the comment should be allowed to
@@ -200,7 +193,7 @@
             raise ValueError("Cannot determine moderation rules because date field is set to a value in the future")
         return now - then
 
-    def allow(self, comment, content_object):
+    def allow(self, comment, content_object, request):
         """
         Determine whether a given comment is allowed to be posted on
         a given object.
@@ -217,7 +210,7 @@
                 return False
         return True
 
-    def moderate(self, comment, content_object):
+    def moderate(self, comment, content_object, request):
         """
         Determine whether a given comment on a given object should be
         allowed to show up immediately, or should be marked non-public
@@ -232,58 +225,8 @@
                 return True
         return False
 
-    def comments_open(self, obj):
+    def email(self, comment, content_object, request):
         """
-        Return ``True`` if new comments are being accepted for
-        ``obj``, ``False`` otherwise.
-
-        The algorithm for determining this is as follows:
-
-        1. If ``enable_field`` is set and the relevant field on
-           ``obj`` contains a false value, comments are not open.
-
-        2. If ``close_after`` is set and the relevant date field on
-           ``obj`` is far enough in the past, comments are not open.
-
-        3. If neither of the above checks determined that comments are
-           not open, comments are open.
-
-        """
-        if self.enable_field:
-            if not getattr(obj, self.enable_field):
-                return False
-        if self.auto_close_field and self.close_after:
-            if self._get_delta(datetime.datetime.now(), getattr(obj, self.auto_close_field)).days >= self.close_after:
-                return False
-        return True
-
-    def comments_moderated(self, obj):
-        """
-        Return ``True`` if new comments for ``obj`` are being
-        automatically sent to moderation, ``False`` otherwise.
-
-        The algorithm for determining this is as follows:
-
-        1. If ``moderate_field`` is set and the relevant field on
-           ``obj`` contains a true value, comments are moderated.
-
-        2. If ``moderate_after`` is set and the relevant date field on
-           ``obj`` is far enough in the past, comments are moderated.
-
-        3. If neither of the above checks decided that comments are
-           moderated, comments are not moderated.
-
-        """
-        if self.moderate_field:
-            if getattr(obj, self.moderate_field):
-                return True
-        if self.auto_moderate_field and self.moderate_after:
-            if self._get_delta(datetime.datetime.now(), getattr(obj, self.auto_moderate_field)).days >= self.moderate_after:
-                return True
-        return False
-
-    def email(self, comment, content_object):
-        """
         Send email notification of a new comment to site staff when email
         notifications have been requested.
 
@@ -341,8 +284,8 @@
         from the comment models.
 
         """
-        signals.pre_save.connect(self.pre_save_moderation, sender=comments.get_model())
-        signals.post_save.connect(self.post_save_moderation, sender=comments.get_model())
+        signals.comment_will_be_posted.connect(self.pre_save_moderation, sender=comments.get_model())
+        signals.comment_was_posted.connect(self.post_save_moderation, sender=comments.get_model())
 
     def register(self, model_or_iterable, moderation_class):
         """
@@ -376,67 +319,34 @@
                 raise NotModerated("The model '%s' is not currently being moderated" % model._meta.module_name)
             del self._registry[model]
 
-    def pre_save_moderation(self, sender, instance, **kwargs):
+    def pre_save_moderation(self, sender, comment, request, **kwargs):
         """
         Apply any necessary pre-save moderation steps to new
         comments.
 
         """
-        model = instance.content_type.model_class()
-        if instance.id or (model not in self._registry):
+        model = comment.content_type.model_class()
+        if model not in self._registry:
             return
-        content_object = instance.content_object
+        content_object = comment.content_object
         moderation_class = self._registry[model]
-        if not moderation_class.allow(instance, content_object): # Comment will get deleted in post-save hook.
-            instance.moderation_disallowed = True
-            return
-        if moderation_class.moderate(instance, content_object):
-            instance.is_public = False
+        if not moderation_class.allow(comment, content_object, request): # Comment will be disallowed outright (HTTP 403 response)
+            return False
+        if moderation_class.moderate(comment, content_object, request):
+            comment.is_public = False
 
-    def post_save_moderation(self, sender, instance, **kwargs):
+    def post_save_moderation(self, sender, comment, request, **kwargs):
         """
         Apply any necessary post-save moderation steps to new
         comments.
 
         """
-        model = instance.content_type.model_class()
+        model = comment.content_type.model_class()
         if model not in self._registry:
             return
-        if hasattr(instance, 'moderation_disallowed'):
-            instance.delete()
-            return
-        self._registry[model].email(instance, instance.content_object)
+        self._registry[model].email(comment, comment.content_object, request)
 
-    def comments_open(self, obj):
-        """
-        Return ``True`` if new comments are being accepted for
-        ``obj``, ``False`` otherwise.
 
-        If no moderation rules have been registered for the model of
-        which ``obj`` is an instance, comments are assumed to be open
-        for that object.
-
-        """
-        model = obj.__class__
-        if model not in self._registry:
-            return True
-        return self._registry[model].comments_open(obj)
-
-    def comments_moderated(self, obj):
-        """
-        Return ``True`` if new comments for ``obj`` are being
-        automatically sent to moderation, ``False`` otherwise.
-
-        If no moderation rules have been registered for the model of
-        which ``obj`` is an instance, comments for that object are
-        assumed not to be moderated.
-
-        """
-        model = obj.__class__
-        if model not in self._registry:
-            return False
-        return self._registry[model].comments_moderated(obj)
-
 # Import this instance in your own code to use in registering
 # your models for moderation.
 moderator = Moderator()
Index: tests/regressiontests/comment_tests/tests/comment_utils_moderators_tests.py
===================================================================
--- tests/regressiontests/comment_tests/tests/comment_utils_moderators_tests.py	(revision 10767)
+++ tests/regressiontests/comment_tests/tests/comment_utils_moderators_tests.py	(working copy)
@@ -1,4 +1,5 @@
 from regressiontests.comment_tests.tests import CommentTestCase, CT, Site
+from django.contrib.comments.forms import CommentForm
 from django.contrib.comments.models import Comment
 from django.contrib.comments.moderation import moderator, CommentModerator, AlreadyModerated
 from regressiontests.comment_tests.models import Entry
@@ -22,24 +23,26 @@
     fixtures = ["comment_utils.xml"]
 
     def createSomeComments(self):
-        c1 = Comment.objects.create(
-            content_type = CT(Entry),
-            object_pk = "1",
-            user_name = "Joe Somebody",
-            user_email = "jsomebody@example.com",
-            user_url = "http://example.com/~joe/",
-            comment = "First!",
-            site = Site.objects.get_current(),
-        )
-        c2 = Comment.objects.create(
-            content_type = CT(Entry),
-            object_pk = "2",
-            user_name = "Joe the Plumber",
-            user_email = "joetheplumber@whitehouse.gov",
-            user_url = "http://example.com/~joe/",
-            comment = "Second!",
-            site = Site.objects.get_current(),
-        )
+        # Tests for the moderation signals must actually post data
+        # through the comment views, because only the comment views
+        # emit the custom signals moderation listens for.
+        e = Entry.objects.get(pk=1)
+        data = self.getValidData(e)
+        self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4")
+        self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4")
+
+        # We explicitly do a try/except to get the comment we've just
+        # posted because moderation may have disallowed it, in which
+        # case we can just return it as None.
+        try:
+            c1 = Comment.objects.all()[0]
+        except IndexError:
+            c1 = None
+
+        try:
+            c2 = Comment.objects.all()[0]
+        except IndexError:
+            c2 = None
         return c1, c2
 
     def tearDown(self):
@@ -51,17 +54,17 @@
 
     def testEmailNotification(self):
         moderator.register(Entry, EntryModerator1)
-        c1, c2 = self.createSomeComments()
+        self.createSomeComments()
         self.assertEquals(len(mail.outbox), 2)
 
     def testCommentsEnabled(self):
         moderator.register(Entry, EntryModerator2)
-        c1, c2 = self.createSomeComments()
+        self.createSomeComments()
         self.assertEquals(Comment.objects.all().count(), 1)
 
     def testAutoCloseField(self):
         moderator.register(Entry, EntryModerator3)
-        c1, c2 = self.createSomeComments()
+        self.createSomeComments()
         self.assertEquals(Comment.objects.all().count(), 0)
 
     def testAutoModerateField(self):
Index: docs/ref/contrib/comments/moderation.txt
===================================================================
--- docs/ref/contrib/comments/moderation.txt	(revision 10767)
+++ docs/ref/contrib/comments/moderation.txt	(working copy)
@@ -12,12 +12,10 @@
 essentially makes it necessary to have some sort of automatic
 moderation system in place for any application which makes use of
 comments. To make this easier to handle in a consistent fashion,
-``django.contrib.comments.moderation`` (based on `comment_utils`_)
-provides a generic, extensible comment-moderation system which can
-be applied to any model or set of models which want to make use of
-Django's comment system.
+``django.contrib.comments.moderation`` provides a generic, extensible
+comment-moderation system which can be applied to any model or set of
+models which want to make use of Django's comment system.
 
-.. _`comment_utils`: http://code.google.com/p/django-comment-utils/
 
 Overview
 ========
@@ -140,29 +138,28 @@
 --------------------------------
 
 For situations where the built-in options listed above are not
-sufficient, subclasses of
-:class:`CommentModerator` can also
-override the methods which actually perform the moderation, and apply any
-logic they desire.
-:class:`CommentModerator` defines three
-methods which determine how moderation will take place; each method will be
-called by the moderation system and passed two arguments: ``comment``, which
-is the new comment being posted, and ``content_object``, which is the
-object the comment will be attached to:
+sufficient, subclasses of :class:`CommentModerator` can also override
+the methods which actually perform the moderation, and apply any logic
+they desire.  :class:`CommentModerator` defines three methods which
+determine how moderation will take place; each method will be called
+by the moderation system and passed two arguments: ``comment``, which
+is the new comment being posted, ``content_object``, which is the
+object the comment will be attached to, and ``request``, which is the
+``HttpRequest`` in which the comment is being submitted:
 
-.. method:: CommentModerator.allow(comment, content_object)
+.. method:: CommentModerator.allow(comment, content_object, request)
 
     Should return ``True`` if the comment should be allowed to
     post on the content object, and ``False`` otherwise (in which
     case the comment will be immediately deleted).
 
-.. method:: CommentModerator.email(comment, content_object)
+.. method:: CommentModerator.email(comment, content_object, request)
 
     If email notification of the new comment should be sent to
     site staff or moderators, this method is responsible for
     sending the email.
 
-.. method:: CommentModerator.moderate(comment, content_object)
+.. method:: CommentModerator.moderate(comment, content_object, request)
 
     Should return ``True`` if the comment should be moderated (in
     which case its ``is_public`` field will be set to ``False``
@@ -217,18 +214,18 @@
         Determines how moderation is set up globally. The base
         implementation in
         :class:`Moderator` does this by
-        attaching listeners to the :data:`~django.db.models.signals.pre_save`
-        and :data:`~django.db.models.signals.post_save` signals from the
+        attaching listeners to the :data:`~django.contrib.comments.signals.comment_will_be_posted`
+        and :data:`~django.contrib.comments.signals.comment_was_posted` signals from the
         comment models.
 
-    .. method:: pre_save_moderation(sender, instance, **kwargs)
+    .. method:: pre_save_moderation(sender, comment, request, **kwargs)
 
         In the base implementation, applies all pre-save moderation
         steps (such as determining whether the comment needs to be
         deleted, or whether it needs to be marked as non-public or
         generate an email).
 
-    .. method:: post_save_moderation(sender, instance, **kwargs)
+    .. method:: post_save_moderation(sender, comment, request, **kwargs)
 
         In the base implementation, applies all post-save moderation
         steps (currently this consists entirely of deleting comments
