/// <summary>
        /// Changes the target media object's parent to a different parent.
        /// </summary>
        /// <param name="target">target object</param>
        /// <param name="np">new parent</param>
        /// <exception cref="InvalidCastException">
        /// Thrown when the target's current parent is not a <see cref="DvMediaContainer"/>.
        /// </exception>
        internal static void ChangeParent2(IDvMedia target, DvMediaContainer np)
        {
            Exception  error          = null;
            IUPnPMedia errorDuplicate = null;

            IDvMedia[] removeThese = new IDvMedia[1];
            removeThese[0] = target;

            DvMediaContainer dvp = (DvMediaContainer)target.Parent;

            // fire about to remove event
            if (dvp.OnChildrenToRemove != null)
            {
                dvp.OnChildrenToRemove(dvp, removeThese);
            }

            // acquire locks
            dvp.m_LockListing.AcquireWriterLock(-1);
            np.m_LockListing.AcquireWriterLock(-1);

            try
            {
                // remove target from current parent
                int i = dvp.HashingMethod.Get(dvp.m_Listing, target);
                dvp.m_Listing.RemoveAt(i);
                target.Parent = null;
                if (dvp.m_Listing.Count == 0)
                {
                    dvp.m_Listing = null;
                }

                // add target to new parent
                if (np.m_Listing == null)
                {
                    np.m_Listing = new ArrayList();
                }
                try
                {
                    np.HashingMethod.Set(np.m_Listing, target, true);
                    target.Parent = np;
                }
                catch (KeyCollisionException)
                {
                    errorDuplicate = target;
                }
            }
            catch (Exception e)
            {
                error = e;
            }

            // release locks
            np.m_LockListing.ReleaseWriterLock();
            dvp.m_LockListing.ReleaseWriterLock();

            // throw exceptions if appropriate
            if (error != null)
            {
                throw new Exception("Unexpected rrror in DvMediaContainer.ChangeParent2", error);
            }

            if (errorDuplicate != null)
            {
                throw new Error_DuplicateIdException(errorDuplicate);
            }

            // fire children removed event
            if (dvp.OnChildrenRemoved != null)
            {
                dvp.OnChildrenRemoved(dvp, removeThese);
            }

            // notify upnp network that two containers changed.
            dvp.NotifyRootOfChange();
            np.NotifyRootOfChange();
        }