Index: /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 689)
+++ /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 690)
@@ -243,50 +243,5 @@
 	var aCells = FCKTableHandler.GetSelectedCells() ;
 
-	// At least 2 cells must be selected.
-	if ( aCells.length < 2 )
-		return ;
-
-	// The merge can occour only if the selected cells are from the same row.
-	if ( aCells[0].parentNode != aCells[aCells.length-1].parentNode )
-		return ;
-
-	// Calculate the new colSpan for the first cell.
-	var iColSpan = isNaN( aCells[0].colSpan ) ? 1 : aCells[0].colSpan ;
-
-	var sHtml = '' ;
-	var oCellsContents = FCK.EditorDocument.createDocumentFragment() ;
-
-	for ( var i = aCells.length - 1 ; i >= 0 ; i-- )
-	{
-		var eCell = aCells[i] ;
-
-		// Move its contents to the document fragment.
-		for ( var c = eCell.childNodes.length - 1 ; c >= 0 ; c-- )
-		{
-			var eChild = eCell.removeChild( eCell.childNodes[c] ) ;
-
-			if ( ( eChild.hasAttribute && eChild.hasAttribute('_moz_editor_bogus_node') ) || ( eChild.getAttribute && eChild.getAttribute( 'type', 2 ) == '_moz' ) )
-				continue ;
-
-			oCellsContents.insertBefore( eChild, oCellsContents.firstChild ) ;
-		}
-
-		if ( i > 0 )
-		{
-			// Accumulate the colspan of the cell.
-			iColSpan += isNaN( eCell.colSpan ) ? 1 : eCell.colSpan ;
-
-			// Delete the cell.
-			FCKTableHandler.DeleteCell( eCell ) ;
-		}
-	}
-
-	// Set the innerHTML of the remaining cell (the first one).
-	aCells[0].colSpan = iColSpan ;
-
-	if ( FCKBrowserInfo.IsGecko && oCellsContents.childNodes.length == 0 )
-		aCells[0].innerHTML = GECKO_BOGUS ;
-	else
-		aCells[0].appendChild( oCellsContents ) ;
+	// TODO: Reimplement MergeCells() with this._InstallTableMap().
 }
 
@@ -562,4 +517,97 @@
 }
 
+// This function is the inverse of _CreateTableMap - it takes in a table map and converts it to an HTML table.
+FCKTableHandler._InstallTableMap = function( tableMap, table )
+{
+	// Clear the table of all rows first.
+	while ( table.rows.length > 0 )
+	{
+		var row = table.rows[0] ;
+		row.parentNode.removeChild( row ) ;
+	}
+
+	// Disconnect all the cells in tableMap from their parents, set all colSpan and rowSpan attributes to 1.
+	for ( var i = 0 ; i < tableMap.length ; i++ )
+	{
+		for ( var j = 0 ; j < tableMap[i].length ; j++ )
+		{
+			var cell = tableMap[i][j] ;
+			if ( cell.parentNode )
+				cell.parentNode.removeChild( cell ) ;
+			cell.colSpan = cell.rowSpan = 1 ;
+		}
+	}
+
+	// Scan by rows and set colSpan.
+	var maxCol = 0 ;
+	for ( var i = 0 ; i < tableMap.length ; i++ )
+	{
+		for ( var j = 0 ; j < tableMap[i].length ; j++ )
+		{
+			var cell = tableMap[i][j] ;
+			if ( ! cell)
+				continue ;
+			if ( j > maxCol )
+				maxCol = j ;
+			if ( cell._colScanned === true )
+				continue ;
+			if ( tableMap[i][j-1] == cell )
+				cell.colSpan++ ;
+			if ( tableMap[i][j+1] != cell )
+				cell._colScanned = true ;
+		}
+	}
+
+	// Scan by columns and set rowSpan.
+	for ( var i = 0 ; i <= maxCol ; i++ )
+	{
+		for ( var j = 0 ; j < tableMap.length ; j++ )
+		{
+			if ( ! tableMap[j] )
+				continue ;
+			var cell = tableMap[j][i] ;
+			if ( ! cell || cell._rowScanned === true )
+				continue ;
+			if ( tableMap[j-1] && tableMap[j-1][i] == cell )
+				cell.rowSpan++ ;
+			if ( ! tableMap[j+1] || tableMap[j+1][i] != cell )
+				cell._rowScanned = true ;
+		}
+	}
+
+	// Clear all temporary flags.
+	for ( var i = 0 ; i < tableMap.length ; i++ )
+	{
+		for ( var j = 0 ; j < tableMap[i].length ; j++)
+		{
+			var cell = tableMap[i][j] ;
+			cell.removeAttribute( '_colScanned' ) ;
+			cell.removeAttribute( '_rowScanned' ) ;
+		}
+	}
+
+	// Insert physical rows and columns to the table.
+	for ( var i = 0 ; i < tableMap.length ; i++ )
+	{
+		var rowObj = table.ownerDocument.createElement( 'tr' ) ;
+		for ( var j = 0 ; j < tableMap[i].length ; )
+		{
+			var cell = tableMap[i][j] ;
+			if ( tableMap[i-1] && tableMap[i-1][j] == cell )
+			{
+				j += cell.colSpan ;
+				continue ;
+			}
+			rowObj.appendChild( cell ) ;
+			j += cell.colSpan ;
+			if ( cell.colSpan == 1 )
+				cell.removeAttribute( 'colspan' ) ;
+			if ( cell.rowSpan == 1 )
+				cell.removeAttribute( 'rowspan' ) ;
+		}
+		table.appendChild( rowObj ) ;
+	}
+}
+
 FCKTableHandler.ClearRow = function( tr )
 {
