/// <summary>
        /// <para>
        /// Calls the parent container's
        /// <see cref="DvMediaContainer.NotifyRootOfChange"/> method.
        /// </para>
        ///
        /// <para>
        /// Enumerates through this item's reference items and instructs
        /// each to notify their parents of the change.
        /// </para>
        /// </summary>
        /// <exception cref="InvalidCastException">
        /// Thrown when parent container is not a <see cref="DvMediaContainer"/> object.
        /// </exception>
        public void NotifyRootOfChange()
        {
            DvMediaContainer mc = (DvMediaContainer)this.m_Parent;

            if (mc != null)
            {
                mc.NotifyRootOfChange();
            }

            this.LockReferenceList();
            if (this.m_ReferringItems != null)
            {
                foreach (IDvItem refItem in this.m_ReferringItems)
                {
                    mc = (DvMediaContainer)refItem.Parent;
                    if (mc != null)
                    {
                        mc.NotifyRootOfChange();
                    }
                }
            }
            this.UnlockReferenceList();
        }
        /// <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();
        }
        /// <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();
        }