public static Task <PreparedFolder> Load(string rootPath, IProgressReporter reporter)
        {
            if (string.IsNullOrEmpty(rootPath))
            {
                throw new ArgumentNullException("rootPath");
            }
            if (!Directory.Exists(rootPath))
            {
                throw new DirectoryNotFoundException(rootPath);
            }
            return(Task.Factory.StartNew(() =>
            {
                var reader = new PreparedRootFolderReader();
                bool report = reporter != null;
                if (report)
                {
                    reporter.Start("read prepared folders");
                    reader.ProgressChanged += (_, e) =>
                    {
                        reporter.Report(e.Percent, e.Status);
                    };
                }
                var root = reader.Read(rootPath);

                if (report)
                {
                    reporter.Complete("prepared folders loaded");
                }

                return root;
            }));
        }
        public static Task <NFSFolder> Load(IEnumerable <string> nfsLines, IProgressReporter reporter)
        {
            return(Task.Factory.StartNew(() =>
            {
                bool report = reporter != null;
                if (report)
                {
                    reporter.Start("read nfs folders");
                }

                var root = NFSFolder.CreateRoot();
                if (nfsLines == null || !nfsLines.Any())
                {
                    if (report)
                    {
                        reporter.Complete("nfs folders loaded");
                    }
                    return root;
                }

                var reader = new NFSFoldersReader(nfsLines);
                if (report)
                {
                    reader.ProgressChanged += (_, e) =>
                    {
                        reporter.Report(e.Percent, e.Status);
                    };
                }

                foreach (var folder in reader.Read())
                {
                    root.Add(folder);
                }

                if (report)
                {
                    reporter.Complete("nfs folders loaded");
                }
                return root;
            }));
        }
        private static void UITest(IProgressReporter reporter)
        {
            var report = reporter != null;

            for (int i = 0; i < 10; i++)
            {
                if (report)
                {
                    reporter.Report((double)i / 10, string.Format("Tesing. . . {0} remind", 10 - i));
                }
                System.Threading.Thread.Sleep(100);
            }

            if (report)
            {
                reporter.Complete("done");
            }
        }
        public Task <IEnumerable <string> > Read(IProgressReporter reporter)
        {
            if (working)
            {
                throw new InvalidOperationException("operation is already running");
            }

            bool report = reporter != null;

            if (report)
            {
                reporter.Start("loading nfs lines");
            }

            this.invoker.Invoke(null);
            this.nfsReadBlock = new AutoResetEvent(false);
            return(Task.Factory.StartNew <IEnumerable <string> >(() =>
            {
                this.nfsReadBlock.WaitOne();
                this.nfsReadBlock.Dispose();
                this.nfsReadBlock = null;

                this.working = false;

                var result = this.result;
                if (result.HasError)
                {
                    if (report)
                    {
                        reporter.Report(0, null);
                    }
                    throw new Exception("error occurred while loading nfs lines: " + result.Error);
                }

                if (report)
                {
                    reporter.Complete("nfs lines loaded");
                }

                var lines = result.NfsLines;
                this.result = null;
                return lines;
            }));
        }