context: namespace StockSharp.Xaml.Actipro
  {
  	using System;
  	using System.Collections.Generic;
  	using System.Collections.ObjectModel;
  	using System.Linq;
  	using System.Windows.Controls;
  	using System.Windows.Input;
  	using System.Windows;
  	using System.Text.RegularExpressions;
  	using System.Linq.Expressions;
  
  	using Ecng.Common;
  	using Ecng.Configuration;
  	using Ecng.Xaml;
  
  	using StockSharp.BusinessEntities;
  
  	using StockSharp.Localization;
  
  	/// <summary>
  	/// Editor of exchange boards.
  	/// </summary>
  	public partial class ExchangeEditor
  	{
  		private IExchangeInfoProvider Provider { get; set; }
  
  		/// <summary>
  		/// List of exchanges.
  		/// </summary>
  		public ObservableCollection<Exchange> Exchanges { get; private set; }
  
  		/// <summary>
  		/// List of time zones.
  		/// </summary>
  		public IEnumerable<TimeZoneInfo> TimeZones { get; private set; }
  
  		private ExchangeEditorViewModel ViewModel
  		{
  			get { return (ExchangeEditorViewModel)DataContext; }
  		}
  
  		private static readonly Regex _checkCodeRegex = new Regex("^[a-z0-9]{1,15}$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
  
  		private string _selectedExchangeName;
  
  		/// <summary>
  		/// The name of the selected exchange.
  		/// </summary>
  		public string SelectedExchangeName
  		{
  			get
  			{
  				return _selectedExchangeName;
  			}
  			private set
  			{
  				if (_selectedExchangeName == value)
  					return;
  
  				_selectedExchangeName = value;
  				SelectedExchangeChanged.SafeInvoke();
  			}
  		}
  
  		/// <summary>
  		/// The selected exchange change event .
  		/// </summary>
  		public event Action SelectedExchangeChanged;
  
  		/// <summary>
  		/// Initializes a new instance of the <see cref="ExchangeEditor"/>.
  		/// </summary>
  		public ExchangeEditor()
  		{
  			Provider = ConfigManager.GetService<IExchangeInfoProvider>();
  
  			Exchanges = new ObservableCollection<Exchange>(Provider.Exchanges);
  
  			TimeZones = TimeZoneInfo.GetSystemTimeZones()
  				.Concat(new[] { Exchange.Moex.TimeZoneInfo, Exchange.Test.TimeZoneInfo, Exchange.Ux.TimeZoneInfo })
  				.Distinct()
  				.ToArray();
  
  			InitializeComponent();
  
  			var vm = new ExchangeEditorViewModel(this, Provider);
  			vm.DataChanged += VmOnDataChanged;
  			DataContext = vm;
  
  			Provider.ExchangeAdded += ProviderOnExchangeAdded;
  		}
  
  		private void ProviderOnExchangeAdded(Exchange exchange)
  		{
  			Dispatcher.GuiAsync(() =>
  			{
  				//using (Dispatcher.DisableProcessing())
  				//{
  					//var selectedVal = CbExchangeName.SelectedValue as string ?? CbExchangeName.Text.Trim();
  					//Exchanges.Clear();
  
  					Exchanges.Add(exchange);
  
  					CbExchangeName.SelectedItem = exchange;
  					//if(!SelectedExchangeName.IsEmpty())
  					SetExchange(exchange.Name);
  				//}
  			});
  		}
  
  		/// <summary>
  		/// To set edited exchange.
  		/// </summary>
  		/// <param name="exchangeName">The code of edited exchange. The exchange for editing is loaded from <see cref="IExchangeInfoProvider"/>.</param>
  		public void SetExchange(string exchangeName)
  		{
  			if (exchangeName.IsEmpty())
  			{
  				ResetEditor();
  				return;
  			}
  
  			ViewModel.SetExchange(exchangeName);
  			SelectedExchangeName = ViewModel.ExchangeName;
  			CbExchangeName.SelectedItem = Exchanges.FirstOrDefault(e => e.Name == SelectedExchangeName);
  		}
  
  		internal Exchange GetSelectedExchange()
  		{
  			return ViewModel.Exchange;
  		}
  
  		private void AutoCompleteSelector_OnKeyDown(object sender, KeyEventArgs e)
  		{
  			((ComboBox)sender).IsDropDownOpen = true;
  		}
  
  		private void ExchangeSelector_OnSelectionChanged(object sender, EventArgs e)
  		{
  			var cb = (ComboBox)sender;
  			if (cb.IsDropDownOpen)
  				return;
  
  			var curText = cb.SelectedValue as string ?? cb.Text.Trim();
  
  			if (curText.IsEmpty())
  				return;
  
  			ViewModel.SetExchange(curText);
  			SelectedExchangeName = ViewModel.ExchangeName;
  		}
  
  		private void ResetEditor()
  		{
  			ViewModel.SetExchange(null);
  			SelectedExchangeName = null;
  			CbExchangeName.SelectedItem = null;
  			CbExchangeName.Text = string.Empty;
  		}
  
  		private void CodeBox_Loaded(object sender, RoutedEventArgs e)
  		{
  			var cb = (ComboBox)sender;
  			var tb = cb.Template.FindName("PART_EditableTextBox", cb) as TextBox;
  			if(tb == null)
  				return;
  
  			DataObject.AddPastingHandler(tb, CheckPasteFormat);
  
  			tb.CharacterCasing = CharacterCasing.Upper;
  			tb.PreviewTextInput += (o, args) =>
  			{
  				var newText = tb.Text + args.Text;
  				if(!_checkCodeRegex.IsMatch(newText))
  					args.Handled = true;
  			};
  		}
  
  		private static void CheckPasteFormat(object sender, DataObjectPastingEventArgs args)
  		{
  			var tb = (TextBox)sender;
  			var str = args.DataObject.GetData(typeof(string)) as string;
  			var newStr = tb.Text + str;
  			if (!_checkCodeRegex.IsMatch(newStr))
  				args.CancelCommand();
  		}
  
  		private void VmOnDataChanged()
  		{
  			ViewModel.SaveExchange();
  		}
  	}
  
  	class ExchangeEditorViewModel : ViewModelBase
  	{
  		#region commands definition
  
  		private ICommand _commandAddNewExchange;
  
  		public ICommand CommandAddNewExchange
  		{
  			get { return _commandAddNewExchange ?? (_commandAddNewExchange = new DelegateCommand(o => CmdAddNewExchange(), o => true)); }
  		}
  
  		#endregion
  
  		private Exchange _exchange;
  		private bool _isNew;
  		private string _exchangeRusName, _exchangeEngName, _saveErrorMessage;
  		private CountryCodes? _countryCode;
  		private TimeZoneInfo _exchangeTimeZone;
  
  		private readonly ExchangeEditor _editor;
  		private readonly IExchangeInfoProvider _provider;
  
  		private bool _updatingModel;
  
  		public event Action DataChanged;
  
  		private IExchangeInfoProvider Provider
  		{
  			get { return _provider; }
  		}
  
  		private IEnumerable<Exchange> Exchanges
  		{
  			get { return _editor.Exchanges; }
  		}
  
  		public ExchangeEditorViewModel(ExchangeEditor editor, IExchangeInfoProvider provider)
  		{
  
gt: 			if (editor == null)