treat all getColumnIndex() checks exactly the same throughout the code: always check using `!= null` or `== null`: treat NULL and UNDEFINED as if identifal.
fed back private edits into the main repo:

- kill the deleted node store: it doesn't work. focus, rendering and white-flash updates are not helped, let alone fixed, by it. Wrong way to do this.

- JSHint/JSCS happiness

- make sure the `$container` also can receive focus (and thus keyboard key events): when slickgrid has moved the focus to one of the catchall drains (`$focusSink2`, `$focusSink`) and the keyboard code (including userland code, which may help to screw things up even worse) and the browser would otherwise 'move out' of the control area of the grid entirely, then we would be able to catch this and prevent it from happening.

- use namespacing for the `$container` events: userland code could already have their own handlers on that one or add some of their own later and we want to be able to kill *our* handlers, while leaving userland events alone: after all, the `$container` is not a DOM element which we have full control over from start to end as we do not *create* it ourselves...

- updateColumnHeader() API: allow the userland event handlers (onBeforeHeaderCellDestroy event) to modify the title and/or tooltip of the addressed column when it edits the columnDef struct. Pick up those changes on the fly.

- updateColumnHeader() API: allow empty (null) column name/title as run with it: treat as empty ("")

- readability of code: `m` --> `columnDef`: whenever we can, we should use that variable name for this item: the column definition struct.

- rowPositionCache[]: take heed of the JavaScript performance info out there, e.g. the talks about the Chrome V8 engine: set up the cache object structure once and do not change it during its lifetime: do not add or delete attributes but instead init them all at one. (even when you init them as `undefined` or `null` the JS engine will have a better chance at optimizing the code as the object structure *type definition* does not change during its lifetime. This is a coding mentality thing, rather than a direct & significant measurable performance improvement right now.

- when `options.asyncRenderDelay` is set to zero(0), then delayed rendering should not occur at all: this would be one way to break away from the optimized lazy rendering tactics which are now part of slickgrid -- and thus a way out away from the bugs that still pester the new invalidate+render mechanism.
- okay, now the grid "white flash" is gone: cells are not deleted (DOM removeChild for cells and/or rows) but instead flagged as "dirty"; then when render() comes around, it updates all the "dirty" content via `updateCell()` (which now gets a *lot* more use than before, so we're definitely exercising quite different areas of slickgrid with this new approach).

- the above is still accompanied by cell/row removal when the cells/rows get *outside* the "rendered area" (which is the visible area plus a bit of buffer in all directions); do note that `cleanupRows()` now is the only one who does some real DOM node removal and it's *only* invoked inside `render()` hence DOM nodes for cells and rows stay around while you scroll very fast (you can see this with the current long delay setting happening: move around and the 'activeCell' gets updated every time and all the 'old' activeCells will still be available while scrolling, even while no render() got executed *yet*. This at least cleans up the render/invalidation/update process a bit, so that is gets to be manageable again (see next item though).

- slickgrid risk area: I'm not sure the row/colspanning cells are handled correctly at all times and I must say that the `invalidateRows()` code which addresses the special concerns for those only got worse in terms of complexity. I'll have to test and simplify that chunk if I can, because it was and still is raising the hairs on my head ;-)

- migrated the internal spans cache from array indexed to object for legibility: now colspan is not index `[3]` but `.colspan`, for example (I'm talking about the `{ row, cell, rowspan, colspan }` arrays turned objects here).

- I'm not at all happy with the way ow/colspanning was & is handled, but right now I can't come up with a faster / more efficient approach to these. Imagine having `rowspan=*` columns in a 1 million row grid and working 'at the bottom of it': the current implementation scans all the way back to row=0 to find rowspan overlaps with the active (visible) area. :-(

- added code to the activateCellInternal() function so that we pick up focus and shift it to the slickgrid focusSisnks when the activeCell is nuked (set to NULL): even without the activeCell we still want to get the keyboard events and all, unless userland code specifically takes focus elsewhere! Focus managment is hairy stuff. Hopefully it just got a little *less* hairy with this edit. (I think it does; that focus stack is still in there too, though, while it may be a horrible hack to tracking focus in your entire app from within the confines of a slickgrid instance alone, but at least that focus stack helps us determine if we *lose focus* because the user clicks somewhere else in the page, *outside* the slickgrid $container`... Buggerit, millenium hand & shrimp!

- as part of the "dirty" flagging, invalidateAllRows() doesn't render (update) any cells any more by itself; you'll have to call render() to get any visual updates happening. (This was crap lingering from the old days; now that we have lazy/delayed rendering, those updateCell() calls in there should have died alongside the introduction of that lazy render approach -- now at least you are sure of the basic principle holding: activeCells are rendered immediately and are always present as a DOM node, while the rest of the grid is lazy-rendered and may not exist yet when you get certain slickgrid events. (TODO: trigger a 'render started' + 'render done' event so userland code can easily observe when the render actually kicks in. Also TODO: observe both the *active* cell and the *focused* cell: the two don't necessarily have to be the same: the user can click or otherwise focus another cell, while the visuals keep *another* cell marked as "the active cell"!)

- Also: fixed up the rowHeight comparisons to always properly account for the `cellHeightDiff` value (code review).

- new API: invalidateCell(): now you can have much finer-grained control of grid invalidation/updating from userland code: instead of calling invalidateRow or one of the others, single cell updates should now be followed by a call to `invalidateCell()` (and a call to `render()`) to make slickgrid *only* update that single (invalidated) cell.

- Also note that this approach will not destroy the existing DOM node for that cell but rather *update* it via `updateCell()`, thus allowing certain assumptions in userland code which were not valid before (now existing DOM nodes are flagged as "dirty" on invalidation and then *updated* on `render()`, rather than being removed entirely (`removeChild() for cell and row DOM nodes!) and subsequently regenerated in the `render()` call.
added two new events: `onRenderStart` and `onRenderEnd`: these are fired at the very start (and end) of the actual grid visual update (render via `forcedRender()`); this means that by the time you get `onRenderEnd` you can assume that all visible cells have been updated (of course excluding the async postprocessing!)

Now these three events are fired during the render process itself:

- onRenderStart
- onRowsRendered
- onRenderEnd