diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1363,111 +1363,16 @@ MoveChildrenTo(nsPresContext* aPresConte
 
   if (setHasChildWithView) {
     aNewParent->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
   }
 
   aNewParent->SetInitialChildList(nsnull, aFrameList);
 }
 
-// -----------------------------------------------------------
-
-// Helper function that determines the child list name that aChildFrame
-// is contained in
-nsIAtom*
-nsCSSFrameConstructor::GetChildListNameFor(nsIFrame* aChildFrame)
-{
-  nsIAtom*      listName;
-
-  if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
-    nsIFrame* pif = aChildFrame->GetPrevInFlow();
-    if (pif->GetParent() == aChildFrame->GetParent()) {
-      listName = nsGkAtoms::excessOverflowContainersList;
-    }
-    else {
-      listName = nsGkAtoms::overflowContainersList;
-    }
-  }
-  // See if the frame is moved out of the flow
-  else if (aChildFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
-    // Look at the style information to tell
-    const nsStyleDisplay* disp = aChildFrame->GetStyleDisplay();
-    
-    if (NS_STYLE_POSITION_ABSOLUTE == disp->mPosition) {
-      listName = nsGkAtoms::absoluteList;
-    } else if (NS_STYLE_POSITION_FIXED == disp->mPosition) {
-      if (nsLayoutUtils::IsReallyFixedPos(aChildFrame)) {
-        listName = nsGkAtoms::fixedList;
-      } else {
-        listName = nsGkAtoms::absoluteList;
-      }
-#ifdef MOZ_XUL
-    } else if (NS_STYLE_DISPLAY_POPUP == disp->mDisplay) {
-      // Out-of-flows that are DISPLAY_POPUP must be kids of the root popup set
-#ifdef DEBUG
-      nsIFrame* parent = aChildFrame->GetParent();
-      NS_ASSERTION(parent && parent->GetType() == nsGkAtoms::popupSetFrame,
-                   "Unexpected parent");
-#endif // DEBUG
-
-      // XXX FIXME: Bug 350740
-      // Return here, because the postcondition for this function actually
-      // fails for this case, since the popups are not in a "real" frame list
-      // in the popup set.
-      return nsGkAtoms::popupList;      
-#endif // MOZ_XUL
-    } else {
-      NS_ASSERTION(aChildFrame->GetStyleDisplay()->IsFloating(),
-                   "not a floated frame");
-      listName = nsGkAtoms::floatList;
-    }
-
-  } else {
-    nsIAtom* childType = aChildFrame->GetType();
-    if (nsGkAtoms::menuPopupFrame == childType) {
-      nsIFrame* parent = aChildFrame->GetParent();
-      nsIFrame* firstPopup = (parent)
-                             ? parent->GetFirstChild(nsGkAtoms::popupList)
-                             : nsnull;
-      NS_ASSERTION(!firstPopup || !firstPopup->GetNextSibling(),
-                   "We assume popupList only has one child, but it has more.");
-      listName = (!firstPopup || firstPopup == aChildFrame)
-                 ? nsGkAtoms::popupList
-                 : nsnull;
-    } else if (nsGkAtoms::tableColGroupFrame == childType) {
-      listName = nsGkAtoms::colGroupList;
-    } else if (nsGkAtoms::tableCaptionFrame == aChildFrame->GetType()) {
-      listName = nsGkAtoms::captionList;
-    } else {
-      listName = nsnull;
-    }
-  }
-
-#ifdef NS_DEBUG
-  // Verify that the frame is actually in that child list or in the
-  // corresponding overflow list.
-  nsIFrame* parent = aChildFrame->GetParent();
-  PRBool found = parent->GetChildList(listName).ContainsFrame(aChildFrame);
-  if (!found) {
-    if (!(aChildFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
-      found = parent->GetChildList(nsGkAtoms::overflowList)
-                .ContainsFrame(aChildFrame);
-    }
-    else if (aChildFrame->GetStyleDisplay()->IsFloating()) {
-      found = parent->GetChildList(nsGkAtoms::overflowOutOfFlowList)
-                .ContainsFrame(aChildFrame);
-    }
-    // else it's positioned and should have been on the 'listName' child list.
-    NS_POSTCONDITION(found, "not in child list");
-  }
-#endif
-
-  return listName;
-}
-
 //----------------------------------------------------------------------
 
 nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument,
                                              nsIPresShell *aPresShell)
   : mDocument(aDocument)
   , mPresShell(aPresShell)
   , mRootElementFrame(nsnull)
   , mRootElementStyleFrame(nsnull)
@@ -7123,17 +7028,18 @@ nsCSSFrameConstructor::ContentRemoved(ns
 
 
     // Notify the parent frame that it should delete the frame
     if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
       childFrame = frameManager->GetPlaceholderFrameFor(childFrame);
       NS_ASSERTION(childFrame, "Missing placeholder frame for out of flow.");
       parentFrame = childFrame->GetParent();
     }
-    rv = frameManager->RemoveFrame(GetChildListNameFor(childFrame), childFrame);
+    rv = frameManager->RemoveFrame(nsLayoutUtils::GetChildListNameFor(childFrame),
+                                   childFrame);
     //XXXfr NS_ENSURE_SUCCESS(rv, rv) ?
 
     if (isRoot) {
       mRootElementFrame = nsnull;
       mRootElementStyleFrame = nsnull;
       mDocElementContainingBlock = nsnull;
       mPageSequenceFrame = nsnull;
       mGfxScrollFrame = nsnull;
diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -98,22 +98,16 @@ public:
   static nsIXBLService * GetXBLService();
   static void ReleaseGlobals() { NS_IF_RELEASE(gXBLService); }
 
   // get the alternate text for a content node
   static void GetAlternateTextFor(nsIContent*    aContent,
                                   nsIAtom*       aTag,  // content object's tag
                                   nsXPIDLString& aAltText);
 
-  /**
-   * Uses heuristics to figure out the appropriate child list name
-   * for aChildFrame.
-   */
-  static nsIAtom* GetChildListNameFor(nsIFrame* aChildFrame);
-
 private: 
   // These are not supported and are not implemented! 
   nsCSSFrameConstructor(const nsCSSFrameConstructor& aCopy); 
   nsCSSFrameConstructor& operator=(const nsCSSFrameConstructor& aCopy); 
 
 public:
   // XXXbz this method needs to actually return errors!
   nsresult ConstructRootFrame(nsIFrame** aNewFrame);
diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -746,19 +746,22 @@ nsFrameManager::RemoveFrame(nsIAtom*    
 
 //----------------------------------------------------------------------
 
 void
 nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
 {
   //XXXfr Because we destroy most continuation chains starting from the FIF
   // this does excess work by triggering on every continuation in the chain
-  if (!aFrame->GetPrevContinuation() && aFrame->GetContent()) {
-    RemoveAsPrimaryFrame(aFrame->GetContent(), aFrame);
-    ClearAllUndisplayedContentIn(aFrame->GetContent());
+  nsIContent* content = aFrame->GetContent();
+  if (!aFrame->GetPrevContinuation() && content) {
+    RemoveAsPrimaryFrame(content, aFrame);
+    if (content != aFrame->GetParent()->GetContent()) { // first-letter
+      ClearAllUndisplayedContentIn(content);
+    }
   }
 }
 
 #ifdef NS_DEBUG
 static void
 DumpContext(nsIFrame* aFrame, nsStyleContext* aContext)
 {
   if (aFrame) {
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -176,16 +176,108 @@ GetLastChildFrame(nsIFrame*       aFrame
     }
 
     return lastChildFrame;
   }
 
   return nsnull;
 }
 
+//static
+nsIAtom*
+nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
+{
+  nsIAtom*      listName;
+
+  if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
+    nsIFrame* pif = aChildFrame->GetPrevInFlow();
+    if (pif->GetParent() == aChildFrame->GetParent()) {
+      listName = nsGkAtoms::excessOverflowContainersList;
+    }
+    else {
+      listName = nsGkAtoms::overflowContainersList;
+    }
+  }
+  // See if the frame is moved out of the flow
+  else if (aChildFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
+    // Look at the style information to tell
+    const nsStyleDisplay* disp = aChildFrame->GetStyleDisplay();
+
+    if (NS_STYLE_POSITION_ABSOLUTE == disp->mPosition) {
+      listName = nsGkAtoms::absoluteList;
+    } else if (NS_STYLE_POSITION_FIXED == disp->mPosition) {
+      if (nsLayoutUtils::IsReallyFixedPos(aChildFrame)) {
+        listName = nsGkAtoms::fixedList;
+      } else {
+        listName = nsGkAtoms::absoluteList;
+      }
+#ifdef MOZ_XUL
+    } else if (NS_STYLE_DISPLAY_POPUP == disp->mDisplay) {
+      // Out-of-flows that are DISPLAY_POPUP must be kids of the root popup set
+#ifdef DEBUG
+      nsIFrame* parent = aChildFrame->GetParent();
+      NS_ASSERTION(parent && parent->GetType() == nsGkAtoms::popupSetFrame,
+                   "Unexpected parent");
+#endif // DEBUG
+
+      // XXX FIXME: Bug 350740
+      // Return here, because the postcondition for this function actually
+      // fails for this case, since the popups are not in a "real" frame list
+      // in the popup set.
+      return nsGkAtoms::popupList;
+#endif // MOZ_XUL
+    } else {
+      NS_ASSERTION(aChildFrame->GetStyleDisplay()->IsFloating(),
+                   "not a floated frame");
+      listName = nsGkAtoms::floatList;
+    }
+
+  } else {
+    nsIAtom* childType = aChildFrame->GetType();
+    if (nsGkAtoms::menuPopupFrame == childType) {
+      nsIFrame* parent = aChildFrame->GetParent();
+      nsIFrame* firstPopup = (parent)
+                             ? parent->GetFirstChild(nsGkAtoms::popupList)
+                             : nsnull;
+      NS_ASSERTION(!firstPopup || !firstPopup->GetNextSibling(),
+                   "We assume popupList only has one child, but it has more.");
+      listName = (!firstPopup || firstPopup == aChildFrame)
+                 ? nsGkAtoms::popupList
+                 : nsnull;
+    } else if (nsGkAtoms::tableColGroupFrame == childType) {
+      listName = nsGkAtoms::colGroupList;
+    } else if (nsGkAtoms::tableCaptionFrame == aChildFrame->GetType()) {
+      listName = nsGkAtoms::captionList;
+    } else {
+      listName = nsnull;
+    }
+  }
+
+#ifdef NS_DEBUG
+  // Verify that the frame is actually in that child list or in the
+  // corresponding overflow list.
+  nsIFrame* parent = aChildFrame->GetParent();
+  PRBool found = parent->GetChildList(listName).ContainsFrame(aChildFrame);
+  if (!found) {
+    if (!(aChildFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
+      found = parent->GetChildList(nsGkAtoms::overflowList)
+                .ContainsFrame(aChildFrame);
+    }
+    else if (aChildFrame->GetStyleDisplay()->IsFloating()) {
+      found = parent->GetChildList(nsGkAtoms::overflowOutOfFlowList)
+                .ContainsFrame(aChildFrame);
+    }
+    // else it's positioned and should have been on the 'listName' child list.
+    NS_POSTCONDITION(found, "not in child list");
+  }
+#endif
+
+  return listName;
+}
+
 // static
 nsIFrame*
 nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
 {
   NS_PRECONDITION(aFrame, "NULL frame pointer");
   NS_ASSERTION(!aFrame->GetPrevContinuation(),
                "aFrame must be first continuation");
   
diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -71,16 +71,23 @@ class nsTextFragment;
 /**
  * nsLayoutUtils is a namespace class used for various helper
  * functions that are useful in multiple places in layout.  The goal
  * is not to define multiple copies of the same static helper.
  */
 class nsLayoutUtils
 {
 public:
+
+  /**
+   * Uses heuristics to figure out the appropriate child list name
+   * for aChildFrame.
+   */
+  static nsIAtom* GetChildListNameFor(nsIFrame* aChildFrame);
+
   /**
    * GetBeforeFrame returns the outermost :before frame of the given frame, if
    * one exists.  This is typically O(1).  The frame passed in must be
    * the first-in-flow.   
    *
    * @param aFrame the frame whose :before is wanted
    * @return the :before frame or nsnull if there isn't one
    */
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -5288,18 +5288,18 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aD
     // prevSibling will only be nsnull when we are deleting the very
     // first frame in the main or overflow list.
     if (searchingOverflowList) {
       nsIFrame* prevSibling = aDeletedFrame->GetPrevSibling();
       if (prevSibling) {
         // XXXbz If we switch overflow lines to nsFrameList, we should
         // change this SetNextSibling call.
         prevSibling->SetNextSibling(nextFrame);
-        aDeletedFrame->SetNextSibling(nsnull);
       }
+      aDeletedFrame->SetNextSibling(nsnull);
     } else {
       mFrames.RemoveFrame(aDeletedFrame);
     }
 
     // Update the child count of the line to be accurate
     PRInt32 lineChildCount = line->GetChildCount();
     lineChildCount--;
     line->SetChildCount(lineChildCount);
diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * rendering object for the point that anchors out-of-flow rendering
  * objects such as floats and absolutely positioned elements
  */
 
-#include "nsCSSFrameConstructor.h"
+#include "nsLayoutUtils.h"
 #include "nsPlaceholderFrame.h"
 #include "nsLineLayout.h"
 #include "nsIContent.h"
 #include "nsPresContext.h"
 #include "nsIRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsFrameManager.h"
 #include "nsDisplayList.h"
@@ -130,17 +130,17 @@ void
 nsPlaceholderFrame::Destroy()
 {
   nsIPresShell* shell = PresContext()->GetPresShell();
   nsIFrame* oof = mOutOfFlowFrame;
   if (oof) {
     NS_ASSERTION(shell && oof->GetParent(), "Null presShell or parent!?");
     // Unregister and destroy out-of-flow frame
     shell->FrameManager()->UnregisterPlaceholderFrame(this);
-    nsIAtom* listName = nsCSSFrameConstructor::GetChildListNameFor(oof);
+    nsIAtom* listName = nsLayoutUtils::GetChildListNameFor(oof);
     shell->FrameManager()->RemoveFrame(listName, oof);
   }
 
   nsFrame::Destroy();
 }
 
 nsIAtom*
 nsPlaceholderFrame::GetType() const
diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h
--- a/layout/generic/nsPlaceholderFrame.h
+++ b/layout/generic/nsPlaceholderFrame.h
@@ -124,16 +124,17 @@ public:
   virtual void AddInlineMinWidth(nsIRenderingContext *aRenderingContext,
                                  InlineMinWidthData *aData);
   virtual void AddInlinePrefWidth(nsIRenderingContext *aRenderingContext,
                                   InlinePrefWidthData *aData);
   NS_IMETHOD Reflow(nsPresContext* aPresContext,
                     nsHTMLReflowMetrics& aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus& aStatus);
+
   virtual void Destroy();
 
   // nsIFrame overrides
 #if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF))
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 #endif // DEBUG || (MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF)
