/// <summary>
        /// Handles asynchronous reverse geocoding completion.
        /// </summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The event arguments object.</param>
        private void _ClientReverseGeocodeCompleted(
            object sender,
            AsyncOperationCompletedEventArgs <ReverseGeocodeResponse> e)
        {
            // Do nothing if we get no result.
            if (e.Cancelled)
            {
                return;
            }

            // There is just no way to report about errors occurred, so just log it and do nothing.
            if (e.Error != null)
            {
                Logger.Warning(e.Error);

                return;
            }

            if (e.Result == null || e.Result.Address == null)
            {
                return;
            }

            // Translate received event into this.AsyncReverseGeocodeCompleted event.
            var address = new Address
            {
                FullAddress = e.Result.Address,
            };

            var eventArguments = new AsyncReverseGeocodedEventArgs(
                address,
                e.Result.Location,
                e.UserState);

            this.AsyncReverseGeocodeCompleted(this, eventArguments);
        }
 /// <summary>
 /// React on reverse geocoding completed.
 /// </summary>
 /// <param name="sender">Ignored.</param>
 /// <param name="e">Reverse geocoding completed event args.</param>
 private void _AsyncReverseGeocodeCompleted(object sender, AsyncReverseGeocodedEventArgs e)
 {
     if (_tokenList.Contains(e.UserState))
     {
         _tokenList.Remove(e.UserState);
         _mapControl.Dispatcher.BeginInvoke(new Action(delegate() { _ShowAddress(e); }),
             DispatcherPriority.Normal);
     }
 }
        /// <summary>
        /// Show popup with geocoded address.
        /// </summary>
        /// <param name="e">Reverse geocoding completed event args.</param>
        private void _ShowAddress(AsyncReverseGeocodedEventArgs e)
        {
            IGeocodable geocodable = _GetCurrentGeocodableObject(_mapControl);
            System.Windows.Point initialPoint = (System.Windows.Point)e.UserState;

            if (geocodable != null && _enabled && _mapControl.LastCursorPos.HasValue &&
                _mapControl.LastCursorPos.Value.X == initialPoint.X &&
                _mapControl.LastCursorPos.Value.Y == initialPoint.Y)
            {
                Point cursorPos = _mapControl.LastCursorPos.Value;

                _HideAddressPopups();

                Rect mapRect = new Rect(0, 0, _mapControl.map.ActualWidth, _mapControl.map.ActualHeight);

                Point objectLocation = _ConvertToScreenPos(e.Location);

                // Create canvas with dotted line.
                Canvas canvas = _CreateDottedLineCanvas(objectLocation, _mapControl.LastCursorPos.Value);

                // Get coordinates of top left of canvas.
                double canvasLeft = cursorPos.X;
                if (objectLocation.X < canvasLeft)
                    canvasLeft = objectLocation.X;

                double canvasTop = cursorPos.Y;
                if (objectLocation.Y < canvasTop)
                    canvasTop = objectLocation.Y;

                Rect canvasRect = new System.Windows.Rect(canvasLeft,
                    canvasTop, canvas.Width, canvas.Height);

                if (mapRect.Contains(canvasRect))
                {
                    canvasRect.Offset(0, -canvasRect.Height);

                    _dottedLinePopup = _CreatePopup(null, canvas, canvasRect);

                    Point popupPosition = _ConvertToScreenPos(e.Location);

                    // Show ellipse popup in position of reverse geocoded object.
                    Rect ellipseRect = new System.Windows.Rect(popupPosition.X - _sizeOfEllipse / 2,
                        popupPosition.Y - 3 * _sizeOfEllipse / 2, _popupWidth, _popupHeigth);
                    _ellipsePopup = _CreatePopup("MapPopupEllipseStyle", null, ellipseRect);

                    // Set cursor to popup. Cursor will be set on ellipse.
                    _ellipsePopup.Cursor = _mapControl.map.Cursor;

                    // Subscribe on mouse down to reraise mouse down on map.
                    _ellipsePopup.MouseDown += new MouseButtonEventHandler(_EllipsePopupMouseDown);

                    // Show address popup higher than IGeocodable object.
                    Rect addressRect = new System.Windows.Rect(popupPosition.X + _popupX,
                        popupPosition.Y - _popupY, _popupWidth, _popupHeigth);

                    string address = _GetAddressValue(e.Address);
                    _addressPopup = _CreatePopup("MapPopupStyle", address, addressRect);
                }
            }
        }
        /// <summary>
        /// Handles asynchronous reverse geocoding completion.
        /// </summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The event arguments object.</param>
        private void _ClientReverseGeocodeCompleted(
            object sender,
            AsyncOperationCompletedEventArgs<ReverseGeocodeResponse> e)
        {
            // Do nothing if we get no result.
            if (e.Cancelled)
            {
                return;
            }

            // There is just no way to report about errors occurred, so just log it and do nothing.
            if (e.Error != null)
            {
                Logger.Warning(e.Error);

                return;
            }

            if (e.Result == null || e.Result.Address == null)
            {
                return;
            }

            // Translate received event into this.AsyncReverseGeocodeCompleted event.
            var address = new Address
            {
                FullAddress = e.Result.Address,
            };

            var eventArguments = new AsyncReverseGeocodedEventArgs(
                address,
                e.Result.Location,
                e.UserState);
            this.AsyncReverseGeocodeCompleted(this, eventArguments);
        }