Index: components/reorderer/js/GeometricManager.js
===================================================================
--- components/reorderer/js/GeometricManager.js	(revision 10166)
+++ components/reorderer/js/GeometricManager.js	(working copy)
@@ -1,6 +1,7 @@
 /*
 Copyright 2008-2010 University of Cambridge
 Copyright 2008-2010 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -237,57 +238,14 @@
         }
     }
     
-    fluid.dropManager = function () {
+   
+    
+    fluid.dropManager = function () { 
         var targets = [];
         var cache = {};
-        var that = {};
-        
-        var lastClosest;
-        
-        function cacheKey(element) {
-            return fluid.allocateSimpleId(element);
-        }
-        
-        function sentinelizeElement(targets, sides, cacheelem, fc, disposition, clazz) {
-            var elemCopy = $.extend(true, {}, cacheelem);
-            elemCopy.rect[sides[fc]] = elemCopy.rect[sides[1 - fc]] + (fc? 1: -1);
-            elemCopy.rect[sides[1 - fc]] = (fc? -1 : 1) * SENTINEL_DIMENSION;
-            elemCopy.position = disposition === fluid.position.INSIDE?
-               disposition : (fc? fluid.position.BEFORE : fluid.position.AFTER);
-            elemCopy.clazz = clazz;
-            targets[targets.length] = elemCopy;
-        }
+        var that = {};        
         
-        function splitElement(targets, sides, cacheelem, disposition, clazz1, clazz2) {
-            var elem1 = $.extend(true, {}, cacheelem);
-            var elem2 = $.extend(true, {}, cacheelem);
-            var midpoint = (elem1.rect[sides[0]] + elem1.rect[sides[1]]) / 2;
-            elem1.rect[sides[1]] = midpoint; 
-            elem1.position = fluid.position.BEFORE;
-            
-            elem2.rect[sides[0]] = midpoint; 
-            elem2.position = fluid.position.AFTER;
-            
-            elem1.clazz = clazz1;
-            elem2.clazz = clazz2;
-            targets[targets.length] = elem1;
-            targets[targets.length] = elem2;
-        }
-       
-        // Expand this configuration point if we ever go back to a full "permissions" model
-        function getRelativeClass(thisElements, index, relative, thisclazz, mapper) {
-            index += relative;
-            if (index < 0 && thisclazz === "locked") {
-                return "locked";
-            }
-            if (index >= thisElements.length || mapper === null) {
-                return null;
-            } else {
-                relative = thisElements[index];
-                return mapper(relative) === "locked" && thisclazz === "locked" ? "locked" : null;
-            }
-        }
-        
+        var lastClosest;              
         var lastGeometry;
         var displacementX, displacementY;
         
@@ -307,21 +265,21 @@
                     if (cacheelem.clazz !== "hidden" && mapper) {
                         cacheelem.clazz = mapper(element);
                     }
-                    cache[cacheKey(element)] = cacheelem;
-                    var backClass = getRelativeClass(thisInfo.elements, j, fluid.position.BEFORE, cacheelem.clazz, mapper); 
-                    var frontClass = getRelativeClass(thisInfo.elements, j, fluid.position.AFTER, cacheelem.clazz, mapper); 
+                    cache[fluid.dropManager.cacheKey(element)] = cacheelem;
+                    var backClass = fluid.dropManager.getRelativeClass(thisInfo.elements, j, fluid.position.BEFORE, cacheelem.clazz, mapper); 
+                    var frontClass = fluid.dropManager.getRelativeClass(thisInfo.elements, j, fluid.position.AFTER, cacheelem.clazz, mapper); 
                     if (disposition === fluid.position.INSIDE) {
                         targets[targets.length] = cacheelem;
                     }
                     else {
-                        splitElement(targets, sides, cacheelem, disposition, backClass, frontClass);
+                        fluid.dropManager.splitElement(targets, sides, cacheelem, disposition, backClass, frontClass);
                     }
                     // deal with sentinel blocks by creating near-copies of the end elements
                     if (sentB && geometricInfo.sentinelize) {
-                        sentinelizeElement(targets, sides, cacheelem, 1, disposition, backClass);
+                        fluid.dropManager.sentinelizeElement(targets, sides, cacheelem, 1, disposition, backClass);
                     }
                     if (sentF && geometricInfo.sentinelize) {
-                        sentinelizeElement(targets, sides, cacheelem, 0, disposition, frontClass);
+                        fluid.dropManager.sentinelizeElement(targets, sides, cacheelem, 0, disposition, frontClass);
                     }
                     //fluid.log(dumpelem(cacheelem));
                     return cacheelem;
@@ -431,18 +389,18 @@
             };
         };
         
-        that.shuffleProjectFrom = function (element, direction, includeLocked) {
-            var togo = that.projectFrom(element, direction, includeLocked);
+        that.shuffleProjectFrom = function (element, direction, includeLocked, disableWrap) {
+            var togo = that.projectFrom(element, direction, includeLocked, disableWrap);
             if (togo) {
                 togo.position = fluid.position.REPLACE;
             }
             return togo;
         };
         
-        that.projectFrom = function (element, direction, includeLocked) {
+        that.projectFrom = function (element, direction, includeLocked, disableWrap) {
             that.updateGeometry(lastGeometry);
-            var cacheelem = cache[cacheKey(element)];
-            var projected = fluid.geom.projectFrom(cacheelem.rect, direction, targets, includeLocked);
+            var cacheelem = cache[fluid.dropManager.cacheKey(element)];
+            var projected = fluid.geom.projectFrom(cacheelem.rect, direction, targets, includeLocked, disableWrap);
             if (!projected.cacheelem) {
                 return null;
             }
@@ -452,31 +410,20 @@
                      };
         };
         
-        function getRelativeElement(element, direction, elements) {
-            var folded = fluid.directionSign(direction);
-      
-            var index = $(elements).index(element) + folded;
-            if (index < 0) {
-                index += elements.length;
-            }
-            index %= elements.length;
-            return elements[index];            
-        }
-        
-        that.logicalFrom = function (element, direction, includeLocked) {
+        that.logicalFrom = function (element, direction, includeLocked, disableWrap) {
             var orderables = that.getOwningSpan(element, fluid.position.INTERLEAVED, includeLocked);
-            return {element: getRelativeElement(element, direction, orderables), 
+            return {element: fluid.dropManager.getRelativeElement(element, direction, orderables, disableWrap), 
                 position: fluid.position.REPLACE};
         };
            
-        that.lockedWrapFrom = function (element, direction, includeLocked) {
-            var base = that.logicalFrom(element, direction, includeLocked);
+        that.lockedWrapFrom = function (element, direction, includeLocked, disableWrap) {
+            var base = that.logicalFrom(element, direction, includeLocked, disableWrap);
             var selectables = that.getOwningSpan(element, fluid.position.INTERLEAVED, includeLocked);
-            var allElements = cache[cacheKey(element)].owner.elements;
+            var allElements = cache[fluid.dropManager.cacheKey(element)].owner.elements;
             if (includeLocked || selectables[0] === allElements[0]) {
                 return base;
             }
-            var directElement = getRelativeElement(element, direction, allElements);
+            var directElement = fluid.dropManager.getRelativeElement(element, direction, allElements, disableWrap);
             if (lastGeometry.elementMapper(directElement) === "locked") {
                 base.element = null;
                 base.clazz = "locked";  
@@ -485,7 +432,7 @@
         }; 
         
         that.getOwningSpan = function (element, position, includeLocked) {
-            var owner = cache[cacheKey(element)].owner; 
+            var owner = cache[fluid.dropManager.cacheKey(element)].owner; 
             var elements = position === fluid.position.INSIDE? [owner.parentElement] : owner.elements;
             if (!includeLocked && lastGeometry.elementMapper) {
                 elements = $.makeArray(elements);
@@ -500,14 +447,77 @@
             var sourceElements = that.getOwningSpan(element, null, true);
             var targetElements = that.getOwningSpan(target, position, true);
             fluid.permuteDom(element, target, position, sourceElements, targetElements);
-        };
+        };              
         
         return that;
-    };
+    };    
+   
  
     fluid.dropManager.NO_CHANGE = "no change";
-
-
+    
+    fluid.dropManager.cacheKey = function (element) {
+        return fluid.allocateSimpleId(element);
+    };
+    
+    fluid.dropManager.sentinelizeElement = function (targets, sides, cacheelem, fc, disposition, clazz) {
+        var elemCopy = $.extend(true, {}, cacheelem);
+        elemCopy.rect[sides[fc]] = elemCopy.rect[sides[1 - fc]] + (fc? 1: -1);
+        elemCopy.rect[sides[1 - fc]] = (fc? -1 : 1) * SENTINEL_DIMENSION;
+        elemCopy.position = disposition === fluid.position.INSIDE?
+           disposition : (fc? fluid.position.BEFORE : fluid.position.AFTER);
+        elemCopy.clazz = clazz;
+        targets[targets.length] = elemCopy;
+    };
+    
+    fluid.dropManager.splitElement = function (targets, sides, cacheelem, disposition, clazz1, clazz2) {
+        var elem1 = $.extend(true, {}, cacheelem);
+        var elem2 = $.extend(true, {}, cacheelem);
+        var midpoint = (elem1.rect[sides[0]] + elem1.rect[sides[1]]) / 2;
+        elem1.rect[sides[1]] = midpoint; 
+        elem1.position = fluid.position.BEFORE;
+        
+        elem2.rect[sides[0]] = midpoint; 
+        elem2.position = fluid.position.AFTER;
+        
+        elem1.clazz = clazz1;
+        elem2.clazz = clazz2;
+        targets[targets.length] = elem1;
+        targets[targets.length] = elem2;
+    };
+    
+    // Expand this configuration point if we ever go back to a full "permissions" model
+    fluid.dropManager.getRelativeClass = function (thisElements, index, relative, thisclazz, mapper) {
+        index += relative;
+        if (index < 0 && thisclazz === "locked") {
+            return "locked";
+        }
+        if (index >= thisElements.length || mapper === null) {
+            return null;
+        } else {
+            relative = thisElements[index];
+            return mapper(relative) === "locked" && thisclazz === "locked" ? "locked" : null;
+        }
+    };
+    
+     fluid.dropManager.getRelativeElement = function (element, direction, elements, disableWrap) {
+        var folded = fluid.directionSign(direction);
+  
+        var index = $(elements).index(element) + folded;
+        if (index < 0) {
+            index += elements.length;
+        }
+        
+        // disable wrap
+        if (disableWrap) {                   
+            if (index === elements.length || index === (elements.length + folded)) {
+                return element;
+            }
+        }
+                      
+        index %= elements.length;
+        return elements[index];              
+    };
+    
     fluid.geom = fluid.geom || {};
     
     // These distance algorithms have been taken from
@@ -545,9 +555,10 @@
      * @param {fluid.direction} direction  The direction of motion
      * @param {Array of Rectangle holders} targets An array of objects "cache elements" 
      * for which the member <code>rect</code> is the holder of the rectangle to be tested.
+     * @param disableWrap which is used to enable or disable wrapping of elements
      * @return The cache element which is the most appropriate for the requested motion.
      */
-    fluid.geom.projectFrom = function (baserect, direction, targets, forSelection) {
+    fluid.geom.projectFrom = function (baserect, direction, targets, forSelection, disableWrap) {
         var axis = fluid.directionAxis(direction);
         var frontSide = fluid.rectSides[direction];
         var backSide = fluid.rectSides[axis * 15 + 5 - direction];
@@ -597,8 +608,13 @@
             }
             //fluid.log("Element " + i + " " + dumpelem(elem) + " mindist " + collect.mindist);
         }
-        var wrap = !collect.minelem || backcollect.mindist < collect.mindist;
-        var mincollect = wrap? backcollect: collect;
+        var wrap = !collect.minelem || backcollect.mindist < collect.mindist ;
+        
+        // disable wrap
+        wrap = wrap && !disableWrap;       
+                
+        var mincollect = wrap? backcollect: collect;        
+        
         var togo = {
             wrapped: wrap,
             cacheelem: mincollect.minelem
Index: components/reorderer/js/ModuleLayout.js
===================================================================
--- components/reorderer/js/ModuleLayout.js	(revision 10166)
+++ components/reorderer/js/ModuleLayout.js	(working copy)
@@ -1,6 +1,7 @@
 /*
 Copyright 2008-2009 University of Cambridge
 Copyright 2008-2009 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -169,7 +170,7 @@
         that.getRelativePosition  = 
            fluid.reorderer.relativeInfoGetter(options.orientation, 
                  fluid.reorderer.WRAP_LOCKED_STRATEGY, fluid.reorderer.GEOMETRIC_STRATEGY, 
-                 dropManager, dom);
+                 dropManager, dom, options.disableWrap);
                  
         that.getGeometricInfo = function () {
         	var extents = [];
Index: components/reorderer/js/Reorderer.js
===================================================================
--- components/reorderer/js/Reorderer.js	(revision 10166)
+++ components/reorderer/js/Reorderer.js	(working copy)
@@ -1,6 +1,7 @@
 /*
 Copyright 2007-2009 University of Toronto
 Copyright 2007-2010 University of Cambridge
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -121,9 +122,9 @@
         }
         var thatReorderer = fluid.initView("fluid.reorderer", container, options);
         options = thatReorderer.options;
-        
-        var dropManager = fluid.dropManager();
-        
+                
+        var dropManager = fluid.dropManager();   
+                
         thatReorderer.layoutHandler = fluid.initSubcomponent(thatReorderer,
             "layoutHandler", [thatReorderer.container, options, dropManager, thatReorderer.dom]);
         
@@ -176,7 +177,7 @@
                 var isMovement = keyset.modifier(evt);
                 
                 var dirnum = fluid.keycodeDirection[keydir];
-                var relativeItem = thatReorderer.layoutHandler.getRelativePosition(item, dirnum, !isMovement);
+                var relativeItem = thatReorderer.layoutHandler.getRelativePosition(item, dirnum, !isMovement);  
                 if (!relativeItem) {
                     continue;
                 }
@@ -569,11 +570,11 @@
     fluid.reorderer.WRAP_LOCKED_STRATEGY       = "lockedWrapFrom";
     fluid.reorderer.NO_STRATEGY = null;
     
-    fluid.reorderer.relativeInfoGetter = function (orientation, coStrategy, contraStrategy, dropManager, dom) {
+    fluid.reorderer.relativeInfoGetter = function (orientation, coStrategy, contraStrategy, dropManager, dom, disableWrap) {
         return function (item, direction, forSelection) {
             var dirorient = fluid.directionOrientation(direction);
             var strategy = dirorient === orientation? coStrategy: contraStrategy;
-            return strategy !== null? dropManager[strategy](item, direction, forSelection) : null;
+            return strategy !== null? dropManager[strategy](item, direction, forSelection, disableWrap) : null;
         };
     };
     
@@ -613,7 +614,11 @@
             keysets: "replace",
             "selectors.selectables": "selectors.movables",
             "selectors.dropTargets": "selectors.movables"
-        }
+        },
+        
+        // The user option to enable or disable wrapping of elements within the container
+        disableWrap: false        
+        
     });
 
 
@@ -649,7 +654,7 @@
 
         that.getRelativePosition = 
           fluid.reorderer.relativeInfoGetter(options.orientation, 
-                fluid.reorderer.LOGICAL_STRATEGY, null, dropManager, dom);
+                fluid.reorderer.LOGICAL_STRATEGY, null, dropManager, dom, options.disableWrap);
         
         that.getGeometricInfo = geometricInfoGetter(options.orientation, options.sentinelize, dom);
         
@@ -675,8 +680,8 @@
 
         that.getRelativePosition = 
            fluid.reorderer.relativeInfoGetter(options.orientation, 
-                 fluid.reorderer.LOGICAL_STRATEGY, fluid.reorderer.SHUFFLE_GEOMETRIC_STRATEGY, 
-                 dropManager, dom);
+                 options.disableWrap ? fluid.reorderer.SHUFFLE_GEOMETRIC_STRATEGY : fluid.reorderer.LOGICAL_STRATEGY, fluid.reorderer.SHUFFLE_GEOMETRIC_STRATEGY, 
+                 dropManager, dom, options.disableWrap);
         
         that.getGeometricInfo = geometricInfoGetter(options.orientation, options.sentinelize, dom);
         
Index: demos/reorderer/gridReorderer/html/gridReorderer.html
===================================================================
--- demos/reorderer/gridReorderer/html/gridReorderer.html	(revision 10166)
+++ demos/reorderer/gridReorderer/html/gridReorderer.html	(working copy)
@@ -48,6 +48,7 @@
             <p>Dogs</p>
             <p>CATT</p>
             <p>Happy</p>
+           
         </div>
         <script type="text/javascript">
             demo.initGridReorderer();
Index: demos/reorderer/gridReorderer/js/gridReorderer.js
===================================================================
--- demos/reorderer/gridReorderer/js/gridReorderer.js	(revision 10166)
+++ demos/reorderer/gridReorderer/js/gridReorderer.js	(working copy)
@@ -1,5 +1,6 @@
 /*
 Copyright 2008-2009 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -19,6 +20,7 @@
     return fluid.reorderGrid('.myGrid', {
         selectors: {
             movables: 'p'
-        }
+        },
+        disableWrap: true
     });
 };
Index: demos/reorderer/imageReorderer/js/imageReorderer.js
===================================================================
--- demos/reorderer/imageReorderer/js/imageReorderer.js	(revision 10166)
+++ demos/reorderer/imageReorderer/js/imageReorderer.js	(working copy)
@@ -2,6 +2,7 @@
 Copyright 2007-2009 University of Cambridge
 Copyright 2007-2009 University of Toronto
 Copyright 2007-2009 University of California, Berkeley
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -22,7 +23,8 @@
         var reorderer = fluid.reorderImages(".flc-imageReorderer", {
             selectors: {
                 movables: ".flc-imageReorderer-item"
-            }
+            },
+            disableWrap: true
         });  
     };
 })(jQuery, fluid);
\ No newline at end of file
Index: demos/reorderer/layoutReorderer/html/layoutReorderer.html
===================================================================
--- demos/reorderer/layoutReorderer/html/layoutReorderer.html	(revision 10166)
+++ demos/reorderer/layoutReorderer/html/layoutReorderer.html	(working copy)
@@ -52,9 +52,10 @@
                 <div class="myColumn fl-container-flex30 fl-force-left">
                     <h2>Column A</h2>
                     <div class="locked">Content Portal A1 (Locked)</div>
-                    <div>Content Portal A2</div>
+                    <div class="locked">Content Portal A2 (Locked)</div>
                     <div>Content Portal A3</div>
-                    <div>Content Portal A4</div>
+                    <div >Content Portal A4 </div>
+                    <div>Content Portal A5</div>
                 </div>
                 <div class="myColumn fl-container-flex30 fl-force-left">
                     <h2>Column B</h2>
Index: demos/reorderer/layoutReorderer/js/layoutReorderer.js
===================================================================
--- demos/reorderer/layoutReorderer/js/layoutReorderer.js	(revision 10166)
+++ demos/reorderer/layoutReorderer/js/layoutReorderer.js	(working copy)
@@ -1,5 +1,6 @@
 /*
 Copyright 2008-2009 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -22,7 +23,8 @@
                 modules: "> div > div",
                 lockedModules: ".locked",
                 dropWarning: ".flc-reorderer-dropWarning"
-            }
+            },
+            disableWrap: true
         });
     };
 })(jQuery, fluid);
Index: demos/reorderer/listReorderer/html/listReorderer.html
===================================================================
--- demos/reorderer/listReorderer/html/listReorderer.html	(revision 10166)
+++ demos/reorderer/listReorderer/html/listReorderer.html	(working copy)
@@ -68,7 +68,7 @@
             <li class="movable">
                 Develop a conference daily schedule of events
             </li>
-        </ol>
+        </ol>        
         
         <script type="text/javascript">
             demo.initListReorderer();
Index: demos/reorderer/listReorderer/js/listReorderer.js
===================================================================
--- demos/reorderer/listReorderer/js/listReorderer.js	(revision 10166)
+++ demos/reorderer/listReorderer/js/listReorderer.js	(working copy)
@@ -2,6 +2,7 @@
 Copyright 2007-2009 University of Cambridge
 Copyright 2007-2009 University of Toronto
 Copyright 2007-2009 University of California, Berkeley
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -22,7 +23,8 @@
         return fluid.reorderList(".todo-list", {
             selectors: {
                 movables: ".movable"
-            }
+            },
+            disableWrap: true
         });
     };
 })(jQuery, fluid);
\ No newline at end of file
Index: tests/component-tests/reorderer/html/GeometricManager-test.html
===================================================================
--- tests/component-tests/reorderer/html/GeometricManager-test.html	(revision 10166)
+++ tests/component-tests/reorderer/html/GeometricManager-test.html	(working copy)
@@ -20,6 +20,7 @@
     <script type="text/javascript" src="../../../test-core/jqUnit/js/jqUnit.js"></script>
 
     <!--  These are tests that have been written using this page as data -->
+    <script type="text/javascript" src="../js/ReordererTestUtils.js"></script>
     <script type="text/javascript" src="../js/GeometricManagerTests.js"></script>
 
   </head>
Index: tests/component-tests/reorderer/js/GeometricManagerTests.js
===================================================================
--- tests/component-tests/reorderer/js/GeometricManagerTests.js	(revision 10166)
+++ tests/component-tests/reorderer/js/GeometricManagerTests.js	(working copy)
@@ -1,5 +1,6 @@
 /*
 Copyright 2008-2009 University of Cambridge
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -18,7 +19,7 @@
     $(document).ready(function () {
     	     
         var GeometricManagerTests = new jqUnit.TestCase("GeometricManagerTests");
-    	
+        
         function assertOrder(message, parentId, required) {
             var all = $("#" + parentId + " div");
             var str = "";
@@ -59,9 +60,8 @@
                 assertOrder(name, "permuteTest", expected1);
                 assertOrder(name, "permuteTest2", expected2);
             });            
-        }
-        
-
+        }        
+       
         // Original order:                                                   "0123A4567B8"
         selfPermuteTest("REPLACE right rend",  2, 8, fluid.position.REPLACE, "0134A5678B2");
         selfPermuteTest("REPLACE right",       2, 6, fluid.position.REPLACE, "0134A5627B8");
@@ -135,40 +135,14 @@
           
         });
         
-      GeometricManagerTests.test("projectFrom", function() {
-          // column 1, 3x3 squares spaced by 1, middle skew 1 to the right
-          var rects = [
-              {left: 1, top: 1, right: 4, bottom: 4},
-              {left: 2, top: 5, right: 5, bottom: 8},
-              {left: 1, top: 9, right: 4, bottom: 12},
-          // column 2, same dimensions but offset down by 1
-              {left: 6, top: 2, right: 9, bottom: 5},
-              {left: 6, top: 6, right: 9, bottom: 9}];
-          
-          var elems = fluid.transform(rects, function(rect, i) {
-             return {rect: rect, index: i}
-          });
-          
-          function assertProject(name, fromIndex, direction, toIndex, wrapped) {
-              var proj = fluid.geom.projectFrom(rects[fromIndex], fluid.direction[direction], elems);
-              jqUnit.assertEquals(name + " index", toIndex, proj.cacheelem.index);
-              jqUnit.assertEquals(name + " wrapped", wrapped, proj.wrapped);
-          }
+      GeometricManagerTests.test("projectFrom", function() {          
           expect(24);  
-          assertProject("Right0", 0, "RIGHT", 3, false);
-          assertProject("Left3",  3, "LEFT",  0, false);
-          assertProject("Right3", 3, "RIGHT", 0, true);
-          assertProject("Left0",  0, "LEFT",  3, true);
-          assertProject("Down0",  0, "DOWN",  1, false);
-          assertProject("Up1",    1, "UP",    0, false);
-          
-          assertProject("Up0",    0, "UP",    2, true);
-          assertProject("Down2",  2, "DOWN",  0, true);
-          assertProject("Right2", 2, "RIGHT", 4, false);
-          assertProject("Left4",  4, "LEFT",  1, false);
-          assertProject("Left1",  1, "LEFT",  4, true);
-          assertProject("Right4", 4, "RIGHT", 1, true);
-          
+          fluid.testUtils.reorderer.stepProjectFrom(false);
+      });
+            
+      GeometricManagerTests.test("projectFrom with disabled wrap", function() {          
+          expect(24);  
+          fluid.testUtils.reorderer.stepProjectFrom(true);
       });
     });
 })(jQuery);
Index: tests/component-tests/reorderer/js/LayoutReordererTests.js
===================================================================
--- tests/component-tests/reorderer/js/LayoutReordererTests.js	(revision 10166)
+++ tests/component-tests/reorderer/js/LayoutReordererTests.js	(working copy)
@@ -1,6 +1,7 @@
 /*
 Copyright 2008-2009 University of Cambridge
 Copyright 2008-2009 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -23,8 +24,8 @@
         
         layoutReordererTests.test("Default selectors", function () {
             var testReorderer = fluid.reorderLayout("#default-selector-test");
-            var item1 = jQuery("#portlet-1");
-            var item2 = jQuery("#portlet-2").focus();
+            var item1 = $("#portlet-1");
+            var item2 = $("#portlet-2").focus();
             
             // Sniff test the reorderer that was created - keyboard selection
             jqUnit.assertTrue("focus on item2", item2.hasClass("fl-reorderer-movable-selected"));
@@ -106,27 +107,25 @@
             reorderer.handleKeyUp(fluid.testUtils.keyEvent("CTRL", portlet8));
             jqUnit.notVisible("After ctrl is released, drop warning should not be visible", "#drop-warning"); 
     
-        });
-    
-    
+        });   
     
-        function expectOrder(message, order) {
-           var items = fluid.transform(jQuery(".portlet"), fluid.getId);
-           var expected = fluid.transform(order, function(item) {return fluid.testUtils.moduleLayout.portletIds[item];});
-           jqUnit.assertDeepEq(message, expected, items);
-        }
-      
         var tests = new jqUnit.TestCase("Reorder Layout Tests");
-    
-        tests.test("reorderLayout API", function () {
-          
-            var options = {
-                selectors: {
-                    columns: "[id^='c']",
-                    modules: ".portlet"
-                }
+        
+        var assembleOptions = function (isDisableWrap,isLocked) {
+            var obj = {
+            		selectors: {
+            			columns: "[id^='c']",
+			            modules: ".portlet",
+			            lockedModules: isLocked
+            		},
+            		disableWrap: isDisableWrap
             };
             
+            return obj;
+        };       
+        
+        tests.test("reorderLayout API", function () {
+            var options = assembleOptions();
             var lastLayoutModel = null;
             
             var layoutReorderer = fluid.reorderLayout(".reorderer_container", options);
@@ -140,8 +139,7 @@
             var item2 = fluid.jById(fluid.testUtils.moduleLayout.portletIds[2]).focus();
             var item3 = fluid.jById(fluid.testUtils.moduleLayout.portletIds[3]);
             
-            // Sniff test the reorderer that was created - keyboard selection and movement
-    
+            // Sniff test the reorderer that was created - keyboard selection and movement    
             jqUnit.assertTrue("focus on item2", item2.hasClass("fl-reorderer-movable-selected"));
             jqUnit.assertTrue("focus on item2 - item3 should be default", item3.hasClass("fl-reorderer-movable-default"));
             jqUnit.assertEquals("No move callback", null, lastLayoutModel);
@@ -155,22 +153,22 @@
             // Test FLUID-3121 - the afterMoveCallback should successfully execute and obtain the model
             jqUnit.assertNotEquals("Move callback with model", null, lastLayoutModel);
     
-            expectOrder("after ctrl-down, expect order 1, 2, 4, 3, 5, 6, 7, 8, 9", 
+            fluid.testUtils.reorderer.expectOrder("after ctrl-down, expect order 1, 2, 4, 3, 5, 6, 7, 8, 9", 
                 [1, 2, 4, 3, 5, 6, 7, 8, 9]);
         });
     
-        tests.test("reorderLayout with optional styles", function () {
+        tests.test("reorderLayout with optional styles", function () {        	
             var options = {
-                selectors: {
-                    columns: "[id^='c']",
-                    modules: ".portlet"            
-                },
-                styles: {
-                    defaultStyle: "myDefault",
-                    selected: "mySelected"
-                }
-            };
-    
+                    selectors: {
+                        columns: "[id^='c']",
+                        modules: ".portlet" 
+                    },
+                    styles: {
+                        defaultStyle: "myDefault",
+                        selected: "mySelected"
+                    }
+                };
+                
             var layoutReorderer = fluid.reorderLayout(".reorderer_container", options);
             
             jqUnit.assertEquals("default class is myDefault", "myDefault", layoutReorderer.options.styles.defaultStyle);
@@ -181,14 +179,7 @@
         });
         
         tests.test("reorderLayout with locked portlets", function () {
-            var options = {
-                selectors: {
-                    columns: "[id^='c']",
-                    modules: ".portlet",
-                    lockedModules: ".locked"
-                }
-            };
-
+        	var options = assembleOptions(false,".locked");
             var layoutReorderer = fluid.reorderLayout(".reorderer_container", options);
             var item2 = fluid.jById(fluid.testUtils.moduleLayout.portletIds[2]).focus();
             var item3 = fluid.jById(fluid.testUtils.moduleLayout.portletIds[3]);
@@ -197,13 +188,13 @@
             jqUnit.assertTrue("focus on item2", item2.hasClass("fl-reorderer-movable-selected"));
             key(layoutReorderer, fluid.testUtils.ctrlKeyEvent("DOWN"), item3);
 
-            expectOrder("after ctrl-down, expect order 1, 2, 3, 4", [1, 2, 3, 4, 5, 6, 7, 8, 9]);
+            fluid.testUtils.reorderer.expectOrder("after ctrl-down, expect order 1, 2, 3, 4", [1, 2, 3, 4, 5, 6, 7, 8, 9]);
 
             item3.focus();
             jqUnit.assertTrue("focus on item3", item3.hasClass("fl-reorderer-movable-selected"));
             key(layoutReorderer, fluid.testUtils.ctrlKeyEvent("DOWN"), item3);
 
-            expectOrder("after ctrl-down, expect order 1, 2, 4, 3", [1, 2, 4, 3, 5, 6, 7, 8, 9]);
+            fluid.testUtils.reorderer.expectOrder("after ctrl-down, expect order 1, 2, 4, 3", [1, 2, 4, 3, 5, 6, 7, 8, 9]);
 
             $("#portlet-reorderer-root tr").append($("<td id=\"c5\"/>"));
             layoutReorderer.refresh();
@@ -217,8 +208,41 @@
             jqUnit.assertTrue("Moved to new column", 
                 fluid.dom.isContainer($("#c5")[0], item3[0]));
                    
+        });        
+       
+        tests.test("reorderLayout, option set disabled wrap, user action ctrl+up", function () {      
+            var expectedOrderArrays = [[1, 2, 3, 4, 5, 6, 7, 8, 9]];	
+            var options = assembleOptions(true);
+            fluid.testUtils.reorderer.stepLayoutReorderer(1, expectedOrderArrays, "UP", options);	                        
+        });        
+     
+        tests.test("reorderLayout, option set disabled wrap, user action ctrl+down", function () {
+            var expectedOrderArrays = [[1, 2, 3, 4, 5, 6, 7, 8, 9]];
+            var options = assembleOptions(true);
+            fluid.testUtils.reorderer.stepLayoutReorderer(9, expectedOrderArrays, "DOWN", options);                          
         });
-    
+        
+        tests.test("reorderLayout with locked portlets, option set disabled wrap, user action ctrl+up", function () {
+            var expectedOrderArrays = [[1, 2, 4, 3, 5, 6, 7, 8, 9],[1, 2, 4, 3, 5, 6, 7, 8, 9]];      
+            var options = assembleOptions(true, ".locked");      
+            fluid.testUtils.reorderer.stepLayoutReorderer(4, expectedOrderArrays, "UP", options); 
+            
+            jqUnit.assertValue("gives warning message when trying to move item4 up ", $(".flc-reorderer-dropWarning"));                   
+        });       
+       
+        tests.test("reorderLayout with locked portlets, option set disabled wrap, user action ctrl+right", function () {
+            var expectedOrderArrays = [[1, 2, 4, 5, 6, 3, 7, 8, 9], [1, 2, 4, 5, 6, 7, 8, 3, 9], 
+                                        [1, 2, 4, 5, 6, 7, 8, 9, 3], [1, 2, 4, 5, 6, 7, 8, 9, 3]];
+            var options = assembleOptions(true, ".locked");                                  
+	        fluid.testUtils.reorderer.stepLayoutReorderer(3, expectedOrderArrays, "RIGHT", options);
+        });        
+        
+        tests.test("reorderLayout with locked portlets, option set disabled wrap, user action ctrl+left", function () {
+            var expectedOrderArrays = [[1, 2, 3, 4, 5, 6, 9, 7, 8], [1, 2, 3, 9, 4, 5, 6, 7, 8], 
+                                        [1, 2, 3, 9, 4, 5, 6, 7, 8]];
+            var options = assembleOptions(true, ".locked");                                  
+            fluid.testUtils.reorderer.stepLayoutReorderer(9, expectedOrderArrays, "LEFT", options);                        
+        });    
     
     });
 })(jQuery);
Index: tests/component-tests/reorderer/js/ReorderGridTests.js
===================================================================
--- tests/component-tests/reorderer/js/ReorderGridTests.js	(revision 10166)
+++ tests/component-tests/reorderer/js/ReorderGridTests.js	(working copy)
@@ -1,6 +1,7 @@
 /*
 Copyright 2008-2009 University of Cambridge
 Copyright 2008-2009 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -15,13 +16,19 @@
         var tests = new jqUnit.TestCase("Reorder Grid Tests");
         
         var k = fluid.testUtils.reorderer.bindReorderer(orderableIds);
-    
-        tests.test("reorderGrid API", function() {
-            var options = {
-                selectors: {
-                    movables: ".float"
-                }
-            };
+        
+        var assembleOptions = function (isDisableWrap) {
+        		var obj = {
+        				selectors: {
+			            	movables: ".float"
+		            	},
+		            	disableWrap: isDisableWrap
+        	};            
+            return obj;
+        };    
+        
+        tests.test("reorderGrid API", function() {            
+        	var options = assembleOptions(false);
             var containerSelector = "[id='" + lightboxRootId + "']";
             var gridReorderer = fluid.reorderGrid(containerSelector, options);
             var item2 = fluid.jById(orderableIds[1]).focus();
@@ -43,10 +50,11 @@
             k.compositeKey(gridReorderer, fluid.testUtils.ctrlKeyEvent("DOWN"), 4);
             
             fluid.testUtils.reorderer.assertItemsInOrder("after ctrl-down", [0, 1, 2, 3, 5, 6, 7, 4, 8, 9, 10, 11, 12, 13], 
-                jQuery("img", jQuery(containerSelector)), "fluid.img.");
+                $("img", $(containerSelector)), "fluid.img.");
         
             });
     
+        
         tests.test("reorderGrid with optional styles", function() {
             var options = {
                 selectors: {
@@ -66,6 +74,64 @@
             jqUnit.assertEquals("dragging class is fl-reorderer-movable-dragging", "fl-reorderer-movable-dragging", gridReorderer.options.styles.dragging);
             jqUnit.assertEquals("mouseDrag class is fl-reorderer-movable-dragging", "fl-reorderer-movable-dragging", gridReorderer.options.styles.mouseDrag);
             
-        });    
+        });  
+        
+        tests.test("reorderGrid, option set disabled wrap, user action ctrl+down", function() {
+        	var expectedOrderArrays = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 9, 13],
+        	                          [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 9, 13]];        	
+        	var options = assembleOptions(true);
+        	fluid.testUtils.reorderer.stepGridReorderer(9, expectedOrderArrays, "DOWN", options);        
+        });
+        
+        tests.test("reorderGrid, option set enabled wrap, user action ctrl+down", function() {        	
+        	var expectedOrderArrays = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 9, 13],
+        	                          [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13]];
+        	var options = assembleOptions(false);
+        	fluid.testUtils.reorderer.stepGridReorderer(9, expectedOrderArrays, "DOWN", options);
+        });
+      
+        tests.test("reorderGrid, option set disabled wrap, user action ctrl+up", function() {        	
+        	var expectedOrderArrays = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
+        	                          [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]];
+        	var options = assembleOptions(true);
+        	fluid.testUtils.reorderer.stepGridReorderer(0, expectedOrderArrays, "UP", options);
+        });
+        
+        tests.test("reorderGrid, option set enabled wrap, user action ctrl+up", function() {        	
+        	var expectedOrderArrays = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 13],
+        	                          [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13],
+        	                          [1, 2, 3, 4, 5, 6, 0, 7, 8, 9, 10, 11, 12, 13]];
+        	var options = assembleOptions(false);
+        	fluid.testUtils.reorderer.stepGridReorderer(0, expectedOrderArrays, "UP", options);
+        });
+           
+        tests.test("reorderGrid, option set disabled wrap, user action ctrl+right", function() {        	
+        	var expectedOrderArrays = [[0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
+        	                          [0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]];
+        	var options = assembleOptions(true);
+        	fluid.testUtils.reorderer.stepGridReorderer(1, expectedOrderArrays, "RIGHT", options);
+        });
+        
+        tests.test("reorderGrid, option set enabled wrap, user action ctrl+right", function() {        	
+        	var expectedOrderArrays = [[0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
+        	                          [0, 2, 3, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]];
+        	var options = assembleOptions(false);
+        	fluid.testUtils.reorderer.stepGridReorderer(1, expectedOrderArrays, "RIGHT", options);
+        });        
+        
+        tests.test("reorderGrid, option set disabled wrap, user action ctrl+left", function() {        	
+        	var expectedOrderArrays = [[1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
+        	                          [1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]];
+        	var options = assembleOptions(true);
+        	fluid.testUtils.reorderer.stepGridReorderer(1, expectedOrderArrays, "LEFT", options);
+       });        
+      
+        tests.test("reorderGrid, option set enabled wrap, user action ctrl+left", function() {        	
+        	var expectedOrderArrays = [[1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
+        	                          [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1]];
+        	var options = assembleOptions(false);
+        	fluid.testUtils.reorderer.stepGridReorderer(1, expectedOrderArrays, "LEFT", options);
+        });
+        
     });
 })(jQuery);
Index: tests/component-tests/reorderer/js/ReorderListTests.js
===================================================================
--- tests/component-tests/reorderer/js/ReorderListTests.js	(revision 10166)
+++ tests/component-tests/reorderer/js/ReorderListTests.js	(working copy)
@@ -1,6 +1,7 @@
 /*
 Copyright 2008-2009 University of Cambridge
 Copyright 2008-2009 University of Toronto
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -16,23 +17,29 @@
     
         function assertItemsInOrder(message, expectOrder) {
             return fluid.testUtils.reorderer.assertItemsInOrder(message, expectOrder, 
-               jQuery("li", jQuery("#list1")), "list1item");
-        }
+               $("li", $("#list1")), "list1item");
+        }        
         
         var k = fluid.testUtils.reorderer.bindReorderer(itemIds);
         
+        var assembleOptions = function (isDisableWrap) {
+        	var obj = {
+        			selectors: {
+        				movables: "li"
+        			},
+        			listeners: {
+        				afterMove: callbackConfirmer
+        			},
+        			disableWrap: isDisableWrap
+        	};            
+            return obj;
+        };
+        
         tests.test("reorderList API", function() {
-            var options = {
-                selectors: {
-                    movables: "li"
-                },
-                listeners: {
-                    afterMove: callbackConfirmer
-                }
-            };
+        	var options = assembleOptions(false); 
             var listReorderer = fluid.reorderList("#list1", options);
-            var item2 = jQuery("#list1item2").focus();
-            var item3 = jQuery("#list1item3");
+            var item2 = $("#list1item2").focus();
+            var item3 = $("#list1item3");
             
             // Sniff test the reorderer that was created - keyboard selection and movement
     
@@ -76,17 +83,16 @@
             
         });    
     
-       function assertItemsInOrder2(message, expectOrder) {
+        function assertItemsInOrder2(message, expectOrder) {
             return fluid.testUtils.reorderer.assertItemsInOrder(message, expectOrder, 
-               jQuery("li", jQuery("#list2")), "list2item");
-        }
-    
+               $("li", $("#list2")), "list2item");
+        }    
     
         var k2 = fluid.testUtils.reorderer.bindReorderer(itemIds2);
     
         tests.test("reorderList with multi selectors", function() {
             var options = {
-                selectors: {
+            	selectors: {
                     movables: ".orderable",
                     selectables: "li", 
                     dropTargets: "li"
@@ -98,10 +104,10 @@
     
             var listReorderer = fluid.reorderList("#list2", options);
             
-            var item1 = jQuery("#list2item1").focus();
-            var item2 = jQuery("#list2item2");
-            var item3 = jQuery("#list2item3");
-            var item4 = jQuery("#list2item4");
+            var item1 = $("#list2item1").focus();
+            var item2 = $("#list2item2");
+            var item3 = $("#list2item3");
+            var item4 = $("#list2item4");
     
             jqUnit.assertTrue("focus on item1", item1.hasClass("fl-reorderer-movable-selected"));
 
@@ -129,5 +135,18 @@
             jqUnit.assertTrue("after ctrl-down on movable, order should change", afterMoveCallbackWasCalled);
     
         });
+        
+        tests.test("reorderList, option set disabled wrap, user action ctrl+down", function() {
+        	var expectedOrderArrays = [[1, 2, 3, 5, 4],[1, 2, 3, 5, 4]];
+        	var options = assembleOptions(true);
+        	fluid.testUtils.reorderer.stepListReorderer(3, expectedOrderArrays, "DOWN", options);         	
+        });
+
+        tests.test("reorderList, option set disabled wrap, user action ctrl+up", function() {
+        	var expectedOrderArrays = [[2, 1, 3, 4, 5],[2, 1, 3, 4, 5]];
+        	var options = assembleOptions(true);
+        	fluid.testUtils.reorderer.stepListReorderer(1, expectedOrderArrays, "UP", options);        	
+        });        
+        
     });
 })(jQuery);
Index: tests/component-tests/reorderer/js/ReordererTestUtils.js
===================================================================
--- tests/component-tests/reorderer/js/ReordererTestUtils.js	(revision 10166)
+++ tests/component-tests/reorderer/js/ReordererTestUtils.js	(working copy)
@@ -1,5 +1,6 @@
 /*
 Copyright 2008-2009 University of Cambridge
+Copyright 2010-2011 OCAD University
 
 Licensed under the Educational Community License (ECL), Version 2.0 or the New
 BSD license. You may not use this file except in compliance with one these
@@ -103,6 +104,98 @@
                    fluid.byId(ids[targetIndex]));
             }
         };
+    };   
+    
+    // GeometricManagerTest
+    fluid.testUtils.reorderer.stepProjectFrom = function (disabledWrap) {
+    	// column 1, 3x3 squares spaced by 1, middle skew 1 to the right
+        var rects = [
+            {left: 1, top: 1, right: 4, bottom: 4},
+            {left: 2, top: 5, right: 5, bottom: 8},
+            {left: 1, top: 9, right: 4, bottom: 12},
+        // column 2, same dimensions but offset down by 1
+            {left: 6, top: 2, right: 9, bottom: 5},
+            {left: 6, top: 6, right: 9, bottom: 9}];
+        
+        var elems = fluid.transform(rects, function(rect, i) {
+           return {rect: rect, index: i}
+        });
+                 
+        function assertProject(name, fromIndex, direction, toIndex, couldWrap) {
+            var proj = fluid.geom.projectFrom(rects[fromIndex], fluid.direction[direction], elems, false, disabledWrap);
+            if(couldWrap && disabledWrap) {
+                jqUnit.assertUndefined(name + " index " + toIndex, proj.cacheelem);
+                jqUnit.assertFalse("no wrapping from index:" + fromIndex + " to index:" + toIndex + " wrapped set to " + couldWrap, proj.wrapped);
+            } else {
+            	jqUnit.assertEquals(name + " index", toIndex, proj.cacheelem.index);
+                jqUnit.assertEquals(name + " wrapped", couldWrap, proj.wrapped);
+            }
+        }
+        
+        assertProject("Right0", 0, "RIGHT", 3, false, disabledWrap);
+        assertProject("Left3",  3, "LEFT",  0, false, disabledWrap);
+        assertProject("Right3", 3, "RIGHT", 0, true, disabledWrap);
+        assertProject("Left0",  0, "LEFT",  3, true, disabledWrap);
+        assertProject("Down0",  0, "DOWN",  1, false, disabledWrap);
+        assertProject("Up1",    1, "UP",    0, false, disabledWrap);
+        
+        assertProject("Up0",    0, "UP",    2, true, disabledWrap);
+        assertProject("Down2",  2, "DOWN",  0, true, disabledWrap);
+        assertProject("Right2", 2, "RIGHT", 4, false, disabledWrap);
+        assertProject("Left4",  4, "LEFT",  1, false, disabledWrap);
+        assertProject("Left1",  1, "LEFT",  4, true, disabledWrap);
+        assertProject("Right4", 4, "RIGHT", 1, true, disabledWrap);            
+             
     };
+    
+    // ReorderGridTests
+    fluid.testUtils.reorderer.stepGridReorderer = function (index, expectedOrderArrays, direction, options) {  
+    	var containerSelector = "[id='" + lightboxRootId + "']";
+    	var gridReorderer = fluid.reorderGrid(containerSelector, options);
+    	var numItemFocused = 1;
+    	var k = fluid.testUtils.reorderer.bindReorderer(orderableIds);
+    	var item = fluid.jById(orderableIds[index]).focus();
+        for (var i = 0; i < expectedOrderArrays.length; i++) {                
+            jqUnit.assertTrue("focus on item" + index, item.hasClass("fl-reorderer-movable-selected"));                
+            k.compositeKey(gridReorderer, fluid.testUtils.ctrlKeyEvent(direction), index);                
+            fluid.testUtils.reorderer.assertItemsInOrder("after ctrl-" + direction.toLowerCase() + " the order is " + expectedOrderArrays[i],expectedOrderArrays[i], 
+                $("img", $(containerSelector)), "fluid.img.");       
+            jqUnit.assertEquals("there should one item selected ", numItemFocused, $('.fl-reorderer-movable-selected').length);                 
+        }
+    };
+    
+    // ReorderListTests
+    fluid.testUtils.reorderer.stepListReorderer = function (index, expectedOrderArrays, direction, options) {      	
+    	var listReorderer = fluid.reorderList("#list1", options);
+    	var k = fluid.testUtils.reorderer.bindReorderer(itemIds);
+    	var itemNum = index+1;
+        var item = $("#list1item" + itemNum).focus();
+    	for (var i = 0; i < expectedOrderArrays.length; i++) {                
+    		jqUnit.assertTrue("focus on item" + itemNum + " of list1", item.hasClass("fl-reorderer-movable-selected"));                
+            k.compositeKey(listReorderer, fluid.testUtils.ctrlKeyEvent(direction), index);                    
+            fluid.testUtils.reorderer.assertItemsInOrder("after ctrl-" + direction.toLowerCase() + ", order should be " + expectedOrderArrays[i], expectedOrderArrays[i], 
+                    $("li", $("#list1")), "list1item");
+        }        	
+    };
+    
+    // LayoutReordererTests expectOrder
+    fluid.testUtils.reorderer.expectOrder = function (message, order) {
+        var items = fluid.transform($(".portlet"), fluid.getId);
+        var expected = fluid.transform(order, function(item) {return fluid.testUtils.moduleLayout.portletIds[item];});
+        jqUnit.assertDeepEq(message, expected, items);
+     }
+          
+    // LayoutReordererTests
+    fluid.testUtils.reorderer.stepLayoutReorderer = function (index, expectedOrderArrays, direction, options) {     	
+    	var layoutReorderer = fluid.reorderLayout(".reorderer_container", options);
+    	var islocked = options.selectors.lockedModules;
+    	var key = fluid.testUtils.reorderer.compositeKey;
+    	var item = fluid.jById(fluid.testUtils.moduleLayout.portletIds[index]).focus();
+    	for (var i = 0; i < expectedOrderArrays.length; i++) {
+            jqUnit.assertTrue("focus on item" + index, item.hasClass("fl-reorderer-movable-selected"));
+            key(layoutReorderer, fluid.testUtils.ctrlKeyEvent(direction), item);
+            fluid.testUtils.reorderer.expectOrder("after ctrl-" + direction.toLowerCase() + ", expect order is " + expectedOrderArrays[i], expectedOrderArrays[i]);            
+        }
+    };   
   
 })(jQuery, fluid_1_2);
\ No newline at end of file

