Index: /FCKeditor/trunk/_whatsnew.html
===================================================================
--- /FCKeditor/trunk/_whatsnew.html	(revision 2597)
+++ /FCKeditor/trunk/_whatsnew.html	(revision 2598)
@@ -93,4 +93,9 @@
 		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2486">#2486</a>] Vertically splitting
 			cell with colspan > 1 breaks table layout.</li> 			
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2412">#2412</a>] Fixed the issue 
+			where FCK.InsertHtml() is no longer removing selected contents after content insertion
+			in Firefox.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2407">#2407</a>] Fixed the issue
+			where the Div container command and the blockquote command would break lists.</li>
 	</ul>
 	<p>
Index: /FCKeditor/trunk/editor/_source/commandclasses/fckblockquotecommand.js
===================================================================
--- /FCKeditor/trunk/editor/_source/commandclasses/fckblockquotecommand.js	(revision 2597)
+++ /FCKeditor/trunk/editor/_source/commandclasses/fckblockquotecommand.js	(revision 2598)
@@ -84,5 +84,4 @@
 		if ( state == FCK_TRISTATE_OFF )
 		{
-			iterator.EnforceRealBlocks = true ;
 			var paragraphs = [] ;
 			while ( ( block = iterator.GetNextParagraph() ) )
@@ -110,4 +109,11 @@
 				commonParent = FCKDomTools.GetCommonParents( block.parentNode, commonParent ).pop() ;
 			}
+
+			// The common parent must not be the following tags: table, tbody, tr, ol, ul.
+			while ( commonParent.nodeName.IEquals( 'table', 'tbody', 'tr', 'ol', 'ul' ) )
+				commonParent = commonParent.parentNode ;
+
+			// Reconstruct the block list to be processed such that all resulting blocks
+			// satisfy parentNode == commonParent.
 			var lastBlock = null ;
 			while ( paragraphs.length > 0 )
@@ -151,4 +157,5 @@
 		{
 			var moveOutNodes = [] ;
+			var elementMarkers = {} ;
 			while ( ( block = iterator.GetNextParagraph() ) )
 			{
@@ -166,9 +173,25 @@
 				}
 
-				if ( bqParent && bqChild )
+				// Remember the blocks that were recorded down in the moveOutNodes array
+				// to prevent duplicates.
+				if ( bqParent && bqChild && !bqChild._fckblockquotemoveout )
+				{
 					moveOutNodes.push( bqChild ) ;
-			}
+					FCKDomTools.SetElementMarker( elementMarkers, bqChild, '_fckblockquotemoveout', true ) ;
+				}
+			}
+			FCKDomTools.ClearAllMarkers( elementMarkers ) ;
 
 			var movedNodes = [] ;
+			var processedBlockquoteBlocks = [], elementMarkers = {} ;
+			var noBlockLeft = function( bqBlock )
+			{
+				for ( var i = 0 ; i < bqBlock.childNodes.length ; i++ )
+				{
+					if ( FCKListsLib.BlockElements[ bqBlock.childNodes[i].nodeName.toLowerCase() ] )
+						return false ;
+				}
+				return true ;
+			} ;
 			while ( moveOutNodes.length > 0 )
 			{
@@ -179,20 +202,28 @@
 				// Otherwise, split the blockquote node and move the paragraph in between the two blockquote nodes.
 				if ( node == node.parentNode.firstChild )
-				{
 					bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock ) ;
-					if ( ! bqBlock.firstChild )
-						bqBlock.parentNode.removeChild( bqBlock ) ;
-				}
 				else if ( node == node.parentNode.lastChild )
-				{
 					bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock.nextSibling ) ;
-					if ( ! bqBlock.firstChild )
-						bqBlock.parentNode.removeChild( bqBlock ) ;
-				}
 				else
 					FCKDomTools.BreakParent( node, node.parentNode, range ) ;
 
+				// Remember the blockquote node so we can clear it later (if it becomes empty).
+				if ( !bqBlock._fckbqprocessed )
+				{
+					processedBlockquoteBlocks.push( bqBlock ) ;
+					FCKDomTools.SetElementMarker( elementMarkers, bqBlock, '_fckbqprocessed', true );
+				}
+
 				movedNodes.push( node ) ;
 			}
+
+			// Clear blockquote nodes that have become empty.
+			for ( var i = processedBlockquoteBlocks.length - 1 ; i >= 0 ; i-- )
+			{
+				var bqBlock = processedBlockquoteBlocks[i] ;
+				if ( noBlockLeft( bqBlock ) )
+					FCKDomTools.RemoveNode( bqBlock ) ;
+			}
+			FCKDomTools.ClearAllMarkers( elementMarkers ) ;
 
 			if ( FCKConfig.EnterMode.IEquals( 'br' ) )
Index: /FCKeditor/trunk/editor/dialog/fck_div.html
===================================================================
--- /FCKeditor/trunk/editor/dialog/fck_div.html	(revision 2597)
+++ /FCKeditor/trunk/editor/dialog/fck_div.html	(revision 2598)
@@ -204,10 +204,41 @@
 	var block ;
 
-	iterator.EnforceRealBlocks = true ;
 	var paragraphs = [] ;
+	while ( ( block = iterator.GetNextParagraph() ) )
+		paragraphs.push( block ) ;
+
+	// Make sure all paragraphs have the same parent.
+	var commonParent = paragraphs[0].parentNode ;
+	var tmp = [] ;
+	for ( var i = 0 ; i < paragraphs.length ; i++ )
+	{
+		block = paragraphs[i] ;
+		commonParent = FCKDomTools.GetCommonParents( block.parentNode, commonParent ).pop() ;
+	}
+
+	// The common parent must not be the following tags: table, tbody, tr, ol, ul.
+	while ( commonParent.nodeName.IEquals( 'table', 'tbody', 'tr', 'ol', 'ul' ) )
+		commonParent = commonParent.parentNode ;
+
+	// Reconstruct the block list to be processed such that all resulting blocks
+	// satisfy parentNode == commonParent.
+	var lastBlock = null ;
+	while ( paragraphs.length > 0 )
+	{
+		block = paragraphs.shift() ;
+		while ( block.parentNode != commonParent )
+			block = block.parentNode ;
+		if ( block != lastBlock )
+			tmp.push( block ) ;
+		lastBlock = block ;
+	}
+	paragraphs = tmp ;
+
+	// Split the paragraphs into groups depending on their BlockLimit element.
 	var groups = [] ;
 	var lastBlockLimit = null ;
-	while ( ( block = iterator.GetNextParagraph() ) )
-	{
+	for ( var i = 0 ; i < paragraphs.length ; i++ )
+	{
+		block = paragraphs[i] ;
 		var elementPath = new FCKElementPath( block ) ;
 		if ( elementPath.BlockLimit != lastBlockLimit )
@@ -219,4 +250,5 @@
 	}
 
+	// Create a DIV container for each group.
 	for ( var i = 0 ; i < groups.length ; i++ )
 	{
