private void TrimDictionaries(StatInfoItem statInfoItem)
		{
			statInfoItem.MapData = TrimDictionary(statInfoItem.MapData);
			statInfoItem.IndexData = TrimDictionary(statInfoItem.IndexData);
			statInfoItem.Level0Data = TrimDictionary(statInfoItem.Level0Data);
			statInfoItem.Level1Data = TrimDictionary(statInfoItem.Level1Data);
			statInfoItem.Level2Data = TrimDictionary(statInfoItem.Level2Data);
		}
		private void UpdateStatInfoFromGraphData(StatInfoItem statInfoItem)
		{
			foreach (var indexingPerformanceStats in IndexesGraphData[statInfoItem.Title].IndexData)
			{
				statInfoItem.IndexData[indexingPerformanceStats.Started] = indexingPerformanceStats;
			}

			foreach (var indexingPerformanceStats in IndexesGraphData[statInfoItem.Title].MapData)
			{
				statInfoItem.MapData[indexingPerformanceStats.Started] = indexingPerformanceStats;
			}

			foreach (var indexingPerformanceStats in IndexesGraphData[statInfoItem.Title].Level0Data)
			{
				statInfoItem.Level0Data[indexingPerformanceStats.Started] = indexingPerformanceStats;
			}

			foreach (var indexingPerformanceStats in IndexesGraphData[statInfoItem.Title].Level1Data)
			{
				statInfoItem.Level1Data[indexingPerformanceStats.Started] = indexingPerformanceStats;
			}

			foreach (var indexingPerformanceStats in IndexesGraphData[statInfoItem.Title].Level2Data)
			{
				statInfoItem.Level2Data[indexingPerformanceStats.Started] = indexingPerformanceStats;
			}

			TrimDictionaries(statInfoItem);
		}
		private void AddIndexStat(StatInfoItem statInfoItem)
		{
			foreach (var propertyInfo in statInfoItem.Item.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
			{
				if (propertyInfo.Name == "Name")
				{
					statInfoItem.Title = propertyInfo.GetValue(statInfoItem.Item, null).ToString();
					ViewOptions.Add(statInfoItem.Title);
					continue;
				}

				if (propertyInfo.Name == "Performance")
				{
					var performance = propertyInfo.GetValue(statInfoItem.Item, null) as IndexingPerformanceStats[];
					if (performance == null || performance.Length == 0)
						continue;

					UpdateGraphDate(performance, statInfoItem);

					continue;
				}

				if (propertyInfo.GetValue(statInfoItem.Item, null) == null)
					continue;

				int isZero;
				var isInt = int.TryParse(propertyInfo.GetValue(statInfoItem.Item, null).ToString(), out isZero);
				if (isInt && isZero == 0)
					continue;

				statInfoItem.ItemData.Add(propertyInfo.Name, GetValueWithFormat(propertyInfo.GetValue(statInfoItem.Item, null)));
			}
		}
		private void UpdateGraphDate(IEnumerable<IndexingPerformanceStats> performance, StatInfoItem statInfoItem)
		{
			if(IndexesGraphData.ContainsKey( statInfoItem.Title) == false)
				IndexesGraphData.Add(statInfoItem.Title, new PerformanceStats());

			foreach (var indexingPerformanceStat in performance)
			{
				indexingPerformanceStat.Started = indexingPerformanceStat.Started.ToLocalTime();
				switch (indexingPerformanceStat.Operation)
				{
					case "Index":
						if (IndexesGraphData[statInfoItem.Title].IndexData.Contains(indexingPerformanceStat) == false)
							IndexesGraphData[statInfoItem.Title].IndexData.Add(indexingPerformanceStat);
						break;
					case "Map":
						if (IndexesGraphData[statInfoItem.Title].MapData.Contains(indexingPerformanceStat) == false)
							IndexesGraphData[statInfoItem.Title].MapData.Add(indexingPerformanceStat);
						break;
					case "Reduce Level 0":
						if (IndexesGraphData[statInfoItem.Title].Level0Data.Contains(indexingPerformanceStat) == false)
							IndexesGraphData[statInfoItem.Title].Level0Data.Add(indexingPerformanceStat);
						break;
					case "Reduce Level 1":
						if (IndexesGraphData[statInfoItem.Title].Level1Data.Contains(indexingPerformanceStat) == false)
							IndexesGraphData[statInfoItem.Title].Level1Data.Add(indexingPerformanceStat);
						break;
					case "Reduce Level 2":
						if (IndexesGraphData[statInfoItem.Title].Level2Data.Contains(indexingPerformanceStat) == false)
							IndexesGraphData[statInfoItem.Title].Level2Data.Add(indexingPerformanceStat);
						break;
				}
			}

			UpdateStatInfoFromGraphData(statInfoItem);
		}
		private void UpdateStatistics()
		{
			StatsData = ApplicationModel.Database.Value.Statistics;
			Statistics.Clear();
			ViewOptions.Clear();
			ViewOptions.Add("All");
			ViewOptions.Add("Single Items");

			if (StatsData.Value == null)
			{
				if (retries-- == 0)
				{
					ApplicationModel.Current.Notifications.Add(new Notification("Could not load settings for database " + ApplicationModel.Database.Value.Name));
					return;
				}
				Thread.Sleep(100);
				UpdateStatistics();
				return;
			}

			retries = 3;

			foreach (var propertyInfo in StatsData.Value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
			{
				var enumerable = propertyInfo.GetValue(StatsData.Value, null) as IEnumerable<object>;

				if (enumerable != null)
				{
					var list = enumerable as List<object> ?? enumerable.ToList();
					if (propertyInfo.Name == "StaleIndexes")
					{
						StaleIndexes = new List<object>(list);
						if (list.Count == 0)
						{
							Statistics.Add(propertyInfo.Name, new StatInfo
							{
								Message = "No Stale Indexes",
								ToolTipData = "No Stale Indexes"
							});
						}
						else if (list.Count > 1)
						{
							ViewOptions.Add("Stale Indexes");
							Statistics.Add(propertyInfo.Name, new StatInfo
							{
								Message = string.Format("There are {0} Stale Indexes: {1}", list.Count, string.Join(",", list)),
								ToolTipData = string.Join(", ", list)
							});
						}
						else // only one item
						{
							ViewOptions.Add("Stale Indexes");
							Statistics.Add(propertyInfo.Name, new StatInfo
							{
								Message = "There is 1 Stale Index: " + list[0],
								ToolTipData = list[0].ToString() // only one item, no need to call string.Join()
							});
						}

						continue;
					}

					if (list.Count == 0)
					{
						continue;						
					}

					if ((list.First() is string == false) && (list.First() is Abstractions.Data.IndexStats == false))
						continue;

					var statInfo = new StatInfo
					{
						IsList = true,
						ListItems = new List<StatInfoItem>(),
					};

					foreach (var item in list)
					{
						var statInfoItem = new StatInfoItem(item);

						if (statInfoItem.ItemType == typeof(Abstractions.Data.IndexStats))
							AddIndexStat(statInfoItem);

						statInfo.ListItems.Add(statInfoItem);
					}

					Statistics.Add(propertyInfo.Name, statInfo);
					ViewOptions.Add(propertyInfo.Name);
				}
				else
				{
					if (string.IsNullOrEmpty(propertyInfo.GetValue(StatsData.Value, null).ToString()) || propertyInfo.GetValue(StatsData.Value, null).ToString() == "0")
						continue;

					Statistics.Add(propertyInfo.Name, new StatInfo
					{
						Message = GetValueWithFormat(propertyInfo.GetValue(StatsData.Value, null)),
						ToolTipData = GetValueWithFormat(propertyInfo.GetValue(StatsData.Value, null))
					});
				}
			}

			OnPropertyChanged(() => StatsData);
			UpdateView();
		}