Index: quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.pt
===================================================================
--- quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.pt	(revision 822)
+++ quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.pt	(revision 1201)
@@ -4,5 +4,9 @@
                    isAnon view/is_anonymous;
                    ifModerate view/is_moderation_enabled;
-                   isModerationAllowed view/can_moderate"
+                   isModerationAllowed view/can_moderate;
+                   isAuthenticatedReportAbuseEnabled view/authenticated_report_abuse_enabled;
+                   isAjaxReportAbuseEnabled view/ajax_report_abuse_enabled;
+                   isAnonymousReportAbuseEnabled view/anonymous_report_abuse_enabled;
+                   isReportAbuseEnabled python:isAnonymousReportAbuseEnabled or not isAnon and isAuthenticatedReportAbuseEnabled"
                    i18n:domain="plone">
     <div class="discussion"
@@ -36,4 +40,5 @@
                 tal:define="indent python:reply_dict['depth']*2;
                             reply python:reply_dict['object'];
+                            comment_id python:reply_dict['object'].id;
                             isPublished python:reply.review_state=='published';"
                 tal:attributes="style string:margin-left:${indent}em;">
@@ -90,4 +95,26 @@
                            />
                 </form>
+                <tal:if tal:condition="python:isReportAbuseEnabled and isPublished">
+                    <form class="report_abuse"
+                          name="report_abuse"
+                          method="post"
+                          style="display: inline;"
+                          tal:attributes="action string:${reply/absolute_url}/report_abuse_form#discussion">
+                        <input type="hidden" name="comment_id" tal:attributes="value comment_id" />
+                        <input class="standalone"
+                            type="submit"
+                            value="Report Abuse"
+                            tal:define="onclick string:javascript:render_abuse_report_form(${comment_id})"
+                            tal:attributes="onclick python:isAjaxReportAbuseEnabled and onclick or '';
+                                            id string:input-render-abuse-cancel-${comment_id}"
+                            i18n:attributes="value label_report_abuse;"
+                            />
+                    </form>
+                    <span tal:attributes="id string:span-reply-form-holder-${comment_id}"
+                            tal:condition="isReportAbuseEnabled">
+                        <metal:macro use-macro="here/report_abuse_form/macros/form"/>
+                    </span>
+                    <span tal:attributes="id string:span-abuse-count-holder-${comment_id}"></span>
+                </tal:if>
                 <form name="publish_discussion"
                       action=""
@@ -108,5 +135,4 @@
                      i18n:domain="quintagroup.plonecomments"
                      tal:condition="not:isPublished">Comment must be approved before replies to comment accepted.</div>
-
             </div>
         </tal:getreplies>
Index: quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.py
===================================================================
--- quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.py	(revision 822)
+++ quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.py	(revision 1201)
@@ -3,13 +3,17 @@
 from Acquisition import aq_inner
 from AccessControl import getSecurityManager
+
+from Products.CMFPlone.utils import IndexIterator
 from Products.CMFPlone.utils import getToolByName
+from Products.CMFFormController.ControllerState import ControllerState
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from quintagroup.plonecomments.utils import manage_mails
 
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
 from plone.app.layout.viewlets import comments
+from plone.app.kss.plonekssview import PloneKSSView
 
 class CommentsViewlet(comments.CommentsViewlet):
     """A custom version of the comments viewlet
     """
-
     render = ViewPageTemplateFile('comments.pt')
 
@@ -52,2 +56,109 @@
 
         return gravatar_url
+
+    def authenticated_report_abuse_enabled(self):
+        """ """
+        portal_properties = getToolByName(self.context, 'portal_properties')
+        prop_sheet = portal_properties['qPloneComments']
+        value =  prop_sheet.getProperty('enable_authenticated_report_abuse', False)
+        return value
+
+    def anonymous_report_abuse_enabled(self):
+        """ """
+        portal_properties = getToolByName(self.context, 'portal_properties')
+        prop_sheet = portal_properties['qPloneComments']
+        value =  prop_sheet.getProperty('enable_anonymous_report_abuse', False)
+        return value
+
+    def ajax_report_abuse_enabled(self):
+        """ """
+        portal_properties = getToolByName(self.context, 'portal_properties')
+        prop_sheet = portal_properties['qPloneComments']
+        value =  prop_sheet.getProperty('enable_ajax_report_abuse', False)
+        return value
+
+    def email_from_address(self):
+        """ """
+        portal_url = getToolByName(self.context, 'portal_url')
+        portal = portal_url.getPortalObject()
+        return portal.email_from_address
+
+    def member(self):
+        """ """
+        pm = getToolByName(self.context, 'portal_membership')
+        return pm.getAuthenticatedMember()
+
+    def tabindex(self):
+        """ Needed for BBB, tabindex has been deprecated.
+        """
+        return IndexIterator()
+
+    def portal_url(self):
+        """ """
+        return getToolByName(self.context, 'portal_url')
+
+
+
+class CommentsKSS(PloneKSSView):
+    """ Operations on the report abuse form using KSS.
+    """   
+
+    def submit_abuse_report(self):
+        """ Send an email with the abuse report message and hide abuse report form.
+        """
+        errors = {}
+        context = aq_inner(self.context)
+        request = context.REQUEST
+        portal = getToolByName(self.context, 'portal_url').getPortalObject()
+        if hasattr(context, 'captcha_validator'):
+            dummy_controller_state = ControllerState(
+                                            id='comments.pt',
+                                            context=context,
+                                            button='submit',
+                                            status='success',
+                                            errors={},
+                                            next_action=None,)
+            # get the form controller
+            controller = portal.portal_form_controller
+            # send the validate script to the form controller with the dummy state object
+            controller_state = controller.validate(dummy_controller_state, request, ['captcha_validator',])
+            errors.update(controller_state.errors)
+
+        message = request.get('message')
+        if not message:
+            errors.update({'message': 'Please provide a message'})
+
+        mtool = getToolByName(self.context, "portal_membership")
+        member = mtool.getAuthenticatedMember()
+        comment_id = self.context.request.get('comment_id')
+        ksscore = self.getCommandSet('core')
+        if errors:
+            html = self.macroContent('context/report_abuse_form/macros/form',
+                                     errors=errors,
+                                     show_form=True,
+                                     tabindex=IndexIterator(),
+                                     member=member,
+                                     **request.form)
+            node = ksscore.getHtmlIdSelector('span-reply-form-holder-%s' % comment_id)
+            ksscore.replaceInnerHTML(node,  html)
+            return self.render()
+
+        # report_abuse(context, context, message, comment)
+        manage_mails(context, self.context, 'report_abuse')
+
+        html = self.macroContent('context/report_abuse_form/macros/form',
+                                 tabindex=IndexIterator(),
+                                 member=member,
+                                 **request.form)
+        node = ksscore.getHtmlIdSelector('span-reply-form-holder-%s' % comment_id)
+        html = '<br/><span style="color:red">You have reported this comment for abuse.</span>'
+        self.commands.addCommand('remove_abuse_report_form', 
+                                 node, 
+                                 comment_id=comment_id, 
+                                 html=html)
+
+        node = ksscore.getHtmlIdSelector('div-captcha-%s' % comment_id)
+        html = self.macroContent('context/report_abuse_form/macros/captcha',
+                                 **request.form)
+        ksscore.replaceInnerHTML(node,  html)
+        return self.render()
Index: quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/configure.zcml
===================================================================
--- quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/configure.zcml	(revision 822)
+++ quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/configure.zcml	(revision 1201)
@@ -2,5 +2,20 @@
     xmlns="http://namespaces.zope.org/zope"
     xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:kss="http://namespaces.zope.org/kss"
     i18n_domain="quintagroup.plonecomments">
 
+    <browser:page
+        for="*"
+        attribute="submit_abuse_report"
+        class=".comments.CommentsKSS"
+        name="kss_submit_abuse_report"
+        permission="zope2.View"
+        /> 
+
+    <kss:action
+        name="remove_abuse_report_form"
+        command_factory="selector"
+        jsfile="../skins/quintagroup_plonecomments/qcomments.js"
+        />
+
 </configure>
