public void BeginCreateDocument(TankInstance tank, IProgressScope progress, Action <CreateDocumentResult> callback)
        {
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                progress.ReportStatusMessage(this.L("stat_inspector", "status_analysing"));
                progress.ReportIsIndetermine();

                this.LogInfo("creating document from template file '{0}'", this.Filename);
                var document = this.LoadTemplate();
                progress.ReportProgress(0);

                var decendants = LogicalTreeHelperEx.GetDecendants <TextElement>(document).ToArray();
                var statVms    = new Dictionary <IStat, StatVM>();

                var completedDecendant = 0;

                foreach (var decendant in decendants)
                {
                    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                    {
                        var key = StatBehaviors.GetKey(decendant);
                        if (key != null)
                        {
                            var stat = StatsProviderManager.Instance.GetStat(key);
                            if (stat == null)
                            {
                                this.LogWarning("unknown stat: key='{0}'", key);
                                return;
                            }

                            var statVm = statVms.GetOrCreate(stat, () => new StatVM(stat, tank));

                            decendant.DataContext = statVm;

                            if (decendant is IAddChild)
                            {
                                this.ApplyTemplate(decendant);
                            }

                            ++completedDecendant;
                            progress.ReportProgress((double)completedDecendant / decendants.Length);
                        }
                    }), DispatcherPriority.Background);
                }

                Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                {
                    progress.ReportIsIndetermine();
                    callback(new CreateDocumentResult(document, statVms.Values));
                    progress.ReportProgress(1.0);
                }), DispatcherPriority.Background);
            }), DispatcherPriority.Background);
        }
        private void ApplyTemplate <TDecendant>(TDecendant decendant)
            where TDecendant : TextElement, IAddChild
        {
            var statTemplateKey = StatBehaviors.GetTemplateKey(decendant);

            if (statTemplateKey == null)
            {
                return;
            }

            var statTemplate = this.GetStatTemplate(statTemplateKey);

            if (statTemplate == null)
            {
                return;
            }

            StatBehaviors.ApplyTemplate(decendant, statTemplate);
        }