diff --git a/js/ui/dash.js b/js/ui/dash.js
index 9e01eab..fb871f0 100644
--- a/js/ui/dash.js
+++ b/js/ui/dash.js
@@ -133,7 +133,7 @@ ResultArea.prototype = {
         this.resultsContainer.append(this.display.actor, Big.BoxPackFlags.EXPAND);
 
         this.controlBox = new Big.Box({ x_align: Big.BoxAlignment.CENTER });
-        this.controlBox.append(this.display.displayControl, Big.BoxPackFlags.NONE);
+        this.controlBox.append(this.display.displayControl.actor, Big.BoxPackFlags.NONE);
         this.actor.append(this.controlBox, Big.BoxPackFlags.EXPAND);
 
         this.display.load();
diff --git a/js/ui/genericDisplay.js b/js/ui/genericDisplay.js
index 22e26e2..20ec98c 100644
--- a/js/ui/genericDisplay.js
+++ b/js/ui/genericDisplay.js
@@ -347,13 +347,6 @@ GenericDisplay.prototype = {
         this._list = new Shell.OverflowList({ spacing: 6.0,
                                               item_height: ITEM_DISPLAY_HEIGHT });
 
-        this._list.connect('notify::n-pages', Lang.bind(this, function (grid, alloc) {
-            this._updateDisplayControl(true);
-        }));
-        this._list.connect('notify::page', Lang.bind(this, function (grid, alloc) {
-            this._updateDisplayControl(false);
-        }));
-
         // map<itemId, Object> where Object represents the item info
         this._allItems = {};
         // an array of itemIds of items that match the current request
@@ -367,9 +360,14 @@ GenericDisplay.prototype = {
         // but we also expose a .displayControl actor which is separate.
         // See also getNavigationArea.
         this.actor = this._list;
-        this.displayControl = new Big.Box({ background_color: ITEM_DISPLAY_BACKGROUND_COLOR,
-                                            spacing: 12,
-                                            orientation: Big.BoxOrientation.HORIZONTAL});
+        this.displayControl = new PagingControl(this._list, this._displayPage);
+
+        this._list.connect('notify::n-pages', Lang.bind(this, function (grid, alloc) {
+            this.displayControl.update()
+        }));
+        this._list.connect('notify::page', Lang.bind(this, function (grid, alloc) {
+            this.displayControl.update()
+        }));
     },
 
     //// Public methods ////
@@ -475,13 +473,8 @@ GenericDisplay.prototype = {
     /*
      * Displays items that match the current request and should show up on the current page.
      * Updates the display control to reflect the matched items set and the page selected.
-     *
-     * resetDisplayControl - indicates if the display control should be re-created because 
-     *                       the results or the space allocated for them changed. If it's false,
-     *                       the existing display control is used and only the page links are
-     *                       updated to reflect the current page selection.
      */
-    _displayMatchedItems: function(resetDisplayControl) {
+    _displayMatchedItems: function() {
         // When generating a new list to display, we first remove all the old
         // displayed items which will unset the selection. So we need 
         // to keep a flag which indicates if this display had the selection.
@@ -607,7 +600,7 @@ GenericDisplay.prototype = {
         if (resetPage)
             this._list.page = 0;
 
-        this._displayMatchedItems(true);
+        this._displayMatchedItems();
 
         this.emit('redisplayed');
     },
@@ -703,50 +696,6 @@ GenericDisplay.prototype = {
         this._list.page = pageNumber;
     },
 
-    /*
-     * Updates the display control to reflect the matched items set and the page selected.
-     *
-     * resetDisplayControl - indicates if the display control should be re-created because 
-     *                       the results or the space allocated for them changed. If it's false,
-     *                       the existing display control is used and only the page links are
-     *                       updated to reflect the current page selection.
-     */
-    _updateDisplayControl: function(resetDisplayControl) {
-        if (resetDisplayControl) {
-            this._selectedIndex = -1;
-            this.displayControl.remove_all();
-            let nPages = this._list.n_pages;
-            let pageNumber = this._list.page;
-            for (let i = 0; i < nPages; i++) {
-                let pageControl = new Link.Link({ color: (i == pageNumber) ? DISPLAY_CONTROL_SELECTED_COLOR : ITEM_DISPLAY_DESCRIPTION_COLOR,
-                                                  font_name: "Sans Bold 16px",
-                                                  text: (i+1) + "",
-                                                  reactive: (i == pageNumber) ? false : true});
-                this.displayControl.append(pageControl.actor, Big.BoxPackFlags.NONE);
-
-                // we use pageNumberLocalScope to get the page number right in the callback function
-                let pageNumberLocalScope = i;
-                pageControl.connect('clicked',
-                                    Lang.bind(this,
-                                              function(o, event) {
-                                                  this._displayPage(pageNumberLocalScope);
-                                              }));
-            }
-        } else {
-            let pageControlActors = this.displayControl.get_children();
-            for (let i = 0; i < pageControlActors.length; i++) {
-                let pageControlActor = pageControlActors[i];
-                if (i == this._list.page) {
-                    pageControlActor.color =  DISPLAY_CONTROL_SELECTED_COLOR;
-                    pageControlActor.reactive = false;
-                } else {
-                    pageControlActor.color =  ITEM_DISPLAY_DESCRIPTION_COLOR;
-                    pageControlActor.reactive = true;
-                }
-            } 
-        }
-    },
-
     // Returns a display item based on its index in the ordering of the
     // display children.
     _findDisplayedByIndex: function(index) {
@@ -795,3 +744,174 @@ GenericDisplay.prototype = {
 };
 
 Signals.addSignalMethods(GenericDisplay.prototype);
+
+function PagingControl(list, callback) {
+    this._init(list, callback);
+}
+
+PagingControl.prototype = {
+    _init : function(list, callback) {
+        this.actor = new Shell.GenericContainer();
+        this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+        this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+        this.actor.connect('allocate', Lang.bind(this, this._allocate));
+
+        this._list = list;
+        this._callback = callback;
+        this._pageControls = [];
+        this._numPages = 0;
+        this._currentPage = 0;
+        this._spacing = 12;
+        this._maxWidth = null;
+        this._goFirst = this._createActor(0, "<<");
+        this._goLast = this._createActor(-1, ">>");
+        this.update();
+    },
+
+    _createActor : function(pageNumber, text) {
+        let pageControl = new Link.Link({ color: ITEM_DISPLAY_DESCRIPTION_COLOR,
+                                          font_name: "Sans Bold 16px",
+                                          text: text,
+                                          reactive: true});
+        pageControl.connect('clicked',
+                            Lang.bind(this, function(o, event) {
+                                                this._callback(pageNumber);
+                                            }));
+        return pageControl;
+    },
+
+    _resetActors: function() {
+        this.actor.remove_all();
+        this.actor.add_actor(this._goFirst.actor);
+        for (let i = 0; i < this._pageControls.length; i++)
+            this.actor.add_actor(this._pageControls[i].actor)
+        this.actor.add_actor(this._goLast.actor);
+    },
+
+    _createActors : function() {
+        let numPages = this._list.n_pages;
+        if (numPages < this._numPages)
+            this._pageControls.slice(numPages, this._numPages - numPages);
+        else if (numPages > this._numPages)
+            for (let i = this._numPages + 1; i <= numPages; i++) {
+                let pageNumber = i; // local scope
+                this._pageControls.push(this._createActor(pageNumber - 1,
+                                                           pageNumber + ""));
+            }
+        if (numPages != this._numPages) {
+            if (this.actor.get_children().length > 0)
+                this.actor.remove_actor(this._goLast.actor);
+            this._goLast = this._createActor(numPages - 1, ">>");
+            this._resetActors();
+            this._numPages = numPages;
+        }
+    },
+
+    _getPreferredWidth: function (grid, forHeight, alloc) {
+        if (this._numPages < 2) {
+            alloc.min_size = 0;
+            alloc.natural_size = 0;
+            return;
+        }
+
+        let minWidth = 0, naturalWidth = 0;
+        let children = this.actor.get_children();
+        for (let i = 0; i < children.length; i++) {
+            let [currentMinWidth, currentNaturalWidth] = children[i].get_preferred_width(forHeight);
+            if (currentMinWidth > minWidth)
+                minWidth = currentMinWidth;
+            if (currentNaturalWidth > naturalWidth)
+                naturalWidth = currentNaturalWidth;
+        }
+        this._maxWidth = naturalWidth;
+
+        alloc.min_size = minWidth * 2 + this._spacing;
+        alloc.natural_size = naturalWidth * this._numPages + this._spacing * (this._numPages - 1);
+    },
+
+    _getPreferredHeight: function (grid, forWidth, alloc) {
+        if (this._numPages < 2) {
+            alloc.min_size = 0;
+            alloc.natural_size = 0;
+            return;
+        }
+
+        let minHeight = 0, naturalHeight = 0;
+        let children = this.actor.get_children();
+        for (let i = 0; i <  children.length; i++) {
+            let [currentMinHeight, currentNaturalHeight] = children[i].get_preferred_height(forWidth);
+            if (currentMinHeight > minHeight)
+                minHeight = currentMinHeight;
+            if (currentNaturalHeight > naturalHeight)
+                naturalHeight = currentNaturalHeight;
+        }
+
+        alloc.min_size = minHeight;
+        alloc.natural_size = naturalHeight;
+    },
+
+    _allocate: function (grid, box, flags) {
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
+        let children = this.actor.get_children();
+
+        let numVisiblePages = Math.min(this._numPages,
+                                       Math.floor(availWidth / (this._maxWidth + this._spacing)));
+        let leftmostPage = Math.max(0, this._currentPage - Math.floor(numVisiblePages / 2));
+        let rightmostPage = Math.min(this._numPages, leftmostPage + numVisiblePages);
+
+        let showGoFirst = leftmostPage > 1;
+        if (leftmostPage == 1)
+            leftmostPage = 0;
+        let showGoLast = rightmostPage < (this._numPages - 1);
+        if (rightmostPage == (this._numPages - 1))
+            rightmostPage = this._numPages;
+        let visiblePages = [];
+        let usedWidth = 0;
+        for (let i = 0; i < children.length; i++) {
+            if ((i == 0 && !showGoFirst) || (i == (children.length - 1) && !showGoLast) ||
+                (i <= leftmostPage && i != 0) || (i >= rightmostPage && (i != children.length - 1))) {
+                children[i].hide();
+                continue;
+            }
+            children[i].show();
+
+            let [childMinWidth, childMinHeight,
+                 childNaturalWidth, childNaturalHeight] = children[i].get_preferred_size();
+            visiblePages.push(i);
+            usedWidth += childNaturalWidth + (i > 0 && i != (children.length - 1)) ? this._spacing : 0;
+        }
+
+        let x = box.x1; // + ((availWidth - usedWidth) / 2);
+        let y = box.y1;
+        for each (let i in visiblePages) {
+            let [childMinWidth, childMinHeight,
+                 childNaturalWidth, childNaturalHeight] = children[i].get_preferred_size();
+
+            let childBox = new Clutter.ActorBox();
+            childBox.x1 = x;
+            childBox.y1 = y;
+            childBox.x2 = childBox.x1 + childNaturalWidth;
+            childBox.y2 = childBox.y1 + childNaturalHeight;
+            children[i].allocate(childBox, flags);
+            x = childBox.x2 + this._spacing;
+        }
+     },
+
+    update : function() {
+        this._createActors();
+        let pageNumber = this._list.page;
+        let previousPage = this._pageControls[this._currentPage].actor;
+        let currentPage = this._pageControls[pageNumber].actor;
+
+        previousPage.reactive = true;
+        previousPage.color = ITEM_DISPLAY_DESCRIPTION_COLOR;
+        currentPage.reactive = false;
+        currentPage.color = DISPLAY_CONTROL_SELECTED_COLOR;
+
+        this._currentPage = pageNumber;
+        this.actor.queue_relayout();
+    }
+};
+
+Signals.addSignalMethods(PagingControl.prototype);
