private void OnSearchChanged()
        {
            if (string.IsNullOrEmpty(this.Model.Search)) return;

            AddressInfo = HoohlShmoohl.AddressQuery.GetAddressInfo(this.Model.Search);

            if (AddressInfo != null)
            {
                if (!string.IsNullOrEmpty(AddressInfo.CountryName))
                    this.Model.Country = AddressInfo.CountryName;
                else
                    this.Model.Country = null;

                if (AddressInfo.City != null)
                {
                    this.Model.City = !string.IsNullOrEmpty(AddressInfo.City.Name) ? AddressInfo.City.Name : AddressInfo.City.FullName;

                    this.Model.CityType = AddressInfo.City.TypeName;
                }
                else
                {
                    this.Model.City = null;


                    this.Model.CityType = HoohlShmoohlModel.CityTypeDefault;
                }

                if (AddressInfo.Street != null)
                {
                    this.Model.Street = !string.IsNullOrEmpty(AddressInfo.Street.Name) ? AddressInfo.Street.Name : AddressInfo.Street.FullName;

                    this.Model.StreetType = AddressInfo.Street.TypeName;
                }
                else
                {
                    this.Model.Street = null;

                    this.Model.StreetType = HoohlShmoohlModel.StreetTypeDefault;
                }

                this.Model.DependedLocality = AddressInfo.DependedLocalityName;

                this.Model.PostalCode = AddressInfo.PostalCode;

                if (AddressInfo.AdministrativeArea != null)
                    this.Model.AdministrativeArea = AddressInfo.AdministrativeArea.FullName;
                else
                    this.Model.AdministrativeArea = null;

                if (AddressInfo.SubAdministrativeArea != null)
                    this.Model.SubAdministrativeArea = AddressInfo.SubAdministrativeArea.FullName;
                else
                    this.Model.SubAdministrativeArea = null;

            }

            ResetBuilding();
        }
        public static AddressInfo Parse(string jSon)
        {
            AddressInfo addr = new AddressInfo(AddressInfoContextType.Google);

            JObject jobj = JObject.Parse(jSon);

            IEnumerable<JProperty> props = jobj.Descendants().OfType<JProperty>();

            string s = GetPropValue(props, "name");

            if (s != null)
                addr.Name = s;

            s = GetPropValue(props, "address");

            if (s != null)
                addr.LatName = s;

            s = GetPropValue(props, "CountryName");

            if (s != null)
                addr.CountryName = s;

            s = GetPropValue(props, "LocalityName");

            if (s != null)
                addr.City = AddressInfo.ParseCityStatic(s);

            s = GetPropValue(props, "AdministrativeAreaName");

            if (s != null)
                addr.AdministrativeArea = AddressInfo.ParseAdministrativeArea(s);

            s = GetPropValue(props, "SubAdministrativeAreaName");

            if (s != null)
                addr.SubAdministrativeArea = AddressInfo.ParseSubAdministrativeArea(s);

            s = GetPropValue(props, "DependentLocalityName");

            if (s != null)
                addr.DependedLocalityName = s;

            s = GetPropValue(props, "ThoroughfareName");

            if (s != null)
                addr.Street = ParseStreet(s);

            if (s != null)
                addr.Building = ParseBuildingByStreet(s);

            if (addr.LatName != null)
                addr.PostalCode = ParsePostalCode(addr.LatName);

            return addr;
        }
        static void Parse(AddressInfo AddressInfo, string LocalityText)
        {
            //Россия, республика Башкортостан, Караидельский район, село Юрюзань

            //Россия, Челябинская область, Юрюзань

            //Россия, Челябинская область, станция Юрюзань

            //Россия, река Юрюзань

            //Россия, Свердловская область, Талицкий район, поселок Первухина

            string [] s = LocalityText.Split(',').Select(p=>p.Trim()).ToArray();

            AddressInfo.CountryName = s[0];

            if (s.Length > 1)
            {
                AddressInfo.AdministrativeAreaInfo admAreaInfo = AddressInfo.ParseAdministrativeArea(s[1]);

                if (admAreaInfo.Type != AddressAdministrativeAreaType.Undefined)
                    AddressInfo.AdministrativeArea = admAreaInfo;

                if (s.Length > 2)
                {
                    AddressInfo.SubAdministrativeAreaInfo subAdmAreaInfo = AddressInfo.ParseSubAdministrativeArea(s[2]);

                    if (subAdmAreaInfo.Type != AddressSubAdministrativeAreaType.Undefined)
                        AddressInfo.SubAdministrativeArea = subAdmAreaInfo;
                }

                int cityPos = -1;

                if (AddressInfo.AdministrativeArea == null)
                {
                    cityPos = 1;
                }
                else
                {
                    if (AddressInfo.SubAdministrativeArea == null)
                        cityPos = 2;
                    else
                        cityPos = 3;
                }

                if (cityPos != -1)
                {
                    AddressInfo.City = AddressInfo.ParseCityStatic(s[cityPos]);

                    if (cityPos + 1 < s.Length)
                        AddressInfo.Street = AddressInfo.ParseStreetStatic(s[cityPos + 1]);
                }
            }            
        }
        internal static void ParseBuilding(AddressInfo.BuildingInfo BuildingInfo)
        {
            if (!string.IsNullOrEmpty(BuildingInfo.FullName))
            {
                string[] r = new string[] { BuildingInfo.FullName };

                try
                {
                    SeparateBuildingParts(BuildingInfo.FullName);
                }
                catch { }

                AddressInfo.ParseBuilding(BuildingInfo, r[0], r.Skip(1).ToArray());
            }
        }
        public static AddressInfo Parse(string jSon)
        {
            AddressInfo addr = new AddressInfo(AddressInfoContextType.Yandex);

            JObject jobj = JObject.Parse(jSon);

            IEnumerable<JProperty> props = jobj.Descendants().OfType<JProperty>().Where(p => p.Name == "locations");

            JProperty loc = (JProperty)props.ElementAt(1);

            string text = (string)(loc.Descendants().OfType<JProperty>().First(p => p.Name == "text")).Value;

            string type = (string)(loc.Descendants().OfType<JProperty>().First(p => p.Name == "kind")).Value;

            string req = (string)(props.Descendants().OfType<JProperty>().First(p => p.Name == "request")).Value;//"request": "москва челябинская 10к1";

            Parse(addr, text);

            string[] buildings = loc.Descendants().OfType<JProperty>().Where(p => p.Name == "num").Select(p => (string)p.Value).ToArray();

            if (buildings.Length > 0)
            {
                if (addr.Street == null)
                    addr.Street = new AddressInfo.StreetInfo();

                addr.Street.Buildings = buildings.Select(p => new AddressInfo.BuildingInfo() { FullName = p }).ToArray();

                foreach (AddressInfo.BuildingInfo buildingInfo in addr.Street.Buildings)
                {
                    ParseBuilding(buildingInfo);
                }

                //Get last request part and suppose this is building number
                int i = req.LastIndexOf(" ");

                if (i != -1)
                {
                    string buildingNum = req.Substring(i).Trim();

                    addr.Building = addr.Street.Buildings.FirstOrDefault(p => p.FullName == buildingNum);
                }
            }

            return addr;
        }
 private void UpdateAddressInfo()
 {
     AddressInfo = HoohlShmoohl.AddressQuery.GetAddressInfo(GetSerachString());
 }
        private void OnStreetChanged()
        {
            this.ResetSubAdministrativeArea(false);

            this.ResetBuilding();

            this.ResetPostalCode();

            if (string.IsNullOrEmpty(this.Model.Street))
                return;

            if (AddressInfo == null)
                this.AddressInfo = AddressQuery.GetAddressInfo(this.Model.Street);
            else
                this.AddressInfo.ParseStreet(this.Model.Street, AddressQuery.LastQueryContext);

            this.Model.Street = !string.IsNullOrEmpty(AddressInfo.Street.Name) ? AddressInfo.Street.Name : AddressInfo.Street.FullName;

            this.Model.StreetType = !string.IsNullOrEmpty(AddressInfo.Street.TypeName) ? AddressInfo.Street.TypeName : HoohlShmoohlModel.StreetTypeDefault;

            if (AddressInfo.AdministrativeArea != null)
            {
                this.AddressInfo.AdministrativeArea = AddressInfo.AdministrativeArea;
                this.Model.AdministrativeArea = AddressInfo.AdministrativeArea.FullName;
            }

            if (AddressInfo.City != null)
            {
                this.AddressInfo.City = AddressInfo.City;
                this.Model.City = !string.IsNullOrEmpty(AddressInfo.City.Name) ? AddressInfo.City.Name : AddressInfo.City.FullName;
            }

            if (!string.IsNullOrEmpty(this.Model.City) && !string.IsNullOrEmpty(this.Model.Street))
            {
                AddressInfo addr = AddressQuery.GetAddressInfo(GetSerachString());

                if (addr.Street != null && addr.Street.Buildings != null)
                {
                    if (this.AddressInfo.Street != null)
                        this.AddressInfo.Street.Buildings = addr.Street.Buildings;
                }


                if (addr.AdministrativeArea != null)
                {
                    this.AddressInfo.AdministrativeArea = addr.AdministrativeArea;
                    this.Model.AdministrativeArea = addr.AdministrativeArea.FullName;
                }

                if (addr.SubAdministrativeArea != null)
                {
                    this.AddressInfo.SubAdministrativeArea = addr.SubAdministrativeArea;
                    this.Model.SubAdministrativeArea = addr.SubAdministrativeArea.FullName;
                }

                if (!string.IsNullOrEmpty(addr.DependedLocalityName))
                {
                    this.AddressInfo.DependedLocalityName = addr.DependedLocalityName;
                    this.Model.DependedLocality = addr.DependedLocalityName;
                }

                this.Model.PostalCode = addr.PostalCode;
                this.AddressInfo.PostalCode = addr.PostalCode;

                this.RefreshSearch();
            }
        }
        private void OnCityChanged()
        {
            this.ResetSubAdministrativeArea(false);

            ResetStreet();

            if (string.IsNullOrEmpty(this.Model.City))
                return;

            if (AddressInfo == null)
                this.AddressInfo = AddressQuery.GetAddressInfo(this.Model.City);
            else
                this.AddressInfo.ParseCity(this.Model.City);

            this.Model.City = !string.IsNullOrEmpty(AddressInfo.City.Name) ? AddressInfo.City.Name : AddressInfo.City.FullName;

            this.Model.CityType = !string.IsNullOrEmpty(AddressInfo.City.TypeName) ? AddressInfo.City.TypeName : HoohlShmoohlModel.CityTypeDefault;

            if (AddressInfo.AdministrativeArea != null)
                this.Model.AdministrativeArea = AddressInfo.AdministrativeArea.FullName;
            else
                this.Model.AdministrativeArea = null;

            if (!string.IsNullOrEmpty(this.Model.City))
            {
                AddressInfo addr = AddressQuery.GetAddressInfo(GetSerachString());

                if (addr.AdministrativeArea != null)
                {
                    this.AddressInfo.AdministrativeArea = addr.AdministrativeArea;
                    this.Model.AdministrativeArea = addr.AdministrativeArea.FullName;
                }
                else
                {
                    this.AddressInfo.AdministrativeArea = null;
                    this.Model.AdministrativeArea = null;
                }

                if (addr.SubAdministrativeArea != null)
                {
                    this.AddressInfo.SubAdministrativeArea = addr.SubAdministrativeArea;
                    this.Model.SubAdministrativeArea = addr.SubAdministrativeArea.FullName;
                }
                else
                {
                    this.AddressInfo.SubAdministrativeArea = null;
                    this.Model.SubAdministrativeArea = null;
                }

                this.AddressInfo.DependedLocalityName = addr.DependedLocalityName;
                this.Model.DependedLocality = addr.DependedLocalityName;

                this.Model.PostalCode = addr.PostalCode;
                this.AddressInfo.PostalCode = addr.PostalCode;

                this.RefreshSearch();
            }
        }
        private void OnCountryChanged()
        {
            ResetAdministrativeArea();

            if (!string.IsNullOrEmpty(this.Model.Country))
                this.AddressInfo = AddressQuery.GetAddressInfo(this.Model.Country);
        }