protected synchronized void replaceChildrenAt(NodeInfo[] source, int index, boolean inherit) {
        if (children == null) {
            return;
        }
        for (int i=0; i<source.length; i++) {
            NodeImpl child = (NodeImpl)source[i];
            child.parent = this;
            int kind = child.getNodeKind();
            switch (kind) {
                case Type.ELEMENT:
                    // If the child has no xmlns="xxx" declaration, then add an xmlns="" to prevent false inheritance
                    // from the new parent
                    ((ElementImpl)child).fixupInsertedNamespaces(inherit);
                    break;
                case Type.COMMENT:
                case Type.TEXT:
                case Type.PROCESSING_INSTRUCTION:
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Replacement child node is not an element, text, comment, or PI");

            }
        }
        if (children instanceof NodeImpl) {
            if (source.length == 0) {
                children = null;
            } else if (source.length == 1) {
                children = source[0];
            } else {
                NodeImpl[] n2 = new NodeImpl[source.length];
                System.arraycopy(source, 0, n2, 0, source.length);
                children = cleanUpChildren(n2);
            }
        } else {
            NodeImpl[] n0 = (NodeImpl[])children;
            NodeImpl[] n2 = new NodeImpl[n0.length + source.length - 1];
            System.arraycopy(n0, 0, n2, 0, index);
            System.arraycopy(source, 0, n2, index, source.length);
            System.arraycopy(n0, index + 1, n2, index+source.length, n0.length - index - 1);
            children = cleanUpChildren(n2);
        }
    }