void InitChannelControl(DeviceChannelControl channControl, ChannelDescription chan, SourcesArgs args, string proftoken = null) {
			//try to remove and clear all needed data
			if (channControl.Content is IDisposable) {
				var disp = channControl.Content as IDisposable;
				//try to remove content from disposables collection
				if(disposables.Contains(disp))
					disposables.Remove(disp);
				//dispose existing control
				disp.Dispose();
			}

			//Begin load channels section
			disposables.Add(SourceView.Load(chan, args.capabilities, args.nvtSession, args.odmSession, proftoken)
				.ObserveOnCurrentDispatcher()
				.Subscribe(sourceArgs => {
					if (sourceArgs.selectedProfile != null)
						channControl.Title = sourceArgs.channelDescr.videoSource.token + ": " + sourceArgs.selectedProfile.name;
					else
						channControl.Title = sourceArgs.channelDescr.videoSource.token;

					SourceView sourceView = new SourceView(container);
					disposables.Add(sourceView);

					sourceView.Init(sourceArgs);
					channControl.Content = sourceView;
				}, err => {
					ErrorView errorView = new ErrorView(err);
					disposables.Add(errorView);

					channControl.Content = errorView;
				}
			));
		}
		public void Init(DeviceDescriptionHolder devHolder, NvtSessionFactory sessionFactory, IUnityContainer container) {
			this.container = container;
			//Add device section (all devices must have this section)
			parent.Title = devHolder.Name;
			
			//Display progress bar
			devicePanel.Content = new ProgressView("Loading ...");

			//Begin load device section
			disposables.Add(SectionDevice.Load(devHolder, sessionFactory)
				.ObserveOnCurrentDispatcher()
				.Subscribe(
					args => {
						invtSession = args.nvtSession;

						SectionDevice devView = container.Resolve<SectionDevice>();
						disposables.Add(devView);
						devView.Init(args);
						devicePanel.Content = devView;

						//Load sections
						LoadSections(args);
					}, 
					err => {
						ErrorView errorView = new ErrorView(err);
						disposables.Add(errorView);

						devicePanel.Content = errorView;
					}
			));

		}
		void InitEngineControl(DeviceEngineControl engineControl, AnalyticsEngine engine, AnalyticsArgs args, string ctrltoken = null) {
			//try to remove and clear all needed data
			if (engineControl.Content is IDisposable) {
				var disp = engineControl.Content as IDisposable;
				//try to remove content from disposables collection
				if (disposables.Contains(disp))
					disposables.Remove(disp);
				//dispose existing control
				disp.Dispose();
			}

			//Begin load channels section
			disposables.Add(EnginesView.Load(engine, args.capabilities, args.nvtSession, args.odmSession, ctrltoken)
				.ObserveOnCurrentDispatcher()
				.Subscribe(ctrlArgs => {
					if (ctrlArgs.selectedEngineControl != null)
						engineControl.Title = ctrlArgs.engine.name + ": " + ctrlArgs.selectedEngineControl.name;
					else
						engineControl.Title = ctrlArgs.engine.name;

					EnginesView enginesView = new EnginesView(container);
					disposables.Add(enginesView);

					enginesView.Init(ctrlArgs);
					engineControl.Content = enginesView;
				}, err => {

					ErrorView errorView = new ErrorView(err);
					disposables.Add(errorView);

					engineControl.Content = errorView;
				}
			));
		}
		public static FSharpAsync<Result> Show(IUnityContainer container, Exception error) {
			var model = new Model(error);
			return container.StartViewActivity<Result>(context => {
				var view = new ErrorView(model, context);
				var presenter = container.Resolve<IViewPresenter>();
				presenter.ShowView(view);
			});
		}
        public static FSharpAsync <Result> Show(IUnityContainer container, Exception error)
        {
            var model = new Model(error);

            return(container.StartViewActivity <Result>(context => {
                var view = new ErrorView(model, context);
                var presenter = container.Resolve <IViewPresenter>();
                presenter.ShowView(view);
            }));
        }
		public void CreateView(DeviceViewArgs args, IUnityContainer container) {
			this.container = container;
			ProgressView progress = new ProgressView("Loading ..");
			if (this.content.Content is IDisposable) {
				var dis = this.content.Content as IDisposable;
				dis.Dispose();
			}
			this.content.Content = progress;

			loadingDisp.Add(Load(args.nvtSession, args.odmSession, args.capabilities)
				.ObserveOnCurrentDispatcher()
				.Subscribe(analyticsArgs => {
					SectionAnalytics analyticsView = new SectionAnalytics(container);
					disposables.Add(analyticsView);
					analyticsView.Init(analyticsArgs);
					this.content.Content = analyticsView;
				}, err => {
					ErrorView errorView = new ErrorView(err);
					disposables.Add(errorView);

					this.content.Content = errorView;
				}
			));
		}
		void LoadEngine(AnalyticsEngine engine, AnalyticsArgs args) {
			try {
				//Create engine control
				DeviceEngineControl engineControl = new DeviceEngineControl();

				//add control to controls dictionary
				//if (engine.token == null) {
				//    throw new ArgumentNullException("Analytics engine token can not be null");
				//}
				engineControls.Add(new KeyValuePair<string, DeviceEngineControl>(engine.token, engineControl));

				//Display progress bar
				ShowLoadingProgress(engineControl, engine.token);

				//add control to parent UI panel
				parent.Children.Add(engineControl);

				InitEngineControl(engineControl, engine, args);

				//subscribe to control changed event
				var subsToken = eventAggregator.GetEvent<ControlChangedEvent>().Subscribe(evargs => {
					if (evargs.engine.token == engine.token) {
						//reload channel with new profile
						InitEngineControl(engineControl, engine, args, evargs.controlToken);
					}
				}, false);
				disposables.Add(Disposable.Create(() => {
					eventAggregator.GetEvent<ControlChangedEvent>().Unsubscribe(subsToken);
				}));
			} catch (Exception err) {
				ErrorView errorView = new ErrorView(err);
				disposables.Add(errorView);
				parent.Children.Add(errorView); 
			}
		}