public override void Log(params Object[] items)
		{
			StringBuilder sbFullLine = new StringBuilder();

			DockPanel dp = new DockPanel();

			SolidColorBrush background = Brushes.Transparent;
			SolidColorBrush foreground = Brushes.Transparent;
			foreach (Object item in items)
			{
				if (item is Color)
				{
					foreground = new SolidColorBrush((Color)item);
				}
				else if (item is String)
				{
					if (!String.IsNullOrEmpty((String)item))
					{
						Tuple<List<UIElement>, String> itemTuple = GenerateElements((String)item, background, foreground);
						foreach (UIElement elem in itemTuple.Item1)
							dp.Children.Add(elem);

						sbFullLine.Append(itemTuple.Item2);
					}
				}
				else if (item is int)
				{
					Tuple<List<UIElement>, String> itemTuple = GenerateElements((int)item, background, foreground);
					foreach (UIElement elem in itemTuple.Item1)
						dp.Children.Add(elem);

					sbFullLine.Append(itemTuple.Item2);
				}
				else if (item is DominionBase.Players.Player)
				{
					Tuple<List<UIElement>, String> itemTuple = GenerateElements((DominionBase.Players.Player)item, background, foreground);
					foreach (UIElement elem in itemTuple.Item1)
						dp.Children.Add(elem);

					sbFullLine.Append(itemTuple.Item2);
				}
				else if (item is DominionBase.Players.PlayerCollection)
				{
					Boolean isFirstItem = true;
					foreach (DominionBase.Players.Player player in (DominionBase.Players.PlayerCollection)item)
					{
						Tuple<List<UIElement>, String> itemTuple;
						if (!isFirstItem)
						{
							itemTuple = GenerateElements(", ", background, foreground);
							foreach (UIElement elem in itemTuple.Item1)
								dp.Children.Add(elem);

							sbFullLine.Append(itemTuple.Item2);
						}

						itemTuple = GenerateElements(player, background, foreground);
						foreach (UIElement elem in itemTuple.Item1)
							dp.Children.Add(elem);

						sbFullLine.Append(itemTuple.Item2);

						isFirstItem = false;
					}

				}
				else if (item is DominionBase.Visual.VisualPlayer)
				{
					Tuple<List<UIElement>, String> itemTuple = GenerateElements((DominionBase.Visual.VisualPlayer)item, background, foreground);
					foreach (UIElement elem in itemTuple.Item1)
						dp.Children.Add(elem);

					sbFullLine.Append(itemTuple.Item2);
				}
				else if (item is DominionBase.ICard)
				{
					Tuple<List<UIElement>, String> itemTuple = GenerateElements((DominionBase.ICard)item, background, foreground);
					foreach (UIElement elem in itemTuple.Item1)
						dp.Children.Add(elem);

					sbFullLine.Append(itemTuple.Item2);
				}
				else if (item is IEnumerable<DominionBase.ICard>)
				{
					Tuple<List<UIElement>, String> itemTuple = GenerateElements((IEnumerable<DominionBase.ICard>)item, background, foreground);
					foreach (UIElement elem in itemTuple.Item1)
						dp.Children.Add(elem);

					sbFullLine.Append(itemTuple.Item2);
				}
			}

			TextBlock g = new TextBlock();
			g.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			g.Background = background;
			DockPanel.SetDock(g, Dock.Left);
			dp.Children.Add(g);

			Utilities.Log(this.LogFile, sbFullLine.ToString());
			spArea.Children.Add(dp);
			dp.BringIntoView();
		}
		public override void Log(DominionBase.Visual.VisualPlayer player, List<Brush> playerBrushes, params Object[] items)
		{
			StringBuilder sbFullLine = new StringBuilder();

			TreeViewItem tvi = new TreeViewItem() { Margin = new Thickness(0), Padding = new Thickness(0) };
			DockPanel dp = new DockPanel();
			dp.LastChildFill = true;
			sbFullLine.Append(this.DepthPrefix);
			TreeView tvActive = tvArea;

			DominionBase.Visual.VisualPlayer lineVisualPlayer = null;

			foreach (Object item in items)
			{
				if (item is String)
				{
					foreach (UIElement elem in Utilities.RenderText((String)item, NET_WPF.RenderSize.Tiny, true))
					{
						if (elem is TextBlock)
							((TextBlock)elem).VerticalAlignment = System.Windows.VerticalAlignment.Center;
						DockPanel.SetDock(elem, Dock.Left);
						dp.Children.Add(elem);
					}

					sbFullLine.Append(item);
				}
				else if (item is DominionBase.Currency)
				{
					foreach (UIElement elem in Utilities.RenderText(((DominionBase.Currency)item).ToStringInline(), NET_WPF.RenderSize.Tiny, true))
					{
						if (elem is TextBlock)
							((TextBlock)elem).VerticalAlignment = System.Windows.VerticalAlignment.Center;
						DockPanel.SetDock(elem, Dock.Left);
						dp.Children.Add(elem);
					}

					sbFullLine.Append(Utilities.RenderText(((DominionBase.Currency)item).ToStringInline()));
				}
				else if (item is DominionBase.Currencies.CurrencyBase)
				{
					foreach (UIElement elem in Utilities.RenderText(((DominionBase.Currencies.CurrencyBase)item).ToString(), NET_WPF.RenderSize.Tiny, true))
					{
						if (elem is TextBlock)
							((TextBlock)elem).VerticalAlignment = System.Windows.VerticalAlignment.Center;
						DockPanel.SetDock(elem, Dock.Left);
						dp.Children.Add(elem);
					}

					sbFullLine.Append(Utilities.RenderText(((DominionBase.Currencies.CurrencyBase)item).ToString()));
				}
				else if (item is DominionBase.Players.Player)
				{
					lineVisualPlayer = new DominionBase.Visual.VisualPlayer((DominionBase.Players.Player)item);

					TextBlock tbLine = new TextBlock();
					tbLine.Text = lineVisualPlayer.Name;
					tbLine.VerticalAlignment = System.Windows.VerticalAlignment.Center;
					if (lineVisualPlayer.PlayerUniqueId != this.Player.PlayerUniqueId)
						tbLine.FontWeight = FontWeights.Bold;

					DockPanel.SetDock(tbLine, Dock.Left);
					dp.Children.Add(tbLine);

					sbFullLine.Append(lineVisualPlayer.Name);
				}
				else if (item is DominionBase.Visual.VisualPlayer)
				{
					lineVisualPlayer = (DominionBase.Visual.VisualPlayer)item;

					TextBlock tbLine = new TextBlock();
					tbLine.Text = lineVisualPlayer.Name;
					tbLine.VerticalAlignment = System.Windows.VerticalAlignment.Center;
					if (lineVisualPlayer.PlayerUniqueId != this.Player.PlayerUniqueId)
						tbLine.FontWeight = FontWeights.Bold;

					DockPanel.SetDock(tbLine, Dock.Left);
					dp.Children.Add(tbLine);

					sbFullLine.Append(lineVisualPlayer.Name);
				}
				else if (item is DominionBase.ICard)
				{
					ucCardIcon icon = CardIconUtilities.CreateCardIcon((DominionBase.ICard)item);
					icon.VerticalAlignment = System.Windows.VerticalAlignment.Center;
					DockPanel.SetDock(icon, Dock.Left);
					dp.Children.Add(icon);

					sbFullLine.Append(((DominionBase.ICard)item).Name);
				}
				else if (item is IEnumerable<DominionBase.ICard>)
				{
					foreach (ucCardIcon icon in CardIconUtilities.CreateCardIcons((IEnumerable<DominionBase.ICard>)item))
					{
						icon.VerticalAlignment = System.Windows.VerticalAlignment.Center;
						DockPanel.SetDock(icon, Dock.Left);
						dp.Children.Add(icon);

						if (icon.Count == 1)
							sbFullLine.Append(icon.Card.Name);
						else
							sbFullLine.AppendFormat("{0}x {1}", icon.Count, icon.Card.Name);

						TextBlock tbLine = new TextBlock();
						tbLine.Text = ", ";
						tbLine.VerticalAlignment = System.Windows.VerticalAlignment.Center;
						DockPanel.SetDock(tbLine, Dock.Left);
						dp.Children.Add(tbLine);

						sbFullLine.Append(", ");
					}

					if (((IEnumerable<DominionBase.ICard>)item).Count() > 0)
					{
						dp.Children.RemoveAt(dp.Children.Count - 1);
						sbFullLine = sbFullLine.Remove(sbFullLine.Length - 2, 2);
					}
				}
				else if (item is IEnumerable<DominionBase.Token>)
				{
					int count = ((IEnumerable<DominionBase.Token>)item).Count();
					String displayString = ((IEnumerable<DominionBase.Token>)item).First().LongDisplayString;
					if (count != 1)
						displayString = String.Format("{0}x {1}", count, displayString);

					TextBlock tbLine = new TextBlock();
					tbLine.Text = displayString;
					tbLine.VerticalAlignment = System.Windows.VerticalAlignment.Center;

					DockPanel.SetDock(tbLine, Dock.Left);
					dp.Children.Add(tbLine);

					sbFullLine.Append(displayString);
				}
			}

			if (tvi.Background != null && dp.Children.Count > 0)
			{
				if (dp.Children.Count == 1)
				{
					if (dp.Children[0] is TextBlock)
						((TextBlock)dp.Children[0]).Padding = new Thickness(2, 1, 2, 1);
					else if (dp.Children[0] is ucCardIcon)
						((ucCardIcon)dp.Children[0]).Padding = new Thickness(2, 1, 2, 1);
				}
				else
				{
					if (dp.Children[0] is TextBlock)
						((TextBlock)dp.Children[0]).Padding = new Thickness(2, 1, 0, 1);
					else if (dp.Children[0] is ucCardIcon)
						((ucCardIcon)dp.Children[0]).Padding = new Thickness(2, 1, 0, 1);
					if (dp.Children[dp.Children.Count - 1] is TextBlock)
						((TextBlock)dp.Children[dp.Children.Count - 1]).Padding = new Thickness(0, 1, 2, 1);
					else if (dp.Children[dp.Children.Count - 1] is ucCardIcon)
						((ucCardIcon)dp.Children[dp.Children.Count - 1]).Padding = new Thickness(0, 1, 2, 1);
				}
			}

			// Need something to fill the remaining gap
			Grid g = new Grid();
			g.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
			dp.Children.Add(g);

			Utilities.Log(this.LogFile, sbFullLine.ToString());

			int level = this._CurrentInset;
			ItemCollection lItems = tvArea.Items;
			TreeViewItem tviParent = null;
			while (level > 0)
			{
				if (lItems[lItems.Count - 1] is TreeViewItem)
					tviParent = (TreeViewItem)lItems[lItems.Count - 1];
				else if (lItems[lItems.Count - 1] is TreeView)
					tviParent = (TreeViewItem)((TreeView)lItems[lItems.Count - 1]).Items[((TreeView)lItems[lItems.Count - 1]).Items.Count - 1];
				tviParent.IsExpanded = true;
				lItems = tviParent.Items;
				level--;
			}

			if (player.PlayerUniqueId == this.Player.PlayerUniqueId)
			{
				lItems.Add(tvi);
				tvi.Header = dp;
				tvi.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			}
			else
			{
				if (lItems.Count == 0 || !(lItems[lItems.Count - 1] is TreeView) || 
					(lItems[lItems.Count - 1] is TreeView && ((TreeView)lItems[lItems.Count - 1]).Background != playerBrushes[0]))
				{
					// This is pretty mess at the moment -- this is to detect nested Player stuff
					// (e.g. discarding Market Square when trashing a card and then revealing Watchtower to put the gained Gold on top of your deck)
					if (tviParent is TreeViewItem && 
						(((TreeViewItem)tviParent).Parent is TreeView && ((TreeView)((TreeViewItem)tviParent).Parent).Background == playerBrushes[0] ||
						((TreeViewItem)tviParent).Parent is TreeViewItem && ((TreeViewItem)((TreeViewItem)tviParent).Parent).Parent is TreeView && ((TreeView)((TreeViewItem)((TreeViewItem)tviParent).Parent).Parent).Background == playerBrushes[0]))
						lItems.Add(tvi);
					else
					{
						TreeView tvNewPlayer = new TreeView();
						tvNewPlayer.Background = playerBrushes[0];
						tvNewPlayer.Margin = new Thickness(-19, 0, 0, 0);
						tvNewPlayer.Items.Add(tvi);
						lItems.Add(tvNewPlayer);
					}
				}
				else if (lItems[lItems.Count - 1] is TreeView)
				{
					((TreeView)lItems[lItems.Count - 1]).Items.Add(tvi);
				}
				else
					lItems.Add(tvi);
				tvi.Header = dp; 
				tvi.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			}
			dp.BringIntoView();

			_PreviousLinePlayer = lineVisualPlayer;
		}