void uiNetworkGraphPlayersListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // FIXME: hack to work around memory leak
            if (uiNetworkGraph.GraphPane == null)
            {
                return;
            }

            HalfLifeDemoAnalyser.Player player = (HalfLifeDemoAnalyser.Player)uiNetworkGraphPlayersListView.SelectedItem;

            if (player == null)
            {
                uiNetworkGraph.GraphPane.CurveList.Clear();
                uiNetworkGraph.Refresh();
                return;
            }

            PointPairList pingPointList = new PointPairList();
            PointPairList lossPointList = new PointPairList();

            Int32  maxSampleSize = player.NetworkStates.Count / 1000;
            Int32  nSamplesTaken = 0;
            UInt32 ping          = 0;
            UInt32 loss          = 0;

            if (maxSampleSize == 0)
            {
                maxSampleSize = 1;
            }

            Int32 i = 0;

            foreach (HalfLifeDemoAnalyser.Player.NetworkState networkState in player.NetworkStates)
            {
                ping += networkState.Ping;
                loss += networkState.Loss;
                nSamplesTaken++;

                if (nSamplesTaken == maxSampleSize)
                {
                    // add to point pair lists
                    Single time = i / (Single)player.NetworkStates.Count * 100.0f;
                    pingPointList.Add(new PointPair(time, ping / (Single)nSamplesTaken));
                    lossPointList.Add(new PointPair(time, loss / (Single)nSamplesTaken));

                    ping          = 0;
                    loss          = 0;
                    nSamplesTaken = 0;
                }

                i++;
            }

            uiNetworkGraph.GraphPane.CurveList.Clear();
            uiNetworkGraph.GraphPane.AddCurve("Ping", pingPointList, System.Drawing.Color.Red, SymbolType.None);
            uiNetworkGraph.GraphPane.AddCurve("Loss", lossPointList, System.Drawing.Color.Blue, SymbolType.None);
            uiNetworkGraph.AxisChange();
            uiNetworkGraph.RestoreScale(uiNetworkGraph.GraphPane);
            uiNetworkGraph.Refresh();
        }
        private void uiPlayersListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            HalfLifeDemoAnalyser.Player player = (HalfLifeDemoAnalyser.Player)uiPlayersListView.SelectedItem;

            if (player != null)
            {
                uiPlayerInfoKeysListView.ItemsSource   = player.InfoKeys;
                uiPlayerInfoKeysListView.SelectedIndex = 0;
            }
            else
            {
                uiPlayerInfoKeysListView.ItemsSource = null;
            }
        }