private void MenuItemFindSynergyFiles_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //just supporting first attached device for now
                NwdPortableDeviceCollection col =
                    new NwdPortableDeviceCollection();
                col.Refresh();

                if (col.Count() > 0)
                {
                    NwdPortableDevice device = col.First();

                    if (device != null)
                    {
                        if (unprocessedSynergyFiles == null ||
                            unprocessedSynergyFiles.Count < 1)
                        {
                            IEnumerable<NwdUriProcessEntry> synergyFiles =
                                GetDeviceSynergyFiles(device);

                            unprocessedSynergyFiles =
                                new Stack<NwdUriProcessEntry>(synergyFiles);

                            Display.Grid(synergyFiles.Count() +
                                " synergy files found", unprocessedSynergyFiles);
                        }
                        else
                        {
                            string msg = unprocessedSynergyFiles.Count +
                                " unprocessed synergy file entries found";

                            Display.Message(msg);
                        }

                        if (unprocessedSynergyFiles != null)
                        {
                            List<NwdUriProcessEntry> processed =
                                new List<NwdUriProcessEntry>();

                            bool again = true;
                            string msg = "Enter processing segment size";

                            while (again && unprocessedSynergyFiles.Count() > 0)
                            {
                                int repetitionSegmentSize =
                                    NineWorldsDeep.UI.Prompt.ForInteger(msg);

                                IEnumerable<NwdUriProcessEntry> currentlyProcessing =
                                    unprocessedSynergyFiles.Pop(repetitionSegmentSize);

                                int copiedFilesCount = 0;
                                Stopwatch watch = Stopwatch.StartNew();

                                foreach (NwdUriProcessEntry pe in currentlyProcessing)
                                {
                                    if (pe.DeviceObject is NwdPortableDeviceFile)
                                    {
                                        NwdPortableDeviceFile pdf =
                                            (NwdPortableDeviceFile)pe.DeviceObject;

                                        string localFolderPath =
                                            Configuration.MtpSynergySyncPath;

                                        device.DownloadFile(pdf, localFolderPath);

                                        copiedFilesCount++;
                                    }

                                    pe.Processed = true;
                                    processed.Add(pe);
                                }

                                watch.Stop();

                                string displayMsg = processed.Count +
                                    " processed / " +
                                    unprocessedSynergyFiles.Count +
                                    " unprocessed";

                                Display.Grid(displayMsg,
                                             processed,
                                             unprocessedSynergyFiles);

                                again =
                                NineWorldsDeep.UI.Prompt.Confirm("Processing time: "
                                + watch.Elapsed.ToString() +
                                " to process " + copiedFilesCount +
                                " entries. Process more entries?");
                            }

                        }

                    }
                }
                else
                {
                    Display.Message("no devices found");
                }

            }
            catch (Exception ex)
            {
                Display.Exception(ex);
            }
        }
        private void MenuItemFindToBeRemovedPlayList_Click(object sender, RoutedEventArgs e)
        {
            //just supporting first attached device for now, can cycle through multiples later
            NwdPortableDeviceCollection col = new NwdPortableDeviceCollection();

            try
            {
                col.Refresh();
            }
            catch (Exception ex)
            {
                Display.Exception(ex);
            }

            if (col.Count() > 0)
            {
                NwdPortableDevice device = col.First();

                if (device != null)
                {
                    //if(unprocessedDeletions == null ||
                    //    unprocessedDeletions.Count < 1)
                    if (unprocessedDeletions.IsEmptyOrNull())
                    {
                        toBeRemoved = GetFirstToBeRemovedPlaylist();

                        if (toBeRemoved == null)
                        {
                            MessageBox.Show("Playlist(s) 'to be removed[*]' not found");
                        }
                        else
                        {
                            MessageBox.Show("found [" + toBeRemoved.Name + "]");

                            //copy file to local file system
                            string localDestinationFolder = Configuration.PlaylistsFolder;
                            device.DownloadFile(toBeRemoved, localDestinationFolder);

                            string localFilePath =
                                System.IO.Path.Combine(localDestinationFolder, toBeRemoved.Name);

                            MessageBox.Show("copied file to [" + localFilePath + "]");

                            List<string> entries = File.ReadAllLines(localFilePath).ToList();

                            MessageBox.Show("found " + entries.Count + " entries");

                            List<NwdUri> lst = new List<NwdUri>();
                            List<string> invalidPaths = new List<string>();

                            foreach (string entry in entries)
                            {
                                NwdUri newUri = Configuration.NwdPathToNwdUri(entry);
                                if (newUri != null)
                                {
                                    lst.Add(newUri);
                                }
                                else
                                {
                                    invalidPaths.Add(entry);
                                }
                            }

                            var pathList = (from entry in invalidPaths
                                            select new
                                            {
                                                Path = entry
                                            }).ToList();

                            if (pathList.Count > 0)
                            {
                                Display.Grid(invalidPaths.Count + " invalid paths skipped", lst, pathList);
                            }
                            else
                            {
                                Display.Grid("0 invalid paths skipped", lst);
                            }

                            var processEntries = (from nwdUri in lst
                                                  select new NwdUriProcessEntry(nwdUri)).ToList();

                            unprocessedDeletions =
                                new Stack<NwdUriProcessEntry>(processEntries);
                        }

                    }
                    else
                    {
                        MessageBox.Show(unprocessedDeletions.Count
                            + " unprocessed entries found for ["
                            + toBeRemoved.Name + "]");
                    }

                    if (unprocessedDeletions != null)
                    {

                        List<NwdUriProcessEntry> processed =
                        new List<NwdUriProcessEntry>();

                        bool again = true;
                        string msg = "Enter processing segment size (keep in mind that " +
                            "caching works better the higher this number is, but the " +
                            "higher the number, the longer each iteration will obviously " +
                            "take, find a balance that works for your device)";

                        while (again && unprocessedDeletions.Count() > 0)
                        {
                            int repetitionSegmentSize =
                            NineWorldsDeep.UI.Prompt.ForInteger(msg);

                            IEnumerable<NwdUriProcessEntry> currentlyProcessing =
                                unprocessedDeletions.Pop(repetitionSegmentSize);

                            Stopwatch watch = Stopwatch.StartNew();
                            var res = FindByUriCached(currentlyProcessing.ToNwdUris());
                            watch.Stop(); //just profiling find by uri

                            foreach (NwdUriProcessEntry pe in currentlyProcessing)
                            {
                                if (res[pe.URI].Count > 0)
                                {
                                    pe.DeviceObject = res[pe.URI].First();
                                }

                                pe.Processed = true;
                                processed.Add(pe);
                            }

                            again =
                                NineWorldsDeep.UI.Prompt.Confirm("Processing took "
                                + watch.Elapsed.ToString() +
                                " milliseconds to complete. Process more entries?");
                        }

                        Display.Grid(processed.Count() + " processed / "
                            + unprocessedDeletions.Count() + " unprocessed", processed);

                        if (NineWorldsDeep.UI.Prompt.Confirm("Delete all processed and found files?"))
                        {
                            int deletionCount = 0;

                            foreach (NwdUriProcessEntry pe in processed)
                            {
                                if (pe.FoundOnDevice)
                                {
                                    NwdPortableDeviceObject pdo = pe.DeviceObject;

                                    if (pdo is NwdPortableDeviceFile)
                                    {
                                        try
                                        {
                                            NwdPortableDeviceFile pdf =
                                                (NwdPortableDeviceFile)pdo;

                                            device.DeleteFile(pdf);
                                            deletionCount++;
                                            MessageBox.Show(deletionCount + " files deleted");
                                        }
                                        catch(Exception ex)
                                        {
                                            Display.Exception(ex);
                                        }
                                    }
                                }
                            }

                            if (unprocessedDeletions.Count < 1 && toBeRemoved != null)
                            {
                                string confirmMsg =
                                    "No more unprocessed entries for [" +
                                    toBeRemoved.Name + "] delete file?";

                                if (NineWorldsDeep.UI.Prompt.Confirm(confirmMsg))
                                {
                                    device.DeleteFile(toBeRemoved);

                                    MessageBox.Show("[" + toBeRemoved.Name + "] deleted.");

                                    unprocessedDeletions = null;
                                    toBeRemoved = null;
                                }
                            }
                        }

                    }
                }
            }
            else
            {
                MessageBox.Show("no devices found.");
            }
        }
        private void MenuItemTransferringContentToDevice_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("This one isn't even active, as my device uses " +
                "alphanumeric object ids with no human readable hierarchy. " +
                "It makes copying this tutorial verbatim non-functional, " +
                "but I have adapted the tutorial into a 'transfer file into " +
                "this folder' context menu option. The code in this example " +
                "won't run as I've disabled it, but its in the source for " +
                "reference sake.");

            bool disabled = true;

            //disabled
            if (!disabled)
            {
                var devices = new NwdPortableDeviceCollection();
                devices.Refresh();
                var kindle = devices.First();
                kindle.Connect();

                kindle.TransferContentToDevice(
                    @"d:\temp\Kindle_Users_Guide.azw",
                    @"g:\documents");

                kindle.Disconnect();
            }
        }