Fix appendChild() and insertBefore() (and replaceChild() indirectly) when
the node being added is a fragment node.
This closes SF bug #487929.
diff --git a/Lib/test/output/test_minidom b/Lib/test/output/test_minidom
index b14f74e..14e8845 100644
--- a/Lib/test/output/test_minidom
+++ b/Lib/test/output/test_minidom
@@ -19,6 +19,9 @@
 Passed Test
 Test Succeeded testAppendChild
 Passed assertion: len(Node.allnodes) == 0
+Passed appendChild(<fragment>)
+Test Succeeded testAppendChildFragment
+Passed assertion: len(Node.allnodes) == 0
 Test Succeeded testAttrListItem
 Passed assertion: len(Node.allnodes) == 0
 Test Succeeded testAttrListItemNS
@@ -122,6 +125,10 @@
 Passed testInsertBefore -- node properly placed in tree
 Test Succeeded testInsertBefore
 Passed assertion: len(Node.allnodes) == 0
+Passed insertBefore(<fragment>, None)
+Passed insertBefore(<fragment>, orig)
+Test Succeeded testInsertBeforeFragment
+Passed assertion: len(Node.allnodes) == 0
 Test Succeeded testLegalChildren
 Passed assertion: len(Node.allnodes) == 0
 Passed test NodeList.item()
@@ -172,6 +179,9 @@
 Passed Test
 Test Succeeded testRemoveAttributeNode
 Passed assertion: len(Node.allnodes) == 0
+Passed replaceChild(<fragment>)
+Test Succeeded testReplaceChildFragment
+Passed assertion: len(Node.allnodes) == 0
 Passed testSAX2DOM - siblings
 Passed testSAX2DOM - parents
 Test Succeeded testSAX2DOM
diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py
index ab985b8..adac990 100644
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -79,6 +79,34 @@
             , "testInsertBefore -- node properly placed in tree")
     dom.unlink()
 
+def _create_fragment_test_nodes():
+    dom = parseString("<doc/>")
+    orig = dom.createTextNode("original")
+    c1 = dom.createTextNode("foo")
+    c2 = dom.createTextNode("bar")
+    c3 = dom.createTextNode("bat")
+    dom.documentElement.appendChild(orig)
+    frag = dom.createDocumentFragment()
+    frag.appendChild(c1)
+    frag.appendChild(c2)
+    frag.appendChild(c3)
+    return dom, orig, c1, c2, c3, frag
+
+def testInsertBeforeFragment():
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.insertBefore(frag, None)
+    confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
+            "insertBefore(<fragment>, None)")
+    frag.unlink()
+    dom.unlink()
+    #
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.insertBefore(frag, orig)
+    confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
+            "insertBefore(<fragment>, orig)")
+    frag.unlink()
+    dom.unlink()
+
 def testAppendChild():
     dom = parse(tstfile)
     dom.documentElement.appendChild(dom.createComment(u"Hello"))
@@ -86,6 +114,23 @@
     confirm(dom.documentElement.childNodes[-1].data == "Hello")
     dom.unlink()
 
+def testAppendChildFragment():
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.appendChild(frag)
+    confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
+            "appendChild(<fragment>)")
+    frag.unlink()
+    dom.unlink()
+
+def testReplaceChildFragment():
+    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
+    dom.documentElement.replaceChild(frag, orig)
+    orig.unlink()
+    confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
+            "replaceChild(<fragment>)")
+    frag.unlink()
+    dom.unlink()
+
 def testLegalChildren():
     dom = Document()
     elem = dom.createElement('element')
diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py
index 5b26da7..2e9d866 100644
--- a/Lib/xml/dom/minidom.py
+++ b/Lib/xml/dom/minidom.py
@@ -132,7 +132,7 @@
 
     def insertBefore(self, newChild, refChild):
         if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
-            for c in newChild.childNodes:
+            for c in tuple(newChild.childNodes):
                 self.insertBefore(c, refChild)
             ### The DOM does not clearly specify what to return in this case
             return newChild
@@ -160,7 +160,7 @@
 
     def appendChild(self, node):
         if node.nodeType == self.DOCUMENT_FRAGMENT_NODE:
-            for c in node.childNodes:
+            for c in tuple(node.childNodes):
                 self.appendChild(c)
             ### The DOM does not clearly specify what to return in this case
             return node