diff --git a/checklist/checklist/admin_urls.py b/checklist/checklist/admin_urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..b289c4aa87d1810a8a5a35ccd5f9f6080b5cd762
--- /dev/null
+++ b/checklist/checklist/admin_urls.py
@@ -0,0 +1,7 @@
+from django.conf.urls.defaults import patterns, url
+
+from checklist.extension import Checklist
+
+urlpatterns = patterns('checklist.views',
+    url(r'^$', 'configure'),
+)
diff --git a/checklist/checklist/checklistResource.py b/checklist/checklist/checklistResource.py
new file mode 100644
index 0000000000000000000000000000000000000000..1d5aba6c49042dd0710421eacee5849f153f7976
--- /dev/null
+++ b/checklist/checklist/checklistResource.py
@@ -0,0 +1,88 @@
+from django.http import HttpResponse
+from django.shortcuts import render_to_response
+from checklist.models import Checklist
+from reviewboard.reviews.models import ReviewRequest
+from django.contrib.auth.models import User
+from reviewboard.webapi.base import WebAPIResource
+from djblets.webapi.resources import *
+
+class ChecklistResource(WebAPIResource):
+
+    name = 'checklists'
+    model = 'Checklist'
+    allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
+
+    @webapi_request_fields(
+        optional={
+            'user_id': {
+                'type': int,
+                'description': 'The id of the user creating the checklist.'
+            },
+            'review_request_id':{
+                'type': int,
+                'description': 'The id of the review request.'
+            },
+            'checklist_item_id': {
+                'type': int,
+                'description': 'The id of the checklist item to edit or '
+                               'delete.'
+            },
+            'item_description': {
+                'type': str,
+                'description': 'The description of the checklist item.'
+            },
+            'toggle': {
+                'type': str,
+                'description': 'If present, status of the item should '
+                               'be toggled.'
+            }
+        }
+    )
+
+    @webapi_response_errors(DOES_NOT_EXIST, NOT_LOGGED_IN)
+    def get(self, *args, **kwargs):
+	"""Retrieves the list of items for a specific checklist."""
+	checklist = Checklist.objects.get(checklistID)
+	items = checklist.checklistItems
+	return HttpResponse(items, content_type="application/json")
+
+    def get_list(self, request, checklist_id, *args, **kwargs):
+	pass
+
+    def create(self, request, *args, **kwargs):
+        """Creates a new checklist."""
+        username = kwargs['user_id']
+	review_request = kwargs['review_request_id']
+	new_checklist = Checklist(user=username, revRequestID=review_request)
+	new_checklist.save()
+
+	return 201, {
+	    self.item_result_key: new_checklist
+	}
+
+    @webapi_login_required
+    def update(self, request, checklist_id, *args, **kwargs):
+        """Add, edit, delete or update the status of an item on the list"""
+	checklist = Checklist.objects.get(checklistID)
+
+	#If there is no checklist_item_id, we are adding a new item
+	if ('checklist_item_id' not in kwargs) and ('item_description' in kwargs):
+	    checklist.addItem(kwargs['item_description'])
+    
+	elif ('checklist_item_id' in kwargs) and ('item_description' in kwargs):
+		
+	    #If the item description is an empty string, delete the item
+	    if (kwargs['item_description'] == ''):
+		checklist.deleteItem(kwargs['checklist_item_id'])
+	    else:
+		checklist.editItemDesc(kwargs['checklist_item_id'], 
+		    kwargs['item_description'])
+
+	#If toggle, we toggle the status of the checklsit item
+	elif ('checklist_item_id' in kwargs) and ('toggle' in kwargs):	
+	    checklist.editItemStatus(kwargs['checklist_item_id'])
+
+    def delete(self, request, checklist_id, *args, **kwargs):
+	pass
+
+checklist_resource = ChecklistResource()
\ No newline at end of file
diff --git a/checklist/checklist/extension.py b/checklist/checklist/extension.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8cafad2e9b66efcd855488a0c4959a905657a60
--- /dev/null
+++ b/checklist/checklist/extension.py
@@ -0,0 +1,39 @@
+# checklist Extension for Review Board.
+from django.conf import settings
+from django.conf.urls.defaults import patterns, include
+from reviewboard.extensions.base import Extension
+from reviewboard.extensions.hooks import URLHook, TemplateHook
+from checklist.checklistResource import ChecklistResource, checklist_resource
+
+
+class Checklist(Extension):
+    is_configurable = True
+
+    metadata = {
+        'Name': 'Review Checklist',
+    }
+    
+    js_model_class = 'Checklist.Extension'
+    
+    css_bundles = {
+	'default': {
+	    'source_filenames': ['css/index.css']
+        }
+    }
+    
+    js_bundles = {
+        'default': {
+	    'source_filenames' : ['js/models/checklist.js',
+		                  'js/models/checklistItem.js',
+                                  'js/views/checklistView.js']
+        }
+    }
+
+    resources = [checklist_resource]
+    
+    def __init__(self, *args, **kwargs):
+        super(Checklist, self).__init__(*args, **kwargs)
+        #pattern = patterns('', (r'^checklist/', include('checklist.urls')))
+        #URLHook(self, pattern)
+        TemplateHook(self, "base-scripts-post", "checklist/template.html",
+	        apply_to=["view_diff", "view_diff_revisions", "file_attachment"])
diff --git a/checklist/checklist/models.py b/checklist/checklist/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..05a9124a6ac4760bbfd817a33af58fff389b88a6
--- /dev/null
+++ b/checklist/checklist/models.py
@@ -0,0 +1,32 @@
+from django.db import models
+from djblets.util.fields import JSONField
+from reviewboard.reviews.models import ReviewRequest
+from django.contrib.auth.models import User
+
+class Checklist(models.Model):
+    checklistID = models.AutoField(primary_key=True)
+    user = models.ForeignKey(User)
+    revRequestID = models.ForeignKey(ReviewRequest)
+    itemsCounter = models.IntegerField()
+    checklistItems = JSONField()
+
+    def addItem(self, item_description):
+        self.itemsCounter += 1
+        checklistItems[self.itemsCounter] = {
+            'finished' : False,
+            'description' : item_description
+        }
+
+    def editItemDesc(self, itemID, item_description):
+	if (itemID in self.checklistItems):
+	    itemDict = self.checklistItems.get(itemID)
+	    itemDict['description'] = item_description
+
+    def editItemStatus(self, itemID):
+	if (itemID in self.checklistItems):
+	    itemDict = self.checklistItems.get(itemID)
+	    itemDict['finished'] = not itemDict['finished']
+
+    def deleteItem(self, itemID):
+	if (itemID in self.checklistItems):
+	    checklistItems.pop(itemID)
diff --git a/checklist/checklist/static/cross.png b/checklist/checklist/static/cross.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a51af98130cd1c1dcbf5cae297d1b03a126256c
Binary files /dev/null and b/checklist/checklist/static/cross.png differ
diff --git a/checklist/checklist/static/css/index.css b/checklist/checklist/static/css/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..99f88cc59c04f5d17649e8621558339d1417b480
--- /dev/null
+++ b/checklist/checklist/static/css/index.css
@@ -0,0 +1,68 @@
+/* Entire container for checklist */
+#checklist {
+  margin: 2%;
+  background-color: #333333;
+  padding: 1%;
+  width: 17%;
+  position: fixed;
+  z-index: 1000;
+  right: 0%;
+  top: 10%;
+  opacity: 0.75;
+}
+
+#checklist ul {
+  list-style-type: none;
+}
+
+input[name="checklist_itemDesc"] {
+  width: 75%;
+  margin-top: 25px;
+}
+
+/* Add item button */
+#checklist_add {
+  background-image:url('/static/ext/checklist.extension.Checklist/plus.png');
+  width: 20px;
+  height: 20px;
+  float: right;
+  margin-top: 3px;
+  clear: both;
+}
+
+/* The minimize and maximize buttons */
+.checklist_min {
+  background-image:url('/static/ext/checklist.extension.Checklist/min.png');
+}
+
+.checklist_max {
+  background-image:url('/static/ext/checklist.extension.Checklist/max.png');
+}
+
+#checklist_toggle_size {
+  width: 16px;
+  height: 16px;
+  float: right;
+  margin-top: -2%;
+  margin-bottom: 5%;
+  clear: left;
+}
+
+input[name="checklist_checkbox"] {
+  margin-right: 5%;
+  margin-left: 1%;
+}
+
+.checklist_item, .checklist_del_item {
+  font-size: 14px;
+  font-weight: bold;
+  color: #ffea38;
+  margin-left: -18%;
+}
+
+.checklist_del_item {
+  background-image:url('/static/ext/checklist.extension.Checklist/cross.png');
+  width: 16px;
+  height: 15px;
+  float: right;
+}
diff --git a/checklist/checklist/static/js/models/checklist.js b/checklist/checklist/static/js/models/checklist.js
new file mode 100644
index 0000000000000000000000000000000000000000..7b59e95816a4220ba2a20d17ec653304386dfd58
--- /dev/null
+++ b/checklist/checklist/static/js/models/checklist.js
@@ -0,0 +1,15 @@
+/* A checklist is a collection of checklist items.
+ * A checklistItem is an individual item in a checklist. */
+var Checklist = {}
+
+Checklist.ChecklistItem = Backbone.Model.extend({
+    defaults: {
+        description: '',
+        id: '',
+        finished: false
+    }
+});
+
+Checklist.Checklist = Backbone.Collection.extend({
+    model: Checklist.ChecklistItem
+});
diff --git a/checklist/checklist/static/js/models/checklistAPI.js b/checklist/checklist/static/js/models/checklistAPI.js
new file mode 100644
index 0000000000000000000000000000000000000000..ec4d6c59bf057a4e8640e4fcbebcc7ff415f3c2a
--- /dev/null
+++ b/checklist/checklist/static/js/models/checklistAPI.js
@@ -0,0 +1,42 @@
+/* An API for the Checklist Extension. */
+
+Checklist.ChecklistAPI = RB.BaseResource.extend({
+
+    defaults: {
+        /* The id of the user interacting with the Checklist. */
+        user_id: null,
+
+        /* The id of the review request the checklist is for. */
+        review_request_id: null,
+
+        /* The item in the checklist being modified / deleted. */
+        checklist_item_id: null,
+        
+        /* The description for the indicated checklist item. */
+        item_description: null,
+
+        /* Indicates whether the checklist item's status should be toggled. */
+        toggle: false
+    },
+
+    url: function() {
+        return '/api/extensions/checklist.extension.Checklist/checklists';
+    },
+
+    toJSON: function(){
+        var data = {};
+        if (this.get('user_id') != null)
+            data.user_id = this.get('user_id');
+        if (this.get('review_request_id') != null)
+            data.review_request_id = this.get('review_request_id');
+        if (this.get('checklist_item_id') != null)
+            data.checklist_item_id = this.get('checklist_item_id');
+        if (this.get('item_description') != null)
+            data.item_description = this.get('item_description');
+        if (this.get('toggle'))
+            data.toggle = this.get(toggle)
+
+        console.log(data);
+        return data;
+    }
+})
\ No newline at end of file
diff --git a/checklist/checklist/static/js/views/checklistView.js b/checklist/checklist/static/js/views/checklistView.js
new file mode 100644
index 0000000000000000000000000000000000000000..e8a28e672e143e3c0abe712b2fe4ebbb255058b7
--- /dev/null
+++ b/checklist/checklist/static/js/views/checklistView.js
@@ -0,0 +1,178 @@
+/* A view for checklistModel. */
+
+Checklist.ChecklistItemView = Backbone.View.extend({
+    tagName: 'li',
+    className: 'checklist_item',
+
+    events: {
+        'click input[name="checklist_checkbox"]' : 'toggleStatus'
+    },
+
+    initialize: function() {
+        _.bindAll(this, 'render', 'toggleStatus');
+    },
+
+    /* Use templates to render. */
+    template: _.template([
+        '<input type="checkbox" name="checklist_checkbox">',
+        '<%= description %>',
+        '<a id=<%= id %> class="checklist_del_item" href="#"></a>'
+    ].join('')),
+
+    render: function() {
+        this.$el.attr('id', 'checklist_item' + this.model.get("id"));
+        this.$el.html(this.template(this.model.attributes));
+        return this;
+    },
+
+    toggleStatus: function() {
+        this.model.set({
+            finished: !this.model.get("finished")
+        });
+    },
+
+});
+
+Checklist.ChecklistView = Backbone.View.extend({
+    el: '#checklist',
+
+    options: {
+        review_request_id: null,
+        user_id: null
+    },
+
+    events: {
+        'click a#checklist_add': 'addItem',
+        'click a.checklist_del_item' : 'removeItem',
+        'click a.checklist_min' : 'minimizeView',
+        'click a.checklist_max' : 'maximizeView'
+    },
+
+    initialize: function(options) {
+        /* Bind every function that uses 'this' as current object. */
+        _.bindAll(this, 'render', 'addItem', 'appendItem', 'removeItem',
+            'minimizeView', 'maximizeView', 'createNewChecklist');
+
+        this.checklistAPI = new Checklist.ChecklistAPI();
+	this.counter = 0;
+        this.curHeight = 0;
+
+        /* Create a new checklist. */
+        this.collection = new Checklist.Checklist();
+        this.collection.bind('add', this.appendItem);
+        this.createNewChecklist();
+    },
+
+    createNewChecklist: function() {
+        /* Create a checklist on the server side. Let the API handle
+	this one. TODO: Must check if a checklist
+	already exists. If it does, do a GET. */
+
+        this.checklistAPI.set({
+	    user_id: this.options.user_id,
+	    review_request_id: this.options.review_request_id,
+	});
+
+	saveOptions = {
+	    success: function(){
+	        this.render();
+	    },
+	    error: function(){
+	        console.log("Error: createNewChecklist");
+	    }
+	};
+
+	this.checklistAPI.save(saveOptions, this);
+    },
+
+    render: function() {
+        var self = this;
+
+        /* Add minimize button */
+        this.$el.append('<a id="checklist_toggle_size" class="checklist_min"></a>');
+		
+        this.$el.append('<input name="checklist_itemDesc"/><a id="checklist_add" ' +
+            'href="#"></a><ul></ul>');
+	
+	this._$ul = this.$('ul');
+        /* If collection is not empty, we want to render each item inside
+	 * it. */
+        $(this.collection.models).each(function(item) {
+            self.appendItem(item);
+        }, this);
+    },
+	
+    minimizeView: function() {
+        var children = this.$el.children();
+        $(children).each(function(index, element) {
+	    $(element).css('visibility', 'hidden');
+        });
+		
+        /* Show the toggle button, and change its class. */
+        $("#checklist_toggle_size").css('visibility', 'visible');
+        $("#checklist_toggle_size").attr('class', 'checklist_max');
+		
+        /* Narrow down the checklist. */
+        this.curHeight = this.$el.height();
+        this.$el.animate({
+            height: "16px",
+            width: "16px"
+        }, 400);
+    },
+
+    maximizeView: function(){
+        var children = this.$el.children();	
+	
+        /* Widen the checklist. */
+        this.$el.animate({
+            'height': this.curHeight,
+            width: "17%"
+        }, 400);
+	
+        
+        $(children).each(function(index, element) {
+            $(element).css('visibility', 'visible');
+        });
+
+        /* Toggle the class of the toggle button. */
+        $("#checklist_toggle_size").attr('class', 'checklist_min');
+    },
+
+    addItem: function() {
+        var item = new Checklist.ChecklistItem();
+        item.set({
+	    description: $('input[name=checklist_itemDesc]').val(),
+            id: this.counter
+        });
+        this.collection.add(item);
+	    this.counter += 1;
+	
+        return false;
+    },
+    
+    appendItem: function(item) {
+        var checklistItemView = new Checklist.ChecklistItemView({
+            model: item
+	});
+        this._$ul.append(checklistItemView.render().el);
+        
+        return false;
+    },
+
+    removeItem: function(e) {
+        /* First, find the item, and remove it from the models. */
+        var id = $(e.currentTarget).attr("id"),
+            item = this.collection.get(id);
+        
+        e.preventDefault();		
+        this.collection.remove(item);
+
+        /* Then remove its view too. */
+        $("#checklist_item" + id).remove();
+
+        return false;
+    },
+});
+
+/* For the instantiation method in the html page. */
+Checklist.Extension = RB.Extension.extend();
diff --git a/checklist/checklist/static/max.png b/checklist/checklist/static/max.png
new file mode 100644
index 0000000000000000000000000000000000000000..13e2903b2e90bfc9c99059ab84124f4788a24f83
Binary files /dev/null and b/checklist/checklist/static/max.png differ
diff --git a/checklist/checklist/static/min.png b/checklist/checklist/static/min.png
new file mode 100644
index 0000000000000000000000000000000000000000..04fa613d7731b43161803e2555d9bf077c53d10c
Binary files /dev/null and b/checklist/checklist/static/min.png differ
diff --git a/checklist/checklist/static/plus.png b/checklist/checklist/static/plus.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3c40885ef0ea279f6551d39cd648e70de65c421
Binary files /dev/null and b/checklist/checklist/static/plus.png differ
diff --git a/checklist/checklist/templates/checklist/configure.html b/checklist/checklist/templates/checklist/configure.html
new file mode 100644
index 0000000000000000000000000000000000000000..c92f183d605a2aaea04a5e651ae3e4d8d6912fab
--- /dev/null
+++ b/checklist/checklist/templates/checklist/configure.html
@@ -0,0 +1,3 @@
+<h5>
+	Eventual configuration should go here.
+</h5>
diff --git a/checklist/checklist/templates/checklist/template.html b/checklist/checklist/templates/checklist/template.html
new file mode 100644
index 0000000000000000000000000000000000000000..a65bf351f869cff0c94908158125fa25ba4a4049
--- /dev/null
+++ b/checklist/checklist/templates/checklist/template.html
@@ -0,0 +1,14 @@
+{% load staticfiles %}
+
+<!--CHECKLIST-->
+<script src="/static/ext/checklist.extension.Checklist/js/models/checklist.js" type="text/javascript"></script>
+<script src="/static/ext/checklist.extension.Checklist/js/views/checklistView.js" type="text/javascript"></script>
+<script src="/static/ext/checklist.extension.Checklist/js/models/checklistAPI.js" type="text/javascript"></script>
+<link rel='stylesheet' type='text/css' href='/static/ext/checklist.extension.Checklist/css/index.css'>
+
+<div id="checklist"></div>
+
+<script>
+    new Checklist.ChecklistView({user_id:"{{user.pk}}", 
+        review_request_id:"{{review_request.id}}"});
+</script>
diff --git a/checklist/setup.py b/checklist/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..d74aa5082580b8bfbeaff7163ed9c8d785a293f4
--- /dev/null
+++ b/checklist/setup.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+from reviewboard.extensions.packaging import setup
+
+
+PACKAGE = "checklist"
+VERSION = "0.1"
+
+setup(
+    name=PACKAGE,
+    version=VERSION,
+    description="Extension checklist",
+    author="None",
+    packages=["checklist"],
+    entry_points={
+        'reviewboard.extensions':
+            '%s = checklist.extension:Checklist' % PACKAGE,
+    },
+    package_data={
+        'checklist': [
+            'templates/checklist/*.txt',
+            'templates/checklist/*.html',
+        ],
+    }
+)
