Index: /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 694)
+++ /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 695)
@@ -315,5 +315,4 @@
 			if ( ! tableMap[rowIdx] || ! tableMap[rowIdx][colIdx] )
 			{
-				FCKDebug.Output( rowIdx + "," + colIdx + " not found" ) ;
 				this._UnmarkCells( cells, '_CellSelected' ) ;
 				return false ;
@@ -322,5 +321,4 @@
 			if ( g.width != geometry.width || g.height != geometry.height )
 			{
-				FCKDebug.Output( "size " + g.width + "x" + g.height + " not match" ) ;
 				this._UnmarkCells( cells, '_CellSelected' ) ;
 				return false ;
@@ -335,5 +333,4 @@
 			if ( ! tableMap[rowIdx] || ! tableMap[rowIdx][colIdx] )
 			{
-				FCKDebug.Output( rowIdx + "," + colIdx + " not found" ) ;
 				this._UnmarkCells( cells, '_CellSelected' ) ;
 				return false ;
@@ -342,5 +339,4 @@
 			if ( g.width != geometry.width || g.height != geometry.height )
 			{
-				FCKDebug.Output( "size " + g.width + "x" + g.height + " not match" ) ;
 				this._UnmarkCells( cells, '_CellSelected' ) ;
 				return false ;
@@ -356,8 +352,51 @@
 {
 	// Get all selected cells.
-	var aCells = FCKTableHandler.GetSelectedCells() ;
-
-	// TODO: Reimplement MergeCells() with this._InstallTableMap().
-
+	var cells = this.GetSelectedCells() ;
+	if ( cells.length < 2 )
+		return ;
+
+	// Assume the selected cells are already in a rectangular geometry.
+	// Because the checking is already done by FCKTableCommand.
+	var refCell = cells[0] ;
+	var tableMap = this._CreateTableMap( refCell.parentNode.parentNode ) ;
+	var rowIdx = refCell.parentNode.rowIndex ;
+	var colIdx = this._GetCellIndexSpan( tableMap, rowIdx, refCell ) ;
+
+	this._MarkCells( cells, '_SelectedCells' ) ;
+	var selectionGeometry = this._GetMarkerGeometry( tableMap, rowIdx, colIdx, '_SelectedCells' ) ;
+
+	var baseColIdx = colIdx - selectionGeometry.x ;
+	var baseRowIdx = rowIdx - selectionGeometry.y ;
+	var cellContents = refCell.ownerDocument.createDocumentFragment() ;
+	for ( var i = 0 ; i < selectionGeometry.height ; i++ ) 
+	{
+		var rowChildNodesCount = 0 ;
+		for ( var j = 0 ; j < selectionGeometry.width ; j++ )
+		{
+			var currentCell = tableMap[baseRowIdx + i][baseColIdx + j] ;
+			while ( currentCell.childNodes.length > 0 )
+			{
+				var node = currentCell.removeChild( currentCell.firstChild ) ;
+				if ( node.nodeType != 1 
+					|| ( node.getAttribute( 'type', 2 ) != '_moz' && node.getAttribute( '_moz_dirty' ) != null ) )
+				{
+					cellContents.appendChild( node ) ;
+					rowChildNodesCount++ ;
+				}
+			}
+		}
+		if ( rowChildNodesCount > 0 )
+			cellContents.appendChild( refCell.ownerDocument.createElement( 'br' ) ) ;
+	}
+
+	this._ReplaceCellsByMarker( tableMap, '_SelectedCells', refCell ) ;
+	this._UnmarkCells( cells, '_SelectedCells' ) ;
+	this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
+	refCell.appendChild( cellContents ) ;
+	
+	if ( FCKBrowserInfo.IsGecko && ( ! refCell.firstChild ) )
+		FCKTools.AppendBogusBr( refCell ) ;
+
+	this._MoveCaretToCell( refCell, false ) ;
 }
 
@@ -381,6 +420,5 @@
 	this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
 
-	FCKSelection.SelectNode( refCell ) ;
-	FCKSelection.Collapse( false ) ;
+	this._MoveCaretToCell( refCell, false ) ;
 }
 
@@ -404,36 +442,67 @@
 	this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
 
-	FCKSelection.SelectNode( refCell ) ;
-	FCKSelection.Collapse( false ) ;
+	this._MoveCaretToCell( refCell, false ) ;
 }
 
 FCKTableHandler.HorizontalSplitCell = function()
 {
-	// Check that just one cell is selected, otherwise return.
-	var aCells = FCKTableHandler.GetSelectedCells() ;
-	if ( aCells.length != 1 )
+	var cells = FCKTableHandler.GetSelectedCells() ;
+	if ( cells.length != 1 )
 		return ;
 
-	var aMap = this._CreateTableMap( aCells[0].parentNode.parentNode ) ;
-	var iCellIndex = FCKTableHandler._GetCellIndexSpan( aMap, aCells[0].parentNode.rowIndex , aCells[0] ) ;
-
-	var aCollCells = this._GetColumnCells( aMap, iCellIndex ) ;
-
-	for ( var i = 0 ; i < aCollCells.length ; i++ )
-	{
-		if ( aCollCells[i] == aCells[0] )
-		{
-			var oNewCell = this.InsertCell( aCells[0], false ) ;
-			if ( !isNaN( aCells[0].rowSpan ) && aCells[0].rowSpan > 1 )
-				oNewCell.rowSpan = aCells[0].rowSpan ;
-		}
-		else
-		{
-			if ( isNaN( aCollCells[i].colSpan ) )
-				aCollCells[i].colSpan = 2 ;
+	var refCell = cells[0] ;
+	var tableMap = this._CreateTableMap( refCell.parentNode.parentNode ) ;
+	var rowIdx = refCell.parentNode.rowIndex ;
+	var colIdx = FCKTableHandler._GetCellIndexSpan( tableMap, rowIdx, refCell ) ;
+	var cellSpan = isNaN( refCell.colSpan ) ? 1 : refCell.colSpan ;
+
+	if ( cellSpan > 1 )
+	{
+		// Splittng a multi-column cell - original cell gets ceil(colSpan/2) columns,
+		// new cell gets floor(colSpan/2).
+		var newCellSpan = Math.ceil( cellSpan / 2 ) ;
+		var newCell = refCell.ownerDocument.createElement( 'td' ) ;
+		if ( FCKBrowserInfo.IsGecko )
+			FCKTools.AppendBogusBr( newCell ) ;
+		var startIdx = colIdx + newCellSpan ;
+		var endIdx = colIdx + cellSpan ;
+		var rowSpan = isNaN( refCell.rowSpan ) ? 1 : refCell.rowSpan ;
+		for ( var r = rowIdx ; r < rowIdx + rowSpan ; r++ )
+			for ( var i = startIdx ; i < endIdx ; i++ )
+				tableMap[r][i] = newCell ;
+	}
+	else
+	{
+		// Splitting a single-column cell - add a new cell, and expand 
+		// cells crossing the same column.
+		var newTableMap = [] ;
+		for ( var i = 0 ; i < tableMap.length ; i++ ) 
+		{
+			var newRow = tableMap[i].slice( 0, colIdx ) ;
+			if ( tableMap[i].length <= colIdx )
+			{
+				newTableMap.push( newRow ) ;
+				continue ;
+			}
+			if ( tableMap[i][colIdx] == refCell )
+			{
+				newRow.push( refCell ) ;
+				newRow.push( refCell.ownerDocument.createElement( 'td' ) ) ;
+				if ( FCKBrowserInfo.IsGecko )
+					FCKTools.AppendBogusBr( newRow[newRow.length - 1] ) ;
+			}
 			else
-				aCollCells[i].colSpan += 1 ;
-		}
-	}
+			{
+				newRow.push( tableMap[i][colIdx] ) ;
+				newRow.push( tableMap[i][colIdx] ) ;
+			}
+			for ( var j = colIdx + 1 ; j < tableMap[i].length ; j++ )
+				newRow.push( tableMap[i][j] ) ;
+			newTableMap.push( newRow ) ;
+		}
+		tableMap = newTableMap ;
+	}
+
+	this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
 }
 
@@ -706,4 +775,12 @@
 }
 
+FCKTableHandler._MoveCaretToCell = function ( refCell, toStart )
+{
+	var range = new FCKDomRange( FCK.EditorWindow ) ;
+	range.MoveToNodeContents( refCell ) ;
+	range.Collapse( toStart ) ;
+	range.Select() ;
+}
+
 FCKTableHandler.ClearRow = function( tr )
 {
