/// <summary>
        /// Starts import process.
        /// </summary>
        /// <param name="parentPage">Page requirest importing.</param>
        /// <param name="profile">Import profile.</param>
        /// <param name="defaultDate">Default date for default initialize imported objects.</param>
        /// <param name="dataProvider">Data provider.</param>
        private void _StartImportProcess(AppPages.Page parentPage,
                                         ImportProfile profile,
                                         DateTime defaultDate,
                                         IDataProvider dataProvider)
        {
            Debug.Assert(null != parentPage);   // created
            Debug.Assert(null != profile);      // created
            Debug.Assert(null != dataProvider); // creatde

            // reset state
            _importer = null;
            _geocoder = null;

            // subscribe to events
            App currentApp = App.Current;

            currentApp.MainWindow.Closed += new EventHandler(_MainWindow_Closed);

            // create background worker
            Debug.Assert(null == _worker); // only once
            SuspendBackgroundWorker worker = _CreateBackgroundWorker();

            // create internal objects
            var tracker       = new ImportCancelTracker(worker);
            var cancelTracker = new CancellationTracker(tracker);

            _informer = new ProgressInformer(parentPage, profile.Type, tracker);
            _informer.SetStatus("ImportLabelImporting");

            var infoTracker = new ProgressInfoTracker(worker,
                                                      _informer.ParentPage,
                                                      _informer.ObjectName,
                                                      _informer.ObjectsName);

            _importer = new Importer(infoTracker);

            if (PropertyHelpers.IsGeocodeSupported(profile.Type))
            {
                _geocoder = new Geocoder(infoTracker);
            }

            // set precondition
            string message = currentApp.GetString("ImportProcessStarted", _informer.ObjectName);

            currentApp.Messenger.AddInfo(message);

            // lock GUI
            currentApp.UIManager.Lock(true);

            // run worker
            var parameters = new ProcessParams(profile,
                                               defaultDate,
                                               dataProvider,
                                               cancelTracker,
                                               infoTracker);

            worker.RunWorkerAsync(parameters);
            _worker = worker;
        }
        /// <summary>
        /// Creates background worker.
        /// </summary>
        /// <returns>Created background worker.</returns>
        private SuspendBackgroundWorker _CreateBackgroundWorker()
        {
            var worker = new SuspendBackgroundWorker();

            worker.WorkerReportsProgress      = true;
            worker.WorkerSupportsCancellation = true;

            // subscribe to worker's events
            worker.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
            worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
            worker.DoWork          += new DoWorkEventHandler(_worker_DoWork);

            return(worker);
        }
        /// <summary>
        /// Worker completed event handler.
        /// Parses results.
        /// </summary>
        /// <param name="sender">Background worker.</param>
        /// <param name="e">Run worker completed event arguments.</param>
        private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var bw = sender as BackgroundWorker;
            Debug.Assert(null != bw); // supported object

            // stop events
            bw.DoWork -= _worker_DoWork;
            bw.ProgressChanged -= _worker_ProgressChanged;
            bw.RunWorkerCompleted -= _worker_RunWorkerCompleted;

            // free resources
            bw.Dispose();
            _worker = null;

            // parse operation results
            Storage storage = _ParseResults(e.Error, e.Cancelled);

            // fire import completed
            if (null != ImportCompleted)
            {
                Debug.Assert(null != storage); // inited
                var events = new ImportCompletedEventArgs(storage.UpdatedObjects, e.Cancelled);
                ImportCompleted(this, events);
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Creates a new instance of the <c>ImportCancelTracker</c> class.
        /// </summary>
        /// <param name="worker">Background worker.</param>
        public ImportCancelTracker(SuspendBackgroundWorker worker)
        {
            Debug.Assert(null != worker); // created
            _worker = worker;
        }
        /// <summary>
        /// Starts import process.
        /// </summary>
        /// <param name="parentPage">Page requirest importing.</param>
        /// <param name="profile">Import profile.</param>
        /// <param name="defaultDate">Default date for default initialize imported objects.</param>
        /// <param name="dataProvider">Data provider.</param>
        private void _StartImportProcess(AppPages.Page parentPage,
                                         ImportProfile profile,
                                         DateTime defaultDate,
                                         IDataProvider dataProvider)
        {
            Debug.Assert(null != parentPage); // created
            Debug.Assert(null != profile); // created
            Debug.Assert(null != dataProvider); // creatde

            // reset state
            _importer = null;
            _geocoder = null;

            // subscribe to events
            App currentApp = App.Current;
            currentApp.MainWindow.Closed += new EventHandler(_MainWindow_Closed);

            // create background worker
            Debug.Assert(null == _worker); // only once
            SuspendBackgroundWorker worker = _CreateBackgroundWorker();

            // create internal objects
            var tracker = new ImportCancelTracker(worker);
            var cancelTracker = new CancellationTracker(tracker);
            _informer = new ProgressInformer(parentPage, profile.Type, tracker);
            _informer.SetStatus("ImportLabelImporting");

            var infoTracker = new ProgressInfoTracker(worker,
                                                      _informer.ParentPage,
                                                      _informer.ObjectName,
                                                      _informer.ObjectsName);
            _importer = new Importer(infoTracker);

            if (PropertyHelpers.IsGeocodeSupported(profile.Type))
            {
                _geocoder = new Geocoder(infoTracker);
            }

            // set precondition
            string message = currentApp.GetString("ImportProcessStarted", _informer.ObjectName);
            currentApp.Messenger.AddInfo(message);

            // lock GUI
            currentApp.UIManager.Lock(true);

            // run worker
            var parameters = new ProcessParams(profile,
                                               defaultDate,
                                               dataProvider,
                                               cancelTracker,
                                               infoTracker);
            worker.RunWorkerAsync(parameters);
            _worker = worker;
        }
        /// <summary>
        /// Creates background worker.
        /// </summary>
        /// <returns>Created background worker.</returns>
        private SuspendBackgroundWorker _CreateBackgroundWorker()
        {
            var worker = new SuspendBackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;

            // subscribe to worker's events
            worker.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
            worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
            worker.DoWork += new DoWorkEventHandler(_worker_DoWork);

            return worker;
        }
 /// <summary>
 /// Stops asynchronous import.
 /// </summary>
 private void _Abort()
 {
     if (_worker != null)
     {
         if (_worker.IsBusy)
             _worker.CancelAsync();
         _worker = null;
     }
 }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Deletes created cursors.
        /// </summary>
        public void Dispose()
        {
            // unsubscribe to events
            if (null != App.Current.MainWindow)
                App.Current.MainWindow.Closed -= _MainWindow_Closed;

            if (null != _informer)
                _informer.Dispose();

            _informer = null;
            _importer = null;
            _geocoder = null;
            _worker = null;
        }
 ///////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////
 /// <summary>
 /// Creates a new instance of the <c>ImportCancelTracker</c> class.
 /// </summary>
 /// <param name="worker">Background worker.</param>
 public ImportCancelTracker(SuspendBackgroundWorker worker)
 {
     Debug.Assert(null != worker); // created
     _worker = worker;
 }