public void Step3_Compare(
			AeroNavigationBar.HistoryInfo History,
			LinkImage[] Source,
			ComparisionInfo[] Comparision,
			ComparisionValue[] Values)
		{
			History.AddFrame(
				delegate
				{
					var Current = Comparision.Where(k => k.WaitingForUser && k.Value == null).FirstOrDefault();

					var MatrixButton = new TextButtonControl
					{
						Text = ">> Show the matrix",
						Width = 400,
						Height = 40,
					}.AttachContainerTo(this).MoveContainerTo(350, 100 + 40 * 10);

					MatrixButton.Content.FontSize = 20;

					var MatrixButton_bg = MatrixButton.Background.ToAnimatedOpacity();


					MatrixButton.Background.Fill = Brushes.White;
					MatrixButton_bg.Opacity = 0;

					MatrixButton.Overlay.MouseEnter +=
						delegate { MatrixButton_bg.Opacity = 1; };


					MatrixButton.Overlay.MouseLeave +=
						delegate { MatrixButton_bg.Opacity = 0; };


					MatrixButton.Click +=
						delegate
						{
							Step4_ShowMatrix(History, Source, Comparision, Values);
						};

					if (Current == null)
					{
						this.Title.Text = "You are done!";

						var MistakeMatrixButton = new TextButtonControl
						{
							Text = ">> Show the mistake matrix",
							Width = 400,
							Height = 40,
						}.AttachContainerTo(this).MoveContainerTo(350, 100 + 40 * 9);

						MistakeMatrixButton.Content.FontSize = 20;

						var MistakeMatrixButton_bg = MistakeMatrixButton.Background.ToAnimatedOpacity();


						MistakeMatrixButton.Background.Fill = Brushes.White;
						MistakeMatrixButton_bg.Opacity = 0;

						MistakeMatrixButton.Overlay.MouseEnter +=
							delegate { MistakeMatrixButton_bg.Opacity = 1; };


						MistakeMatrixButton.Overlay.MouseLeave +=
							delegate { MistakeMatrixButton_bg.Opacity = 0; };


						MistakeMatrixButton.Click +=
							delegate
							{
								Step5_ShowMistakeMatrix(History, Source, Comparision, Values);
							};

						var RestartButton = new TextButtonControl
						{
							Text = ">> Restart",
							Width = 400,
							Height = 40,
						}.AttachContainerTo(this).MoveContainerTo(350, 100 + 40 * 11);

						RestartButton.Content.FontSize = 20;

						var RestartButton_bg = RestartButton.Background.ToAnimatedOpacity();


						RestartButton.Background.Fill = Brushes.White;
						RestartButton_bg.Opacity = 0;

						RestartButton.Overlay.MouseEnter +=
							delegate { RestartButton_bg.Opacity = 1; };


						RestartButton.Overlay.MouseLeave +=
							delegate { RestartButton_bg.Opacity = 0; };


						RestartButton.Click +=
							delegate
							{
								Step1_ChooseImageSet(History, DefaultDataSets);
							};


						// step 1 - each row gets a geomean and is seen as a new column
						var GeomeanColumn = Enumerable.Range(0, Source.Length).ToArray(
							i => Comparision.Where(k => k.Y == i).Geomean(k => k.GetCurrentValue())
						);

						// step 2 - geomean gets a sum
						var GeomeanColumnSum = GeomeanColumn.Sum();

						// step 3 - each column gets a sum
						//var SumRow = Enumerable.Range(0, Source.Length).ToArray(
						//    i => Comparision.Where(k => k.X == i).Sum(k => k.GetCurrentValue())
						//);

						// step 4 - calculate the weights for each row
						var GeomeanWeightColumn = GeomeanColumn.ToArray(k => k / GeomeanColumnSum);

						// step 5 - calculate max selfvalue
						//var MaxSelfValue = SumRow.MatrixMultiplication(GeomeanWeightColumn);


						var Sorted = GeomeanWeightColumn.
							Select((weight, i) => new { weight = 1 - weight, i, Source = Source[i] }).
							OrderBy(k => k.weight).Select((k, i) => new { k.weight, i, k.Source }).ToArray();

						var DisposeSorted = new List<Action>();


						foreach (var v in Sorted)
						{
							var k = v;

							var zoom = (0.5 + v.weight * 0.5) / 2.0;

							Console.WriteLine(new { v.i, zoom, v.weight }.ToString());

							v.Source.ClickEnabled = false;
							v.Source.SizeTo(zoom);

							var k_x = 500 + Convert.ToInt32(-30 * v.i * zoom) * v.i;
							var k_y = 100 + Convert.ToInt32(70 * v.i * zoom);

							v.Source.MoveContainerTo(k_x, k_y);
							v.Source.AttachContainerTo(this);


							var k_Text = new TextBox
							{
								Background = Brushes.Black,
								Width = 60,
								Height = 22,
								Foreground = Brushes.Yellow,
								BorderThickness = new Thickness(0),
								Text = "" + v.weight,
								IsReadOnly = true
							};


							bool MouseEnterDisabled = false;
							MouseEventHandler MouseEnter =
								delegate
								{
									// cannot remove event from MouseEnter yet
									if (MouseEnterDisabled)
										return;

									k.Source.BringContainerToFront();
									k_Text.BringToFront();
								};

							k.Source.Overlay.MouseEnter += MouseEnter;

							k_Text.MoveTo(k_x - 30, k_y - 11).AttachTo(this);

							DisposeSorted.Add(
								delegate
								{
									k.Source.OrphanizeContainer();

									k_Text.Orphanize();

									MouseEnterDisabled = true;
								}
							);
						}

						MatrixButton.BringContainerToFront();
						MistakeMatrixButton.BringContainerToFront();


						return delegate
						{
							this.Title.Text = "...";

							DisposeSorted.ToArray().ForEach(h => h());


							MatrixButton.OrphanizeContainer();
							MistakeMatrixButton.OrphanizeContainer();
							RestartButton.OrphanizeContainer();
						};


					}
					else
					{
						var More = Comparision.Count(k => k.WaitingForUser && k.Value == null);

						this.Title.Text = "Compare images #" + (1 + Current.X) + " above and #" + (1 + Current.Y) + " below. You have " + More + " image pairs to compare...";


						var X = Source[Current.X];
						var Y = Source[Current.Y];

						X.ClickEnabled = false;
						X.SizeTo(0.5).MoveContainerTo(100, 100).AttachContainerTo(this);

						Y.ClickEnabled = false;
						Y.SizeTo(0.5).MoveContainerTo(100, 300).AttachContainerTo(this);

						#region Options
						var Options = Values.Select(
							(Value, Index) =>
							{
								var o7 = new TextButtonControl
								{
									Text = "above is " + Value.Name + " than below (" + Value.ToString() + ")",
									Width = 400,
									Height = 40,
								}.AttachContainerTo(this).MoveContainerTo(350, 100 + 40 * Index);

								o7.Content.FontSize = 20;

								var o7bg = o7.Background.ToAnimatedOpacity();


								o7.Background.Fill = Brushes.White;
								o7bg.Opacity = 0;

								o7.Overlay.MouseEnter +=
									delegate { o7bg.Opacity = 1; };


								o7.Overlay.MouseLeave +=
									delegate { o7bg.Opacity = 0; };


								o7.Click +=
									delegate
									{
										var NewComparision = Comparision.ToArray(
											o =>
											{
												var n = new ComparisionInfo
												{
													WaitingForUser = o.WaitingForUser,
													Value = o.Value,
													X = o.X,
													Y = o.Y
												};

												if (o == Current)
												{
													n.Value = Value;
												}

												if (o.Y == Current.X)
													if (o.X == Current.Y)
													{
														if (Value.InverseOf != null)
															n.Value = Value.InverseOf;
														else
														{
															var Inverse = Values.SingleOrDefault(k => k.InverseOf == Value);

															if (Inverse == null)
																n.Value = Value;
															else
																n.Value = Inverse;
														}
													}

												return n;
											}
										);

										Step3_Compare(History, Source, NewComparision, Values);
									};

								return o7;
							}
						).ToArray();
						#endregion

						return delegate
						{
							this.Title.Text = "...";

							X.OrphanizeContainer();
							Y.OrphanizeContainer();

							Options.ForEach(k => k.OrphanizeContainer());
							MatrixButton.OrphanizeContainer();
						};
					}



				}
			);
		}
		public AvalonQueryExampleCanvas()
		{
			CheckIsPanel();

			Width = DefaultWidth;
			Height = DefaultHeight;

			#region Gradient
			for (int i = 0; i < DefaultHeight; i += 4)
			{
				new Rectangle
				{
					Fill = ((uint)(0xff00007F + Convert.ToInt32(128 * i / DefaultHeight))).ToSolidColorBrush(),
					Width = DefaultWidth,
					Height = 5,
				}.MoveTo(0, i).AttachTo(this);
			}
			#endregion

			new Image
			{
				Source = "assets/FlashAvalonQueryExample/labels.png".ToSource()
			}.MoveTo(0, 0).AttachTo(this);

			//var FaciconService = "http://www.google.com/s2/favicons?domain=";

			// http://www.google.com/s2/favicons?domain=wordpress.com
			var KnownDomains = "63/155262375_104aee1bb0, 3183/2825405970_a1469cd673, 2336/2454679206_de5176b827, 3178/2825551196_6548ff54b9";
			var KnownFilter = "31";

			Func<Brush> Color_Inactive = () => 0xffc0c0c0.ToSolidColorBrush();
			Func<Brush> Color_Active = () => 0xffffffff.ToSolidColorBrush();
			Func<Brush> Color_Error = () => 0xffffff80.ToSolidColorBrush();

			var KnownDomainsInputHeight = 100;

			var KnownDomainsInput = new TextBox
			{
				AcceptsReturn = true,
				FontSize = 15,
				Text = KnownDomains,
				BorderThickness = new Thickness(0),
				//Foreground = 0xffffffff.ToSolidColorBrush(),
				Background = Color_Inactive(),
				Width = 400,
				Height = KnownDomainsInputHeight,
				TextWrapping = TextWrapping.Wrap
			}.MoveTo(32, 32).AttachTo(this);

			KnownDomainsInput.Orphanize();
			KnownDomainsInput.AttachTo(this);

			Action<TextBox> ApplyActiveColor =
				e =>
				{
					e.GotFocus +=
						delegate
						{
							e.Background = Color_Active();
						};


					e.LostFocus +=
						delegate
						{
							e.Background = Color_Inactive();
						};
				};

			ApplyActiveColor(KnownDomainsInput);

			var FilterInputHeight = 22;

			var FilterInput = new TextBox
			{
				FontSize = 15,
				Text = KnownFilter,
				BorderThickness = new Thickness(0),
				//Foreground = 0xffffffff.ToSolidColorBrush(),
				Background = Color_Inactive(),
				Width = 400,
				Height = FilterInputHeight,
			}.MoveTo(32, 32 + KnownDomainsInputHeight + 4).AttachTo(this);

			ApplyActiveColor(FilterInput);


			var AnyInputChangedBefore = new List<Action>();

			Action AnyInputChanged =
				delegate
				{
					AnyInputChangedBefore.Do();
					AnyInputChangedBefore.Clear();

					var query = from k in KnownDomainsInput.Text.Split(',')
								let t = k.Trim()
								where t.Contains(FilterInput.Text)
								orderby t
								select t;


					query.ForEach(
						(k, i) =>
						{
							// http://static.flickr.com/63/155262375_104aee1bb0.jpg
							var src = "http://static.flickr.com/" + k + "_s.jpg";

							var y = 32 + KnownDomainsInputHeight + 4 + FilterInputHeight + 4 + i * 80;

							var bg = new Rectangle
							{
								Fill = Color_Inactive(),
								Width = 400,
								Height = 26

							}
							.MoveTo(32, y + 20).AttachTo(this);

							var img_shadow = new Rectangle
							{
								Fill = 0xff000000.ToSolidColorBrush(),
								Opacity = 0.3,
								Width = 75,
								Height = 75
							}
							.MoveTo(32 + 2 + 3, y + 2 + 3).AttachTo(this);

							var img = new Image
							{
								Width = 75,
								Height = 75
							}
							.MoveTo(32 + 2, y + 2).AttachTo(this);


							var text = new TextBox
							{
								IsReadOnly = true,
								Text = (i + 1) + ". " + src,
								Width = 400 - 88,
								Height = 20,
								BorderThickness = new Thickness(0),
								Foreground = 0xff0000ff.ToSolidColorBrush(),
								Background = 0xffffffff.ToSolidColorBrush()
							}.MoveTo(32 + 84, y + 22).AttachTo(this);




							var src_uri = new BitmapImage();

							src_uri.DownloadCompleted +=
								delegate
								{
									text.Foreground = 0xff000000.ToSolidColorBrush();
									//bg.Fill = Color_Active();
								};

							src_uri.DownloadFailed +=
								delegate
								{
									text.Text += " failed...";
									text.Foreground = 0xffff0000.ToSolidColorBrush();
									//bg.Fill = Color_Error();
								};

							src_uri.BeginInit();
                            Console.WriteLine(src);
							src_uri.UriSource = new Uri(src);
							src_uri.EndInit();


							img.Source = src_uri;

							text.Background = Color_Inactive();
							bg.Opacity = 0.3;

							text.GotFocus +=
								delegate
								{
									text.Background = Color_Active();
									bg.Opacity = 1;
								};

							text.LostFocus +=
								delegate
								{
									text.Background = Color_Inactive();
									bg.Opacity = 0.3;
								};

							AnyInputChangedBefore.Add(
								delegate
								{
									bg.Orphanize();
									img.Orphanize();
									text.Orphanize();
									img_shadow.Orphanize();
								}
							);

							//ResultOutput.AppendTextLine((i + 1) + ". " + k + " " + src);
						}
					);
					// we need to validate CNAMEs



				};

			#region attach AnyInputChanged
			KnownDomainsInput.TextChanged +=
				delegate
				{
					AnyInputChanged();
				};

			FilterInput.TextChanged +=
				delegate
				{
					AnyInputChanged();
				};

			AnyInputChanged();

			#endregion

		}