/// <summary>
        /// Download thumbnails
        /// </summary>
        async private void GetThumbnails()
        {
            if (_getThumbnailQueue.Count == 0)
            {
                return;
            }

            var thumbFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ThetaImage", "thumbnails"));

            thumbFolder.Create();

            // Get list of thumbnails already downloaded
            var existingFiles = thumbFolder.EnumerateFiles().Where(file => file.Extension.Equals(".jpg", StringComparison.CurrentCultureIgnoreCase) ||
                                                                   file.Extension.Equals(".jpeg", StringComparison.CurrentCultureIgnoreCase)).ToList();

            var localFiles = new Dictionary <string, FileInfo>();

            foreach (var file in existingFiles)
            {
                localFiles.Add(file.Name, file);
            }

            // For each entry...
            while (_getThumbnailQueue.Count > 0)
            {
                var anEntry = _getThumbnailQueue.Dequeue();
                if (localFiles.ContainsKey(anEntry.Data.Name))
                {
                    // if the thumbnail is already downloaded, use that .
                    anEntry.LocalThumbFile = localFiles[anEntry.Data.Name].FullName;
                    localFiles.Remove(anEntry.Data.Name);
                }
                else
                {
                    // Otherwise get it from camera
                    var param = new ListFilesParam()
                    {
                        FileType = ThetaFileType.Image, EntryCount = 1, Detail = true, StartPosition = anEntry.EntryNo
                    };
                    try
                    {
                        var res = await _theta.ThetaApi.ListFilesAsync(param);

                        if (res.Entries.Length == 0)
                        {
                            continue;
                        }
                        var result = res.Entries[0];

                        using (var memStream = new MemoryStream())
                        {
                            await memStream.WriteAsync(result.ThumbnailData, 0, result.ThumbnailData.Length);

                            var newFile = new FileInfo(Path.Combine(thumbFolder.FullName, anEntry.Data.Name));
                            using (Stream aStream = newFile.Open(FileMode.CreateNew, FileAccess.Write))
                            {
                                memStream.Seek(0, SeekOrigin.Begin);
                                memStream.CopyTo(aStream);
                            }

                            anEntry.LocalThumbFile = newFile.FullName;
                        }
                    }
                    catch (System.Net.WebException)
                    {
                        break;
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                await Task.Delay(1);
            }

            // Delete files that are no longer exist inside the camera
            foreach (var key in localFiles.Keys)
            {
                try
                {
                    localFiles[key].Delete();
                }
                catch (IOException)
                {
                    // This happens when we delete pictures.
                    // It is too soon to delete thumbnails. Safe to delete next time.
                }
            }
        }
        /// <summary>
        /// Reload all files
        /// </summary>
        public async Task ReloadAllFilesAsync(bool force = true)
        {
            if (!this.Dispatcher.CheckAccess())
            {
                await this.Dispatcher.BeginInvoke(new Action(async() =>
                {
                    await ReloadAllFilesAsync(force);
                }));

                return;
            }
            if (force || _deviceImages.Count == 0)
            {
                _deviceImages.Clear();

                while (true)
                {
                    var param = new ListFilesParam()
                    {
                        FileType = ThetaFileType.Image, EntryCount = 50, StartPosition = _deviceImages.Count, Detail = false
                    };
                    var res = await _theta.ThetaApi.ListFilesAsync(param);

                    foreach (var anEntry in res.Entries)
                    {
                        var wrapper = new FileEntryWrapper()
                        {
                            Data = anEntry, EntryNo = _deviceImages.Count
                        };
                        _deviceImages.Add(wrapper);
                        _getThumbnailQueue.Enqueue(wrapper);
                    }

                    if (_deviceImages.Count >= res.TotalEntries)
                    {
                        break;
                    }
                }
            }

            var di = new DirectoryInfo(txtFolder.Text);
            // Get list of thumbnails already downloaded
            var existingFiles = di.EnumerateFiles().Where(file => file.Extension.Equals(".jpg", StringComparison.CurrentCultureIgnoreCase) ||
                                                          file.Extension.Equals(".jpeg", StringComparison.CurrentCultureIgnoreCase)).ToList();

            var localFiles = new Dictionary <string, FileInfo>();

            foreach (var file in existingFiles)
            {
                localFiles.Add(file.Name, file);
            }

            foreach (var anEntry in _deviceImages)
            {
                if (localFiles.ContainsKey(anEntry.Data.Name))
                {
                    anEntry.DownloadStatus = DOWNLOAD_STATUS.DOWNLOADED;
                }
            }

            IEnumerable <FileEntryWrapper> filteredEntries = null;

            switch (cmbImageFilter.SelectedValue)
            {
            case PHOTO_FILTER.DOWNLOADED:
                filteredEntries = from anEntry in _deviceImages where anEntry.DownloadStatus == DOWNLOAD_STATUS.DOWNLOADED select anEntry;
                break;

            case PHOTO_FILTER.NOT_DOWNLOADED:
                filteredEntries = from anEntry in _deviceImages where anEntry.DownloadStatus != DOWNLOAD_STATUS.DOWNLOADED select anEntry;
                break;

            case PHOTO_FILTER.ALL:
            default:
                filteredEntries = _deviceImages;
                break;
            }

            var view      = (CollectionView)CollectionViewSource.GetDefaultView(filteredEntries);
            var groupDesc = new PropertyGroupDescription("SimpleDate");

            view.GroupDescriptions.Add(groupDesc);

            groupDesc.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending));
            lstFiles.DataContext = filteredEntries;

            GetThumbnails();
        }