anchor.diff:  
             if (!sortOpts) {
               sortOpts = { columnId: column.id, sortAsc: column.defaultSortAsc };
  -            sortColumns.push(sortOpts);
  +            sortColumns.add(sortOpts);
             } else if (sortColumns.length == 0) {
  -            sortColumns.push(sortOpts);
  +            sortColumns.add(sortOpts);
             }
           }
   
           setSortColumns(sortColumns);
   
           if (!options.multiColumnSort) {
  -          trigger(self.onSort, {
  -            multiColumnSort: false,
  -            sortCol: column,
  -            sortAsc: sortOpts.sortAsc}, e);
  +          fire(ON_SORT, {
  +            'multiColumnSort': false,
  +            'sortCol': column,
  +            'sortAsc': sortOpts.sortAsc}, e);
           } else {
  -          trigger(self.onSort, {
  -            multiColumnSort: true,
  -            sortCols: $.map(sortColumns, function(col) {
  -              return {sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc };
  +          fire(ON_SORT, {
  +            'multiColumnSort': true,
  +            'sortCols': $.map(sortColumns, (col) { // TODO map
  +              return {'sortCol': columns[getColumnIndex(col.columnId)], 'sortAsc': col.sortAsc };
               })}, e);
           }
         }
       });
     }
   
  -  function setupColumnReorder() {
  +  void setupColumnReorder() {
       $headers.filter(":ui-sortable").sortable("destroy");
       $headers.sortable({
  -      containment: "parent",
  -      distance: 3,
  -      axis: "x",
  -      cursor: "default",
  -      tolerance: "intersection",
  -      helper: "clone",
  -      placeholder: "slick-sortable-placeholder ui-state-default slick-header-column",
  -      start: function (e, ui) {
  +      'containment': "parent",
  +      'distance': 3,
  +      'axis': "x",
  +      'cursor': "default",
  +      'tolerance': "intersection",
  +      'helper': "clone",
  +      'placeholder': "slick-sortable-placeholder ui-state-default slick-header-column",
  +      'start': (e, ui) {
           ui.placeholder.width(ui.helper.outerWidth() - headerColumnWidthDiff);
  -        $(ui.helper).addClass("slick-header-column-active");
  +        (ui.helper as dom.HtmlElement).classes.add("beu-datagrid-header-column-active");
         },
  -      beforeStop: function (e, ui) {
  -        $(ui.helper).removeClass("slick-header-column-active");
  +      'beforeStop': (e, ui) {
  +        (ui.helper as dom.HtmlElement).classes.remove("bwu-datagrid-header-column-active");
         },
  -      stop: function (e) {
  +      'stop': (e) {
           if (!getEditorLock().commitCurrentEdit()) {
  -          $(this).sortable("cancel");
  +          $(this).sortable("cancel"); // TODO
             return;
           }
   
  
positive.code:       resizeCanvas();
        bindAncestorScrollEvents();
  
        $container.on["resize.slickgrid"].listen(resizeCanvas);
        //$viewport
            //.bind("click", handleClick)
        $viewport.onScroll.listen(handleScroll);
        $headerScroller..onContextMenu.listen(handleHeaderContextMenu)
            ..onClick.listen(handleHeaderClick)
            .delegate(".bwu-datagrid-header-column", "mouseenter", handleHeaderMouseEnter)
            .delegate(".bwu-datagrid-header-column", "mouseleave", handleHeaderMouseLeave);
        $headerRowScroller
            .onScroll.listen(handleHeaderRowScroll);
        $focusSink.add($focusSink2)
            .bind("keydown", handleKeyDown);
        $canvas
            ..onKeyDown.listen(handleKeyDown)
            ..onClick.listen(handleClick)
            ..onDoubleClick.listen(handleDblClick)
            ..onContextMenu.listen(handleContextMenu)
            //..bind("draginit", handleDragInit) // TODO
            ..onDragStart.listen((e) {/*{distance: 3}*/; handleDragStart(e);}) // TODO what is distance?
            ..onDrag.listen(handleDrag)
            ..onDragEnd.listen(handleDragEnd)
            ..querySelectorAll(".bwu-datagrid--cell").forEach((e) {
              (e as dom.HtmlElement)
                ..onMouseEnter.listen(handleMouseEnter)
                ..onMouseLeave.listen(handleMouseLeave);
  
        // Work around http://crbug.com/312427.
        if (navigator.userAgent.toLowerCase().match('webkit') &&  // TODO match
            navigator.userAgent.toLowerCase().match('macintosh')) { // TODO match
          $canvas.onMouseWheel.listen(handleMouseWheel);
        }
      }
  
negative.code: library bwu_dart.bwu_datagrid.datagrid;
  
  import 'dart:async' as async;
  import 'dart:math' as math;
  import 'dart:html' as dom;
  
  