private bool AddDirectoryEx(DvMediaContainer container, DirectoryInfo directory)
        {
            if (directory.Exists == false) return false;

            MediaBuilder.storageFolder storageInfo = new MediaBuilder.storageFolder(directory.Name);
            storageInfo.Searchable = true;
            storageInfo.IsRestricted = false;
            DvMediaContainer newContainer = DvMediaBuilder.CreateContainer(storageInfo);
            newContainer.OnChildrenRemoved += new DvDelegates.Delegate_OnChildrenRemove(this.Sink_OnChildRemoved);
            newContainer.Callback_UpdateMetadata = new DvMediaContainer.Delegate_UpdateMetadata(this.Sink_UpdateContainerMetadata);

            InnerMediaDirectory mediadir = new InnerMediaDirectory();
            mediadir.directory = directory;
            mediadir.directoryname = directory.FullName;
            mediadir.watcher = new FileSystemWatcher(directory.FullName);
            mediadir.watcher.Changed += new FileSystemEventHandler(OnDirectoryChangedSink);
            mediadir.watcher.Created += new FileSystemEventHandler(OnDirectoryCreatedSink);
            mediadir.watcher.Deleted += new FileSystemEventHandler(OnDirectoryDeletedSink);
            mediadir.watcher.Renamed += new RenamedEventHandler(OnFileSystemRenameSink);
            mediadir.restricted = true;
            mediadir.readOnly = true;

            watcherTable.Add(mediadir.watcher,newContainer);
            mediadir.watcher.EnableRaisingEvents = true;

            newContainer.Tag = mediadir;

            FileInfo[] files = directory.GetFiles();
            ArrayList addedFiles = new ArrayList(files.Length);
            foreach (FileInfo file in files)
            {
                IDvMedia newObj = CreateObjFromFile(file, new ArrayList());
                if (newObj != null)
                {
                    addedFiles.Add(newObj);
                    totalFileCount++;
                }
            }

            newContainer.AddObjects(addedFiles, true);

            // Add the new container to an existing container.
            container.AddObject(newContainer, true);

            foreach (IDvMedia item in addedFiles)
            {
                if (item.Class.IsA(MediaBuilder.StandardMediaClasses.AudioItem))
                {
                    this.m_AudioItems.AddReference((DvMediaItem)item);
                }
                else if (item.Class.IsA(MediaBuilder.StandardMediaClasses.ImageItem))
                {
                    this.m_ImageItems.AddReference((DvMediaItem)item);
                }
                else if (item.Class.IsA(MediaBuilder.StandardMediaClasses.VideoItem))
                {
                    this.m_VideoItems.AddReference((DvMediaItem)item);
                }
                else if (item.Class.IsA(MediaBuilder.StandardMediaClasses.PlaylistContainer))
                {
                    // References to playlists are not allowed, so we have to build
                    // completely new instances of the container and its resources.
                    // However the new container can have references to the items.
                    DvMediaContainer originalC = (DvMediaContainer) item;

                    MediaBuilder.playlistContainer plcInfo = new MediaBuilder.playlistContainer(originalC.Title);
                    DvMediaContainer newC = DvMediaBuilder.CreateContainer(plcInfo);

                    foreach (DvMediaResource res in originalC.Resources)
                    {
                        ResourceBuilder.AllResourceAttributes resAttribs = new ResourceBuilder.AllResourceAttributes();
                        resAttribs.contentUri = res.ContentUri;
                        foreach (string attribute in res.ValidAttributes)
                        {
                            object obj = res[attribute];
                            _RESATTRIB attribName = (_RESATTRIB) Enum.Parse(typeof(_RESATTRIB), attribute, true);

                            switch (attribName)
                            {
                                case _RESATTRIB.bitrate:
                                    resAttribs.bitrate = (_UInt) obj;
                                    break;
                                case _RESATTRIB.bitsPerSample:
                                    resAttribs.bitsPerSample = (_UInt) obj;
                                    break;
                                case _RESATTRIB.colorDepth:
                                    resAttribs.colorDepth = (_UInt) obj;
                                    break;
                                case _RESATTRIB.duration:
                                    resAttribs.duration = (_TimeSpan) obj;
                                    break;
                                case _RESATTRIB.importUri:
                                    //do not allow import
                                    break;
                                case _RESATTRIB.nrAudioChannels:
                                    resAttribs.nrAudioChannels = (_UInt) obj;
                                    break;
                                case _RESATTRIB.protection:
                                    resAttribs.protection = (string) obj;
                                    break;
                                case _RESATTRIB.protocolInfo:
                                    resAttribs.protocolInfo = new ProtocolInfoString(((ProtocolInfoString)obj).ToString());
                                    break;
                                case _RESATTRIB.resolution:
                                    resAttribs.resolution = (ImageDimensions) obj;
                                    break;
                                case _RESATTRIB.sampleFrequency:
                                    resAttribs.sampleFrequency = (_UInt) obj;
                                    break;
                                case _RESATTRIB.size:
                                    resAttribs.size = (_ULong) obj;
                                    break;
                            }
                        }
                        DvMediaResource newCR = DvResourceBuilder.CreateResource(resAttribs, false);
                        newCR.AllowImport = res.AllowImport;
                        newCR.CheckAutomapFileExists = res.CheckAutomapFileExists;
                        newCR.HideContentUri = res.HideContentUri;
                        newCR.MakeStreamAtHttpGetTime = res.MakeStreamAtHttpGetTime;
                        newCR.Tag = res.Tag;

                        newC.AddResource(newCR);
                    }

                    // The child container should only have items.
                    // If the child-container has child containers, then
                    // then this is bad because those child playlists
                    // should have been converted to a flat list
                    // in the recursive building of the hierarchy
                    foreach (DvMediaItem childItem in originalC.CompleteList)
                    {
                        newC.AddReference(childItem);
                    }

                    this.m_Playlists.AddObject(newC, true);
                }
            }

            DirectoryInfo[] directories = directory.GetDirectories();
            foreach (DirectoryInfo dir in directories)
            {
                AddDirectoryEx(newContainer,dir);
            }

            totalDirectoryCount++;
            if (OnStatsChanged != null) OnStatsChanged(this);
            return true;
        }
        private void AdjustContainer(DvMediaContainer c)
        {
            InnerMediaDirectory imd = c.Tag as InnerMediaDirectory;
            bool dirExists = false;

            // Remove non-root containers if the associated directory no longer exists.
            if (c.IsRootContainer == false)
            {
                if (imd != null)
                {
                    imd.directory = new DirectoryInfo(imd.directoryname);
                    if (imd.directory.Exists == false)
                    {
                        c.Parent.RemoveObject(c);
                    }
                    else
                    {
                        dirExists = true;
                    }
                }
            }

            // c.CompleteList returns a shallow copy
            foreach (IDvMedia dv in c.CompleteList)
            {
                if (dv.IsContainer)
                {
                    this.AdjustContainer((DvMediaContainer) dv);
                }
                else if (dv.IsReference)
                {
                    // ignore references
                }
                else
                {
                    // this is an item; dv.Resources returns a shallow copy
                    foreach (IDvResource res in dv.Resources)
                    {
                        if (res.ContentUri.StartsWith(MediaResource.AUTOMAPFILE))
                        {
                            string localPath = res.ContentUri.Remove(0, MediaResource.AUTOMAPFILE.Length);
                            int quesMark = localPath.LastIndexOf('?');
                            if (quesMark >= 0)
                            {
                                localPath = localPath.Substring(0, localPath.LastIndexOf('?'));
                            }

                            if (File.Exists(localPath) == false)
                            {
                                dv.RemoveResource(res);
                            }
                        }
                    }

                    // if the item has no resources, remove it
                    if (dv.Resources.Length == 0)
                    {
                        dv.Parent.RemoveObject(dv);
                    }
                }
            }

            if (dirExists)
            {
                this.totalDirectoryCount++;

                // Scan the directory for containers and files that don't exist
                // in the current tree
                DirectoryInfo[] subdirs = imd.directory.GetDirectories();
                FileInfo[] files = imd.directory.GetFiles();
                IList containers = c.Containers;
                IList items = c.Items;

                foreach (DirectoryInfo subdir in subdirs)
                {
                    bool found = false;
                    foreach (IDvContainer dvc in containers)
                    {
                        InnerMediaDirectory imd2 = dvc.Tag as InnerMediaDirectory;

                        if (imd2 != null)
                        {
                            // this container has a mapping to a local directory,
                            // so determine if the container matches the
                            // target name
                            if (string.Compare(subdir.FullName, imd2.directoryname, true) == 0)
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    if (found == false)
                    {
                        // the subdirectory wasn't found as a container in the tree,
                        // so go ahead and add it
                        this.AddDirectoryEx(c, subdir);
                    }
                }

                foreach (FileInfo file in files)
                {
                    bool found = false;
                    foreach (IDvItem dvi in items)
                    {
                        if (dvi.IsReference == false)
                        {
                            bool foundRes = false;
                            foreach (IDvResource res in dvi.Resources)
                            {
                                string localPath = res.ContentUri.Remove(0, MediaResource.AUTOMAPFILE.Length);
                                int quesMark = localPath.LastIndexOf('?');
                                if (quesMark >= 0)
                                {
                                    localPath = localPath.Substring(0, localPath.LastIndexOf('?'));
                                }

                                if (string.Compare(localPath, file.FullName, true) == 0)
                                {
                                    foundRes = true;
                                }
                                break;
                            }

                            if (foundRes)
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    foreach (IDvContainer dvc in containers)
                    {
                        if (dvc.Class.IsA(MediaBuilder.StandardMediaClasses.PlaylistContainer))
                        {
                            FileInfo plfi = dvc.Tag as FileInfo;
                            if (plfi != null)
                            {
                                if (string.Compare(plfi.FullName, file.FullName, true) == 0)
                                {
                                    found = true;
                                }
                            }
                        }
                    }

                    if (found == false)
                    {
                        // the file wasn't found as a resource in the
                        // content hierarchy, so go ahead and add it
                        IDvMedia newItem = this.CreateObjFromFile(file, new ArrayList());
                        c.AddObject(newItem, true);
                    }

                    // we either already had a media item for the file, or we just added one
                    this.totalFileCount++;
                }

                // Also initialize inner media directory objects with a file
                // system watcher if the directory still exists.
                // We do this at the end because we don't want to subscribe
                // to changes until after we've added files.
                imd.watcher = new FileSystemWatcher(imd.directory.FullName);
                imd.watcher.Changed += new FileSystemEventHandler(OnDirectoryChangedSink);
                imd.watcher.Created += new FileSystemEventHandler(OnDirectoryCreatedSink);
                imd.watcher.Deleted += new FileSystemEventHandler(OnDirectoryDeletedSink);
                imd.watcher.Renamed += new RenamedEventHandler(OnFileSystemRenameSink);
            }
        }
        public void ResetCoreRoot()
        {
            MediaBuilder.SetNextID(0);
            rootContainer = mediaServer.Root;

            MediaBuilder.container containerImagesInfo = new MediaBuilder.container("All Image Items");
            containerImagesInfo.IsRestricted = true;

            MediaBuilder.container containerAudioItemsInfo = new MediaBuilder.container("All Audio Items");
            containerAudioItemsInfo.IsRestricted = true;

            MediaBuilder.container containerVideoItemsInfo = new MediaBuilder.container("All Video Items");
            containerVideoItemsInfo.IsRestricted = true;

            MediaBuilder.container containerPlaylistsInfo = new MediaBuilder.container("All Playlists");
            containerPlaylistsInfo.IsRestricted = true;

            m_ImageItems = (DvMediaContainer) DvMediaBuilder.CreateContainer(containerImagesInfo);

            m_AudioItems = (DvMediaContainer) DvMediaBuilder.CreateContainer(containerAudioItemsInfo);

            m_VideoItems = (DvMediaContainer) DvMediaBuilder.CreateContainer(containerVideoItemsInfo);

            m_Playlists = (DvMediaContainer) DvMediaBuilder.CreateContainer(containerPlaylistsInfo);

            rootContainer.AddObject(m_ImageItems, true);
            rootContainer.AddObject(m_AudioItems, true);
            rootContainer.AddObject(m_VideoItems, true);
            rootContainer.AddObject(m_Playlists, true);
        }