docs: function joinNextLineToCursor( editor, cursor, nextCursor ) {
  		editor.fire( 'saveSnapshot' );
  
  		// Merge with previous block's content.
  		nextCursor.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );
  		var frag = nextCursor.extractContents();
  
  		cursor.trim( false, true );
  		var bm = cursor.createBookmark();
  
  		// Kill original bogus;
  		var currentPath = new CKEDITOR.dom.elementPath( cursor.startContainer ),
  				pathBlock = currentPath.block,
  				currentBlock = currentPath.lastElement.getAscendant( 'li', 1 ) || pathBlock,
  				nextPath = new CKEDITOR.dom.elementPath( nextCursor.startContainer ),
  				nextLi = nextPath.contains( CKEDITOR.dtd.$listItem ),
  				nextList = nextPath.contains( CKEDITOR.dtd.$list ),
  				last;
  
  		// Remove bogus node the current block/pseudo block.
  		if ( pathBlock ) {
  			var bogus = pathBlock.getBogus();
  			bogus && bogus.remove();
  		}
  		else if ( nextList ) {
  			last = nextList.getPrevious( nonEmpty );
  			if ( last && blockBogus( last ) )
  				last.remove();
  		}
  
  		// Kill the tail br in extracted.
  		last = frag.getLast();
  		if ( last && last.type == CKEDITOR.NODE_ELEMENT && last.is( 'br' ) )
  			last.remove();
  
  		// Insert fragment at the range position.
  		var nextNode = cursor.startContainer.getChild( cursor.startOffset );
  		if ( nextNode )
  			frag.insertBefore( nextNode );
  		else
  			cursor.startContainer.append( frag );
  
  		// Move the sub list nested in the next list item.
  		if ( nextLi ) {
  			var sublist = getSubList( nextLi );
  			if ( sublist ) {
  				// If next line is in the sub list of the current list item.
  				if ( currentBlock.contains( nextLi ) ) {
  					mergeChildren( sublist, nextLi.getParent(), nextLi );
  					sublist.remove();
  				}
  				// Migrate the sub list to current list item.
  				else
  					currentBlock.append( sublist );
  			}
  		}
  
  		var nextBlock, parent;
  		// Remove any remaining zombies path blocks at the end after line merged.
  		while ( nextCursor.checkStartOfBlock() && nextCursor.checkEndOfBlock() ) {
  			nextPath = nextCursor.startPath();
  			nextBlock = nextPath.block;
  
  			// Abort when nothing to be removed (#10890).
  			if ( !nextBlock )
  				break;
  
  			// Check if also to remove empty list.
  			if ( nextBlock.is( 'li' ) ) {
  				parent = nextBlock.getParent();
  				if ( nextBlock.equals( parent.getLast( nonEmpty ) ) && nextBlock.equals( parent.getFirst( nonEmpty ) ) )
  					nextBlock = parent;
  			}
  
  			nextCursor.moveToPosition( nextBlock, CKEDITOR.POSITION_BEFORE_START );
  			nextBlock.remove();
  		}
  
  		// Check if need to further merge with the list resides after the merged block. (#9080)
  		var walkerRng = nextCursor.clone(), editable = editor.editable();
  		walkerRng.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END );
  		var walker = new CKEDITOR.dom.walker( walkerRng );
  		walker.evaluator = function( node ) { return nonEmpty( node ) && !blockBogus( node ); };
  		var next = walker.next();
  		if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.getName() in CKEDITOR.dtd.$list )
  			mergeListSiblings( next );
  
  		cursor.moveToBookmark( bm );
  
  		// Make fresh selection.
  		cursor.select();
  
  		editor.fire( 'saveSnapshot' );
  	}