public void TestFinishedState()
        {
            var listener = new TaskListener <string>();

            listener.SetValue("lolz");
            listener.SetFinished();

            Assert.AreEqual("lolz", listener.Value);
            Assert.IsTrue(listener.IsFinished);
            Assert.AreEqual(1f, listener.TotalProgress, Delta);

            listener.SetProgress(0.5f);
            listener.SetValue("a");
            Assert.AreEqual("lolz", listener.Value);
            Assert.IsTrue(listener.IsFinished);
            Assert.AreEqual(1f, listener.TotalProgress, Delta);
        }
        public void TestGeneric()
        {
            var listener = new TaskListener <int>();
            int result   = 0;

            listener.OnFinished += (v) => result = v;
            Assert.AreEqual(default(int), listener.Value);
            Assert.AreEqual(default(int), result);

            listener.SetValue(5);
            Assert.AreEqual(5, listener.Value);
            Assert.AreEqual(0, result);

            listener.SetFinished();
            Assert.AreEqual(5, listener.Value);
            Assert.AreEqual(5, result);
        }
        public async Task <T> Import(FileInfo archive, bool deleteOnImport = true, TaskListener <T> listener = null)
        {
            if (archive == null)
            {
                throw new ArgumentNullException(nameof(archive));
            }
            if (!archive.Exists)
            {
                throw new FileNotFoundException($"File at ({archive.FullName}) does not exist!");
            }

            // Retrieve the compressed file representation of the archive.
            var compressed = CompressedHelper.GetCompressed(archive);

            if (compressed == null)
            {
                throw new NotImportableException(archive, GetType());
            }

            // Start extraction of archive.
            var extractedDir = await compressed.Uncompress(GetTempExtractDir(archive), listener?.CreateSubListener <DirectoryInfo>());

            if (!extractedDir.Exists)
            {
                throw new NotImportableException(archive, GetType());
            }

            // Parse the data at temporary extraction destination.
            var data = ParseData(extractedDir);

            // Failed to parse.
            if (data == null)
            {
                listener?.SetFinished();
                return(default(T));
            }

            // Calculate hash code.
            data.CalculateHash();

            // Check whether this data already exists using hash check.
            bool isNewData = false;

            if (ContainsHash(data.HashCode, out T existingData))
            {
                // Replace existing data.
                PostProcessData(data, existingData.Id);
            }
            else
            {
                // Allocate a new Id.
                PostProcessData(data, Guid.NewGuid());
                isNewData = true;
            }

            // Move the extracted data under management of the storage.
            storage.Move(data.Id.ToString(), extractedDir);
            // Replace or add the data to database.
            database.Edit().Write(data).Commit();

            // Delete archive
            if (deleteOnImport)
            {
                archive.Delete();
            }

            // Report finished.
            listener?.SetValue(data);
            listener?.SetFinished();
            if (isNewData)
            {
                OnNewData?.Invoke(data);
            }
            return(data);
        }