diff --git a/app/views/aspects/_aspect_stream.haml b/app/views/aspects/_aspect_stream.haml
index 564b1d9612b01620e7479f1444d9b314ad89672a..0ddc45b9488826f2c9a46e7e67d5d82a50d390d7 100644
--- a/app/views/aspects/_aspect_stream.haml
+++ b/app/views/aspects/_aspect_stream.haml
@@ -10,7 +10,9 @@
 
 #gs-shim{:title => popover_with_close_html("3. #{t('.stay_updated')}"), 'data-content' => t('.stay_updated_explanation')}
 
-#main_stream.stream{:data => {:guids => stream.aspect_ids.join(',')}}
+#main_stream.stream
+
+#paginate
 
 - if current_user.contacts.size < 2
   = render 'aspects/no_contacts_message'
diff --git a/public/javascripts/app/models/stream.js b/public/javascripts/app/models/stream.js
index 8611af3e28d538a4b4e2bc855ba39c45ef34e6a6..bee78eebb6882c1423c9a352050f42d3b57542e1 100644
--- a/public/javascripts/app/models/stream.js
+++ b/public/javascripts/app/models/stream.js
@@ -7,19 +7,33 @@ app.models.Stream = Backbone.Collection.extend({
     return _.any(this.posts.models) ? this.timeFilteredPath() : this.basePath()
   },
 
+  _fetching : false,
+
   fetch: function() {
     var self = this
 
+    // we're fetching the collection... there is probably a better way to do this
+    self._fetching = true;
+
     this.posts
       .fetch({
         add : true,
         url : self.url()
       })
       .done(
-        function(){ 
+        function(resp){
+          // we're done fetching... there is probably a better way to handle this
+          self._fetching = false;
+
           self.trigger("fetched", self);
+
+          // all loaded?
+          if(resp.posts && (resp.posts.author || resp.posts.length == 0)) {
+            self.trigger("allPostsLoaded", self);
+          }
         }
       )
+    return this;
   },
 
   basePath : function(){
diff --git a/public/javascripts/app/router.js b/public/javascripts/app/router.js
index 986e2789b3013805c2094b01db36bbc6bfa2f441..effd9dadcb3f3f05e81cdc7538731d6e0d15d523 100644
--- a/public/javascripts/app/router.js
+++ b/public/javascripts/app/router.js
@@ -14,10 +14,12 @@ app.Router = Backbone.Router.extend({
 
   stream : function() {
     app.stream = new app.models.Stream()
-    app.page = new app.views.Stream().render();
-    $("#main_stream").html(app.page.el);
+    app.page = new app.views.Stream({model : app.stream}).render();
+    app.publisher = app.publisher || new app.views.Publisher({collection : app.stream.posts});
 
     var streamFacesView = new app.views.StreamFaces({collection : app.stream.posts}).render();
+
+    $("#main_stream").html(app.page.el);
     $('#selected_aspect_contacts .content').html(streamFacesView.el);
   }
 });
diff --git a/public/javascripts/app/views/commment_stream_view.js b/public/javascripts/app/views/commment_stream_view.js
index 5348ed55d0f55fbf6d918da257c52d5c8bad8fd9..f47a1a00c167d97764bd452b870eb0a9c48534df 100644
--- a/public/javascripts/app/views/commment_stream_view.js
+++ b/public/javascripts/app/views/commment_stream_view.js
@@ -12,6 +12,9 @@ app.views.CommentStream = app.views.Base.extend({
 
   initialize: function(options) {
     this.model.comments.bind('add', this.appendComment, this);
+
+    // add autoexpanders to new comment textarea
+    this.$('textarea').autoResize();
   },
 
   postRenderTemplate : function() {
diff --git a/public/javascripts/app/views/publisher_view.js b/public/javascripts/app/views/publisher_view.js
index 68e358ca048a6175828764e8fb18d74fd9316b87..b33f4ea2e5ce1aa98e9bc6db573bdf5129851715 100644
--- a/public/javascripts/app/views/publisher_view.js
+++ b/public/javascripts/app/views/publisher_view.js
@@ -12,7 +12,7 @@ app.views.Publisher = Backbone.View.extend({
   },
 
   initialize : function(){
-    this.collection = this.collection || new app.collections.Posts;
+    this.collection = this.collection //takes a Posts collection
     return this;
   },
 
diff --git a/public/javascripts/app/views/stream_view.js b/public/javascripts/app/views/stream_view.js
index 8f396f39215464cc32c14248d3eeeb118004a6c1..7dbd08c14898622d64e0c5b00b866a34ca8a9fbf 100644
--- a/public/javascripts/app/views/stream_view.js
+++ b/public/javascripts/app/views/stream_view.js
@@ -4,16 +4,20 @@ app.views.Stream = Backbone.View.extend({
   },
 
   initialize: function(options) {
-    this.stream = app.stream || new app.models.Stream()
-    this.collection = this.stream.posts
-    this.publisher = new app.views.Publisher({collection : this.collection});
+    this.stream = this.model
+    this.collection = this.model.posts
 
-    this.stream.bind("fetched", this.collectionFetched, this)
-    this.collection.bind("add", this.addPost, this);
+    this.setupEvents()
     this.setupInfiniteScroll()
     this.setupLightbox()
   },
 
+  setupEvents : function(){
+    this.stream.bind("fetched", this.removeLoader, this)
+    this.stream.bind("allPostsLoaded", this.unbindInfScroll, this)
+    this.collection.bind("add", this.addPost, this);
+  },
+
   addPost : function(post) {
     var postView = new app.views.Post({ model: post });
 
@@ -26,51 +30,30 @@ app.views.Stream = Backbone.View.extend({
     return this;
   },
 
-  isLoading : function(){
-    return this._loading && !this._loading.isResolved();
-  },
-
-  allContentLoaded : false,
-
-
-  collectionFetched: function(collection, response) {
-    this.removeLoader()
-    if(!collection.parse(response).length || collection.parse(response).length == 0) {
-      this.allContentLoaded = true;
-      $(window).unbind('scroll')
-      return
-    }
-
-    $(this.el).append($("<a>", {
-      href: this.stream.url(),
-      id: "paginate"
-    }).text('Load more posts'));
+  unbindInfScroll : function() {
+    $("window").unbind("scroll");
   },
 
   render : function(evt) {
     if(evt) { evt.preventDefault(); }
 
-    this.addLoader();
-    this._loading = this.stream.fetch();
+    // fetch more posts from the stream model
+    if(this.stream.fetch()) {
+      this.appendLoader()
+    };
 
     return this;
   },
 
-  addLoader: function(){
-    if(this.$("#paginate").length == 0) {
-      $(this.el).append($("<div>", {
-        "id" : "paginate"
-      }));
-    }
-
-    this.$("#paginate").html($("<img>", {
+  appendLoader: function(){
+    $("#paginate").html($("<img>", {
       src : "/images/static-loader.png",
       "class" : "loader"
     }));
   },
 
-  removeLoader : function(){
-    this.$("#paginate").remove();
+  removeLoader: function() {
+    $("#paginate").empty();
   },
 
   setupLightbox : function(){
@@ -80,13 +63,11 @@ app.views.Stream = Backbone.View.extend({
 
   setupInfiniteScroll : function() {
     var throttledScroll = _.throttle($.proxy(this.infScroll, this), 200);
-    $(window).scroll(throttledScroll);
+    $("window").scroll(throttledScroll);
   },
 
   infScroll : function() {
-    if(this.allContentLoaded || this.isLoading()) { return }
-
-    var $window = $(window);
+    var $window = $("window");
     var distFromTop = $window.height() + $window.scrollTop();
     var distFromBottom = $(document).height() - distFromTop;
     var bufferPx = 500;
diff --git a/spec/javascripts/app/models/stream_spec.js b/spec/javascripts/app/models/stream_spec.js
index 064b8d8ddbda502e783e477aa86356931c2b354f..c7a18f62146cb66423d6263df75adf718bd93787 100644
--- a/spec/javascripts/app/models/stream_spec.js
+++ b/spec/javascripts/app/models/stream_spec.js
@@ -9,7 +9,7 @@ describe("app.models.Stream", function() {
     beforeEach(function(){
       postFetch = new $.Deferred()
 
-      spyOn(this.stream.posts, "fetch").andCallFake(function(){ 
+      spyOn(this.stream.posts, "fetch").andCallFake(function(){
         return postFetch
       })
     })
@@ -32,7 +32,23 @@ describe("app.models.Stream", function() {
       var fetchedSpy = jasmine.createSpy()
       this.stream.bind('fetched', fetchedSpy)
       this.stream.fetch()
-      postFetch.resolve()
+      postFetch.resolve({posts : [1,2,3]})
+      expect(fetchedSpy).toHaveBeenCalled()
+    })
+
+    it("triggers allPostsLoaded on the stream when zero posts are returned", function(){
+      var fetchedSpy = jasmine.createSpy()
+      this.stream.bind('allPostsLoaded', fetchedSpy)
+      this.stream.fetch()
+      postFetch.resolve({posts : []})
+      expect(fetchedSpy).toHaveBeenCalled()
+    })
+
+    it("triggers allPostsLoaded on the stream when a Post is returned", function(){
+      var fetchedSpy = jasmine.createSpy()
+      this.stream.bind('allPostsLoaded', fetchedSpy)
+      this.stream.fetch()
+      postFetch.resolve({posts : factory.post().attributes})
       expect(fetchedSpy).toHaveBeenCalled()
     })
   });
diff --git a/spec/javascripts/app/views/stream_view_spec.js b/spec/javascripts/app/views/stream_view_spec.js
index 38160b033cb3a921d4884fc8a625cf20130e0dc5..5f3b1d3714a80dfef31d3896040ce42f4269775b 100644
--- a/spec/javascripts/app/views/stream_view_spec.js
+++ b/spec/javascripts/app/views/stream_view_spec.js
@@ -4,11 +4,10 @@ describe("app.views.Stream", function(){
 
     this.posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"];
 
-    app.stream = new app.models.Stream()
-    app.stream.add(this.posts);
+    this.stream = new app.models.Stream()
+    this.stream.add(this.posts);
 
-    this.collection = app.stream.posts
-    this.view = new app.views.Stream({collection : this.collection});
+    this.view = new app.views.Stream({model : this.stream});
 
     app.stream.bind("fetched", this.collectionFetched, this) //untested
 
@@ -20,16 +19,15 @@ describe("app.views.Stream", function(){
   describe("initialize", function(){
     it("binds an infinite scroll listener", function(){
       spyOn($.fn, "scroll");
-
-      new app.views.Stream();
+      new app.views.Stream({model : this.stream});
       expect($.fn.scroll).toHaveBeenCalled()
     })
   })
 
   describe("#render", function(){
     beforeEach(function(){
-      this.statusMessage = this.collection.models[0];
-      this.reshare = this.collection.models[1];
+      this.statusMessage = this.stream.posts.models[0];
+      this.reshare = this.stream.posts.models[1];
       this.statusElement = $(this.view.$("#" + this.statusMessage.get("guid")));
       this.reshareElement = $(this.view.$("#" + this.reshare.get("guid")));
     })
@@ -44,77 +42,31 @@ describe("app.views.Stream", function(){
   describe("infScroll", function(){
     // NOTE: inf scroll happens at 500px
 
-    beforeEach(function(){
-      spyOn(this.view.collection, "fetch").andReturn($.Deferred())
-    })
-
-    context("when the user is at the bottom of the page", function(){
-      beforeEach(function(){
-        spyOn($.fn, "height").andReturn(0)
-        spyOn($.fn, "scrollTop").andReturn(100)
-      })
-
-      it("calls fetch", function(){
-        spyOn(this.view, "isLoading").andReturn(false)
-
-        this.view.infScroll();
-        expect(this.view.collection.fetch).toHaveBeenCalled();
-      })
-
-      it("does not call fetch if the collection is loading", function(){
-        spyOn(this.view, "isLoading").andReturn(true)
-
-        this.view.infScroll();
-        expect(this.view.collection.fetch).not.toHaveBeenCalled();
-      })
-
-      it("does not call fetch if all content has been fetched", function(){
-        spyOn(this.view, "isLoading").andReturn(false)
-        this.view.allContentLoaded = true;
-
-        this.view.infScroll();
-        expect(this.view.collection.fetch).not.toHaveBeenCalled();
-      })
-    })
-
-    it("does not fetch new content when the user is not at the bottom of the page", function(){
-      spyOn(this.view, "isLoading").andReturn(false)
-
-      spyOn($.fn, "height").andReturn(0);
-      spyOn($.fn, "scrollTop").andReturn(-500);
+    it("calls render when the user is at the bottom of the page", function(){
+      spyOn($.fn, "height").andReturn(0)
+      spyOn($.fn, "scrollTop").andReturn(100)
+      spyOn(this.view, "render")
 
       this.view.infScroll();
-      expect(this.view.collection.fetch).not.toHaveBeenCalled();
+      expect(this.view.render).toHaveBeenCalled();
     })
   })
 
-  describe("collectionFetched", function(){
-    context("unbinding scroll", function(){
-      beforeEach(function(){
-        spyOn($.fn, "unbind")
-      })
-
-      it("unbinds scroll if there are no more posts left to load", function(){
-        this.view.collectionFetched(this.collection, {posts : []})
-        expect($.fn.unbind).toHaveBeenCalled()
-      })
-
-      it("does not fetch new content when the user is fetching one post", function(){
-        this.view.collectionFetched(this.collection, {posts : {}})
-        expect($.fn.unbind).toHaveBeenCalled()
-      })
-    })
-
-    it("sets this.allContentLoaded if there are no more posts left to load", function(){
-      expect(this.view.allContentLoaded).toBe(false)
-      this.view.collectionFetched(this.collection, {posts : []})
-      expect(this.view.allContentLoaded).toBe(true)
+  describe("removeLoader", function() {
+    it("emptys the pagination div when the stream is fetched", function(){
+      $("#jasmine_content").append($('<div id="paginate">OMG</div>'))
+      expect($("#paginate").text()).toBe("OMG")
+      this.view.stream.trigger("fetched")
+      expect($("#paginate")).toBeEmpty()
     })
+  })
 
-    it("does not set this.allContentLoaded if there was a non-empty response from the server", function(){
-      expect(this.view.allContentLoaded).toBe(false)
-      this.view.collectionFetched(this.collection, {posts : this.posts})
-      expect(this.view.allContentLoaded).toBe(false)
+  describe("unbindInfScroll", function(){
+    it("unbinds scroll", function() {
+      spyOn($.fn, "unbind")
+      this.view.unbindInfScroll()
+      expect($.fn.unbind.mostRecentCall.object.selector).toBe("window")
+      expect($.fn.unbind).toHaveBeenCalledWith("scroll")
     })
   })
 })