How to group list of start times by a category? I have a list people and when they started occupied various rooms in the building. Like so:

IF OBJECT_ID('tempdb..#RoomAssignments') IS NOT NULL
  DROP TABLE #RoomAssignments;
CREATE TABLE #RoomAssignments (
  PersonID smallint,
  FloorNum tinyint,
  Room varchar(5),
  EnterTime datetime
);
INSERT INTO #RoomAssignments (PersonID, FloorNum, Room, EnterTime) VALUES
  (24601, 23, 'S', CONVERT(datetime,'2015-02-27 07:42:03.287', 121)),
  (24601, 16, 'F', CONVERT(datetime,'2015-02-27 11:29:59.497', 121)),
  (24601, 12, 'B', CONVERT(datetime,'2015-03-03 14:38:03.243', 121)),
  (24601, 41, 'E', CONVERT(datetime,'2015-03-03 21:03:05.007', 121)),
  (24601, 12, 'B', CONVERT(datetime,'2015-03-05 10:17:36.773', 121)),
  (24601, 15, 'S', CONVERT(datetime,'2015-03-05 12:19:40.573', 121)),
  (24601, 15, 'P', CONVERT(datetime,'2015-03-06 21:51:20.430', 121)),
  (24601, 15, 'L', CONVERT(datetime,'2015-03-09 10:25:00.127', 121)),
  (24601, 16, 'A', CONVERT(datetime,'2015-03-10 17:19:30.550', 121))
;
SELECT * FROM #RoomAssignments
ORDER BY Personid, EnterTime;
/********* #RoomAssignments: ********************
Person FloorNum  Room  EnterTime
------ --------- ----- ------------------------
24601  23        S     2015-02-27 07:42:03.287
24601  16        F     2015-02-27 11:29:59.497
24601  12        B     2015-03-03 14:38:03.243
24601  41        E     2015-03-03 21:03:05.007
24601  12        B     2015-03-05 10:17:36.773
24601  15        S     2015-03-05 12:19:40.573
24601  15        P     2015-03-06 21:51:20.430
24601  15        L     2015-03-09 10:25:00.127
24601  16        A     2015-03-10 17:19:30.550
************************************************/


I'd like to get that data grouped by person/floor with the next beginning timestamp becoming the end timestamp of the previous row.  Like this:

/********* Desired Output: ******************************************
id     FloorNum  FromTime                 ToTime
------ --------- ------------------------ ------------------------
24601  23        2015-02-27 07:42:03.287  2015-02-27 11:29:59.497
24601  16        2015-02-27 11:29:59.497  2015-03-03 14:38:03.243
24601  12        2015-03-03 14:38:03.243  2015-03-03 21:03:05.007
24601  41        2015-03-03 21:03:05.007  2015-03-05 10:17:36.773
24601  12        2015-03-05 10:17:36.773  2015-03-05 12:19:40.573
24601  15        2015-03-05 12:19:40.573  2015-03-10 17:19:30.550
24601  16        2015-03-10 17:19:30.550  NULL
********************************************************************/


I've tried to come up with various uses of window functions to solve this in a set-based manner, but I can't seem to find a way to group consecutive entries on the same floor together while separating the non-consecutive ones.
Using the newly added LAG() and LEAD() functions makes it look easy:

WITH a AS
    ( SELECT PersonID, FloorNum, EnterTime,
             PrevFloorNum = LAG(FloorNum) OVER
                                (PARTITION BY PersonID ORDER BY EnterTime)
      FROM RoomAssignments
    ) 
SELECT PersonID, FloorNum,
       FromTime = EnterTime,
       ToTime = LEAD(EnterTime) OVER 
                    (PARTITION BY PersonID ORDER BY EnterTime)
FROM a
WHERE PrevFloorNum &lt;&gt; FloorNum OR PrevFloorNum IS NULL 
ORDER BY PersonID, FromTime ;


Test in SQLfiddle