diff --git a/reviewboard/reviews/models.py b/reviewboard/reviews/models.py
index 9830fee06c564cd3dab18bdde5db7284d88a6b0f..79b7075d5a50b39dced762f05c29980595015466 100644
--- a/reviewboard/reviews/models.py
+++ b/reviewboard/reviews/models.py
@@ -1905,12 +1905,15 @@ class Action(models.Model):
 
     @property
     def type(self):
-        """Return one of these strings: 'review', 'change'"""
+        """Return one of these strings: 'review', 'reply', 'change'"""
         if self.changedesc_id:
             return 'change'
+        elif self.verb == self.PUBLISHED_REPLY:
+            return 'reply'
         else:
             return 'review'
 
+
     @property
     def display_verb(self):
         return self.get_verb_display()
diff --git a/reviewboard/reviews/views.py b/reviewboard/reviews/views.py
index 5f45d70830b687f0258fe7e0decf3f57790a4f51..84aebcd82f0f01e4904479cd9980950e3c97ed4c 100644
--- a/reviewboard/reviews/views.py
+++ b/reviewboard/reviews/views.py
@@ -50,7 +50,7 @@ from reviewboard.reviews.forms import NewReviewRequestForm, \
                                       UploadDiffForm, \
                                       UploadScreenshotForm
 
-from reviewboard.reviews.models import Action, Comment, \
+from reviewboard.reviews.models import Comment, \
                                        FileAttachmentComment, \
                                        Group, ReviewRequest, Review, \
                                        Screenshot, ScreenshotComment
diff --git a/reviewboard/static/rb/css/action-feed.less b/reviewboard/static/rb/css/action-feed.less
index b8cc70af6d6aa92be511c57c9f3c20358aa37fb3..93dae4a5cc5526edea579dfdf163578d0c979183 100644
--- a/reviewboard/static/rb/css/action-feed.less
+++ b/reviewboard/static/rb/css/action-feed.less
@@ -22,6 +22,17 @@
   }
 }
 
+.reply-comment {
+  color: black;
+  font-family: monospace;
+  font-size: 10pt;
+}
+
+.reply-to-comment {
+  color: gray;
+  font-size: 9pt;
+}
+
 .action_feed {
   .action-summary {
     display: block;
diff --git a/reviewboard/static/rb/js/action-feed.js b/reviewboard/static/rb/js/action-feed.js
index a0548fcf5ef7f9073ac7cc611eed7e9a43b6952d..c696939fa369036d03c31cb6f0c8ff47281bfda3 100644
--- a/reviewboard/static/rb/js/action-feed.js
+++ b/reviewboard/static/rb/js/action-feed.js
@@ -196,6 +196,7 @@ function get_comment_text(comment) {
                     .text('An issue was opened.')
                 )
             )
+	    .append($('<br/>'))
         )
     }
     return dd;
@@ -308,6 +309,137 @@ function with_review(collapse_button, review, callback) {
     callback();
 }
 
+function get_reply_text(comment) {
+    var dd = $('<dd/>')
+        .append($('<pre/>')
+		.addClass('reply-to-comment')
+                .attr('id',  comment.id)
+                .text(comment.links.reply_to.title));
+    dd.append($('<ol/>')
+	      .addClass('reply-comment')
+	      .append($('<span/>')
+		      .text(comment.text)
+		     )
+	     );
+    return dd
+}
+
+function with_reply(collapse_button, reply, callback) {
+    var body = collapse_button.parent().siblings('.body'),
+    request_url = collapse_button.parent().find('a').attr('href'),
+    reply_to;
+
+    if (reply.body_top) {
+	reply_to = $('<pre/>')
+            .addClass('reply-to-comment')
+            .text(reply.base_reply_to.body_top)
+            .appendTo(body);
+	reply_to.append($('<ol/>')
+			.addClass('reply-comment')
+			.append($('<span/>')
+				.text(reply.body_top)
+			       )
+		       );
+    }
+
+    if (reply.diff_comments || reply.screenshot_comments ||
+        reply.file_attachment_comments) {
+        var i, length,
+            comment_body,
+            reply_comments = $('<dl/>')
+                .addClass('diff-comments')
+                .appendTo(body);
+
+	length = 0;
+	if (reply.screenshot_comments) {
+            length = reply.screenshot_comments.length;
+	}
+
+        for (i = 0; i < length; i++) {
+            var comment = reply.screenshot_comments[i],
+                screenshot = comment.links.screenshot,
+                id = screenshot.href.match(/\d+(?!.*\d+)/),
+                title = screenshot.title.match(/\w+/).toString();
+            $('<dt/>')
+                .append(get_comment_anchor(comment))
+                .append($('<div/>')
+                    .addClass('screenshot')
+                    .text('Screenshot: ')
+                    .append($('<a/>')
+                        .attr('href', request_url + 's/' + id)
+                        .text(title)
+                    )
+                )
+                .appendTo(reply_comments);
+            get_reply_text(comment).appendTo(reply_comments);
+        }
+
+	if (reply.file_attachment_comments) {
+            length = reply.file_attachment_comments.length;
+	}
+        for (i = 0; i < length; i++) {
+            var comment = reply.file_attachment_comments[i],
+                file_attachment = comment.links.file_attachment,
+                title = file_attachment.title;
+            $('<dt/>')
+                .append(get_comment_anchor(comment))
+                .append($('<div/>')
+                    .addClass('file-attachment')
+                    .text('File attachment: ' + title)
+                )
+                .appendTo(reply_comments);
+            get_reply_text(comment).appendTo(reply_comments);
+        }
+
+	if (reply.diff_comments) {
+            length = reply.diff_comments.length;
+	}
+
+        for (i = 0; i < length; i++) {
+            var comment = reply.diff_comments[i],
+                filediff = comment.links.filediff,
+                title = filediff.title.match(/^[^ ]*/)[0],
+                ids = filediff.href.match('diffs/\\d+/files/\\d+')[0],
+                file_id = ids.match(/\d+(?!.*\d+)/),
+                diff_id = ids.match(/\d/),
+                filediff_name = 'diff/' + diff_id + '/?file=' + file_id +
+                         '#file' + file_id + 'line' + comment.first_line;
+
+            $('<dt/>')
+                .append(get_comment_anchor(comment))
+                .append($('<div/>')
+                    .attr('id', 'comment_cotainer_' + comment.id)
+                    .append($('<div/>')
+                        .addClass('file_attachment')
+                        .text('Filediff: ')
+                        .append($('<a/>')
+                            .attr('href', request_url + filediff_name)
+                            .text(title)
+                        )
+                    )
+                    .append(get_reply_text(comment))
+                )
+                .appendTo(reply_comments)
+        }
+    }
+
+    if (reply.body_bottom) {
+        reply_to = $('<pre/>')
+            .addClass('reply-to-comment')
+            .text(reply.base_reply_to.body_bottom)
+           .appendTo(body);
+	reply_to.append($('<ol/>')
+			.addClass('reply-comment')
+			.append($('<span/>')
+				.text(reply.body_bottom)
+			       )
+		       );
+    }
+
+    callback();
+}
+
+
 function append_actions(action_list) {
     var container = $('#action-feed-content'),
         site_prefix = SITE_ROOT + gSitePrefix,
@@ -350,12 +482,13 @@ function append_actions(action_list) {
             .attr('data-action-id', action.id)
             .attr('data-review-display-id', action.request_display_id);
         reviewer = $('<div/>')
-            .append($('<a/>')
-                .addClass('user')
-                .attr('href', site_prefix + action.submitter.url.substring(1))
-                .text(action.submitter.username)
-            )
-            .append(' ' + action.display_verb);
+	    .append($('<b/>')
+                .append($('<a/>')
+                   .addClass('user')
+                   .attr('href', site_prefix + action.submitter.url.substring(1))
+                   .text(action.submitter.username)
+                )
+		       .append(' ' + action.display_verb));
 
         if (action.type === 'change') {
             posted_text = 'Updated';
@@ -412,11 +545,11 @@ function on_collapse(){
         $(self).closest('.box').toggleClass('collapsed');
     }
 
-    if (action_type === 'review') {
-        expand = 'review,diff_comments,file_attachment_comments,' +
-                 'screenshot_comments';
-    } else {
+    if (action_type === 'change') {
         expand = 'changedesc';
+    } else {
+	expand = 'review,base_reply_to,diff_comments,file_attachment_comments,' +
+            'screenshot_comments';
     }
 
     action = self.data(action_id);
@@ -427,7 +560,9 @@ function on_collapse(){
             self.data(action_id, action);
                 if (action_type === 'review') {
                     with_review(self, action.review, toggle_collapsed);
-                } else {
+                } else if (action_type == 'reply') {
+		    with_reply(self, action.review, toggle_collapsed);
+		} else {
                     with_change(self, action.changedesc, toggle_collapsed);
                 }
             });
diff --git a/reviewboard/webapi/resources.py b/reviewboard/webapi/resources.py
index 2bb0491c8fbd06f5c546b130add700441d1eb73c..455c34d372e911fb05213e2c75a7f331726ee553 100644
--- a/reviewboard/webapi/resources.py
+++ b/reviewboard/webapi/resources.py
@@ -252,10 +252,6 @@ class ActionResource(WebAPIResource):
             'type': str,
             'description': 'The type of the action. Either "change", "review" or "reply"',
         },
-        'verb': {
-            'type': str,
-            'description': 'Verb that describes the action.'
-        },
         'display_verb': {
             'type': str,
             'description': 'Human readable version of the verb.'
@@ -5304,6 +5300,10 @@ class ReviewReplyResource(BaseReviewResource):
     name = 'reply'
     name_plural = 'replies'
     fields = {
+        'base_reply_to': {
+            'type': 'reviewboard.webapi.resources.BaseReviewResource',
+            'description': 'The upmost review comment'
+        },
         'body_bottom': {
             'type': str,
             'description': 'The response to the review content below '
