   # Helper method for onScroll that separates the sticky components
   # into the keys of those which should now be stuck and those that
   # shouldn't.  
-  determineIfStuck : (sorted_by_original_y) -> 
+  determineIfStuck : (stickies) -> 
     stuck = []; unstuck = []
 
     # Whether the screen is zoomed or quite small 
     zoomed_or_small = window.innerWidth < $(window).width() || screen.width <= 700
 
+    # Sort by stacking order. Stacking order based on the 
+    # y position when the component was mounted. 
+    sorted = _.sortBy(_.values(stickies), (v) -> v.stack_priority)
+
     y_stack = 0
-    for [k, v] in sorted_by_original_y
+    for v in sorted
 
       if v.skip_stick || (!v.stick_on_zoom && zoomed_or_small)
         is_stuck = false 

        c.GEQ, \
        scroller.viewport_top - v.jut + y_stack, \
        if scrolling_down then c.Strength.weak else c.Strength.medium

      # Try to keep the bottom above the viewport, especially when scrolling down
      console.log "\tBottom Above viewport bottom: #{k} + #{v.$el.height() + v.jut} <= #{scroller.viewport_top} + #{viewport_height}, #{if scrolling_down then 'weak' else 'medium'}" if debug
      solver.addConstraint new c.Inequality \

  #
  # Different constraints may need to be introduced to accommodate different
  # sticky component configurations.   
  solveForY : (stickies) -> 
    
    # cassowary constraint solver
    solver = new c.SimplexSolver()    

    # Stores the cassowary variables representing each component's y-position 
    # that the solver will optimize. 
    y_pos = {}
    for own k,v of stickies
      y_pos[k] = new c.Variable

    # We modify the contraints slightly based on whether we're scrolling up or down
    scrolling_down = scroller.viewport_top > scroller.last_viewport_top
    scroll_distance = Math.abs(scroller.viewport_top - scroller.last_viewport_top)

    viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)

    # We'll iterate through each component in order of their stacking priority
    y_stack = 0

    sorted = _.sortBy(_.values(stickies), (v) -> v.stack_priority)

    ########
    # Linear constraints
    #
    # Set the constraints for the y-position of each docked component. 
    #
    # y(t) is the y-position of this component at time t. 
    # v(t) is the viewport top at time t
    #
    # START
    # The component shouldn't be placed above its specified docking start location.
    #        y(t) >= start
    #
    # STOP
    # The component shouldn't be placed below its specified docking stopping location.
    #        y(t) + height <= stop
    #    
    # BOUNDED BY SCROLL DISTANCE (strength = strong)
    # If this component has previously been positioned, the change in position
    # should be bound by the scroll distance. 
    #       |y(t) - y(t-1)| <= |v(t) - v(t-1)|
    #
    # CLOSE TO TOP (strength = weak)
    # Prefer being close to the top of the viewport. In the future, if we need
    # to support components preferring to be stuck to bottom, we'd need to 
    # conditionally set the component's edge preference. 
    #        y(t) = v(t)
    #
    # BELOW VIEWPORT TOP (strength = variable)
    # Try to keep y(t) at or below the viewport to be seen. In order to 
    # implement the scheme described at http://stackoverflow.com/questions/18358816, 
    # we weaken the strength of this constraint when scrolling down and strengthen 
    # it when scrolling up. 
    #        y(t) >= v(t) + sum of heights of components higher in stack
    #
    # BOTTOM OF COMPONENT ABOVE VIEWPORT BOTTOM (strenth = variable)
    # Like the previous constraint. Try to keep the bottom of the component in
    # the viewport so it can be seen. We increase the strength of this constraint
    # when scrolling down and weaken it when scrolling up.
    #        y(t) + component height <= v(t) + viewport height
    #
    # RELATIONAL
    # Add any declared constraints between different sticky components, constraining
    # the one higher in the stacking order to always be above and non-overlapping 
    # the one lower in the stacking order
    #        y1(t) + height <= y2(t)


    for v, i in sorted
      console.log "**#{v.key} constraints**" if debug
      k = v.key; sticky = fetch k

      # START
      console.log "\tStart: #{k} >= #{v.start}, required" if debug
      solver.addConstraint new c.Inequality \
        y_pos[k], c.GEQ, v.start

      # STOP
      console.log "\tStop: #{k} <= #{v.stop - (v.height)}, required" if debug
      solver.addConstraint new c.Inequality \
        y_pos[k], c.LEQ, v.stop - v.height

      if sticky.y?
        # BOUNDED BY SCROLL DISTANCE
        console.log "\tBOUNDED BY SCROLL DISTANCE: |#{k} - #{sticky.y}| <= |#{scroller.viewport_top} - #{scroller.last_viewport_top}|, strong" if debug
        solver.addConstraint new c.Inequality \
          y_pos[k], \
          c.LEQ,
