nl_tokens: Returns a W3C DOM compatible range object by using the IE Range API
pl_tokens: function getRange ( ) { var ieRange = selection . getRng ( ) , domRange = dom . createRng ( ) , element , collapsed , tmpRange , element2 , bookmark , fail ; // If selection is outside the current document just return an empty range
   element = ieRange . item ? ieRange . item ( 0 ) : ieRange . parentElement ( ) ; if ( element . ownerDocument != dom . doc ) return domRange ; collapsed = selection . isCollapsed ( ) ; // Handle control selection
   if ( ieRange . item ) { domRange . setStart ( element . parentNode , dom . nodeIndex ( element ) ) ; domRange . setEnd ( domRange . startContainer , domRange . startOffset + 1 ) ; return domRange ; } function findEndPoint ( start ) { var endPoint = getPosition ( ieRange , start ) , container , offset , textNodeOffset = 0 , sibling , undef , nodeValue ; container = endPoint . node ; offset = endPoint . offset ; if ( endPoint . inside && ! container . hasChildNodes ( ) ) { domRange [ start ? 'setStart' : 'setEnd' ] ( container , 0 ) ; return ; } if ( offset === undef ) { domRange [ start ? 'setStartBefore' : 'setEndAfter' ] ( container ) ; return ; } if ( endPoint . position < 0 ) { sibling = endPoint . inside ? container . firstChild : container . nextSibling ; if ( ! sibling ) { domRange [ start ? 'setStartAfter' : 'setEndAfter' ] ( container ) ; return ; } if ( ! offset ) { if ( sibling . nodeType == 3 ) domRange [ <mask> ? 'setStart' : 'setEnd' ] ( sibling , 0 ) ; else domRange [ start ? 'setStartBefore' : 'setEndBefore' ] ( sibling ) ; return ; } // Find the text node and offset
   while ( sibling ) { nodeValue = sibling . nodeValue ; textNodeOffset += nodeValue . length ; // We are at or passed the position we where looking for
   if ( textNodeOffset >= offset ) { container = sibling ; textNodeOffset -= offset ; textNodeOffset = nodeValue . length - textNodeOffset ; break ; } sibling = sibling . nextSibling ; } } else { // Find the text node and offset
   sibling = container . previousSibling ; if ( ! sibling ) return domRange [ start ? 'setStartBefore' : 'setEndBefore' ] ( container ) ; // If there isn't any text to loop then use the first position
   if ( ! offset ) { if ( container . nodeType == 3 ) domRange [ start ? 'setStart' : 'setEnd' ] ( sibling , container . nodeValue . length ) ; else domRange [ start ? 'setStartAfter' : 'setEndAfter' ] ( sibling ) ; return ; } while ( sibling ) { textNodeOffset += sibling . nodeValue . length ; // We are at or passed the position we where looking for
   if ( textNodeOffset >= offset ) { container = sibling ; textNodeOffset -= offset ; break ; } sibling = sibling . previousSibling ; } } domRange [ start ? 'setStart' : 'setEnd' ] ( container , textNodeOffset ) ; } ; try { // Find start point
   findEndPoint ( true ) ; // Find end point if needed
   if ( ! collapsed ) findEndPoint ( ) ; } catch ( ex ) { // IE has a nasty bug where text nodes might throw "invalid argument" when you
   // access the nodeValue or other properties of text nodes. This seems to happend when
   // text nodes are split into two nodes by a delete/backspace call. So lets detect it and try to fix it.
   if ( ex . number == - 2147024809 ) { // Get the current selection
   bookmark = self . getBookmark ( 2 ) ; // Get start element
   tmpRange = ieRange . duplicate ( ) ; tmpRange . collapse ( true ) ; element = tmpRange . parentElement ( ) ; // Get end element
   if ( ! collapsed ) { tmpRange = ieRange . duplicate ( ) ; tmpRange . collapse ( false ) ; element2 = tmpRange . parentElement ( ) ; element2 . innerHTML = element2 . innerHTML ; } // Remove the broken elements
   element . innerHTML = element . innerHTML ; // Restore the selection
   self . moveToBookmark ( bookmark ) ; // Since the range has moved we need to re-get it
   ieRange = selection . getRng ( ) ; // Find start point
   findEndPoint ( true ) ; // Find end point if needed
   if ( ! collapsed ) findEndPoint ( ) ; } else throw ex ; // Throw other errors
   } return domRange ; }