private static bool TryGetCachedMarketStat(int typeID, int regionID, out MarketStat value)
        {
            Dictionary<int, MarketStat> regionCache;

            // check cache
            lock (m_cache)
            {
                if (m_cache.TryGetValue(regionID, out regionCache)
                    && regionCache.TryGetValue(typeID, out value)
                    && DateTime.Now.Subtract(value.TimeStamp) < m_cacheDuration)
                    return true;
            }

            // default
            value = new MarketStat();
            return false;
        }
        private static void CacheMarketStat(int typeID, int regionID, MarketStat value)
        {
            Dictionary<int, MarketStat> regionCache;

            lock (m_cache)
            {
                // fetch or create the region cache
                if (!m_cache.TryGetValue(regionID, out regionCache))
                {
                    regionCache = new Dictionary<int, MarketStat>();
                    m_cache[regionID] = regionCache;
                }

                // store the value
                regionCache[typeID] = value;
                m_cacheDirty = true;
            }
        }
        private static Dictionary<int, MarketStat> ParseMarketStat(string path)
        {
            Dictionary<int, MarketStat> results = new Dictionary<int, MarketStat>();
            DateTime now = DateTime.Now;

            // parse the requested value from the eve-central XML
            using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
            {
                XPathDocument doc = new XPathDocument(fs);
                XPathNavigator nav = doc.CreateNavigator();
                XPathNodeIterator typeNodes = nav.Select("//marketstat/type");
                MarketStat stat;
                int typeID;

                while (typeNodes.MoveNext())
                {
                    // read the data from this node
                    try
                    {
                        typeID = typeNodes.Current.SelectSingleNode("@id").ValueAsInt;

                        stat = new MarketStat();
                        stat.TimeStamp = now;
                        stat.All = ParseMarketStatEntry(typeNodes.Current.SelectSingleNode("all"));
                        stat.Buy = ParseMarketStatEntry(typeNodes.Current.SelectSingleNode("buy"));
                        stat.Sell = ParseMarketStatEntry(typeNodes.Current.SelectSingleNode("sell"));

                        results[typeID] = stat;
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
                    }
                }
            }

            return results;
        }