private static void OnBusyStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			var isBusy = (bool) e.NewValue;
			var wasBusy = (bool) e.OldValue;

			if (isBusy == wasBusy)
			{
				return;
			}

			var hostGridObject = (GetTargetVisual(d) ?? d);
			Debug.Assert(hostGridObject != null);

			var hostGrid = hostGridObject as Grid;
			if (hostGrid == null)
			{
				throw new InvalidCastException(
					string.Format(
						"The object being attached to must be of type {0}. Try embedding your visual inside a {0} control, and attaching the behavior to the {0} instead.",
						typeof(Grid).Name));
			}

			if (isBusy)
			{
				Debug.Assert(LogicalTreeHelper.FindLogicalNode(hostGrid, "BusyIndicator") == null);

				var dimBackground = GetDimBackground(d);
				var grid = new Grid
				           	{
				           		Name = "BusyIndicator",
				           		Opacity = 0.0
				           	};
				if (dimBackground)
				{
					grid.Cursor = Cursors.Wait;
					grid.ForceCursor = true;

					InputManager.Current.PreProcessInput += OnPreProcessInput;
				}
				grid.SetBinding(FrameworkElement.WidthProperty, new Binding("ActualWidth")
				                                                	{
				                                                		Source = hostGrid
				                                                	});
				grid.SetBinding(FrameworkElement.HeightProperty, new Binding("ActualHeight")
				                                                 	{
				                                                 		Source = hostGrid
				                                                 	});
				for (var i = 1; i <= 3; ++i)
				{
					grid.ColumnDefinitions.Add(new ColumnDefinition
					                           	{
					                           		Width = new GridLength(1, GridUnitType.Star)
					                           	});
					grid.RowDefinitions.Add(new RowDefinition
					                        	{
					                        		Height = new GridLength(1, GridUnitType.Star)
					                        	});
				}

				var viewbox = new Viewbox
				              	{
				              		HorizontalAlignment = HorizontalAlignment.Center,
				              		Stretch = Stretch.Uniform,
				              		StretchDirection = StretchDirection.Both,
				              		Child = new CircularProgressBar()
				              	};
				grid.SetCurrentValue(Panel.ZIndexProperty, 1000);
				grid.SetCurrentValue(Grid.RowSpanProperty, Math.Max(1, hostGrid.RowDefinitions.Count));
				grid.SetCurrentValue(Grid.ColumnSpanProperty, Math.Max(1, hostGrid.ColumnDefinitions.Count));
				if (GetAddMargins(d))
				{
					viewbox.SetCurrentValue(Grid.RowProperty, 1);
					viewbox.SetCurrentValue(Grid.ColumnProperty, 1);
				}
				else
				{
					viewbox.SetCurrentValue(Grid.RowSpanProperty, 3);
					viewbox.SetCurrentValue(Grid.ColumnSpanProperty, 3);
				}
				viewbox.SetCurrentValue(Panel.ZIndexProperty, 1);

				var dimmer = new Rectangle
				             	{
				             		Name = "Dimmer",
				             		Opacity = GetDimmerOpacity(d),
				             		Fill = GetDimmerBrush(d),
				             		Visibility = (dimBackground ? Visibility.Visible : Visibility.Collapsed)
				             	};
				dimmer.SetCurrentValue(Grid.RowSpanProperty, 3);
				dimmer.SetCurrentValue(Grid.ColumnSpanProperty, 3);
				dimmer.SetCurrentValue(Panel.ZIndexProperty, 0);
				grid.Children.Add(dimmer);

				grid.Children.Add(viewbox);

				grid.BeginAnimation(UIElement.OpacityProperty, new DoubleAnimation(1.0, GetDimTransitionDuration(d)));

				hostGrid.Children.Add(grid);
			}
			else
			{
				var grid = (Grid) LogicalTreeHelper.FindLogicalNode(hostGrid, "BusyIndicator");

				Debug.Assert(grid != null);

			    grid.Name = string.Empty;

			    var fadeOutAnimation = new DoubleAnimation(0.0, GetDimTransitionDuration(d));
			    fadeOutAnimation.Completed += (sender, args) => OnFadeOutAnimationCompleted(d, hostGrid, grid);
			    grid.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
			}
		}