private void getTemplateUrls(jsTileInfo[] tiles, out string[] mapUrlTemplates, out string[] overlayUrlTemplates)
        {
            List<string> baseUrls = new List<string>();
            List<string> overlayUrls = new List<string>();
            foreach (var ti in tiles)
            {
                Match m = rex.Match(ti.Url);
                if (m.Success)
                {
                    string url = ti.Url;
                    url = url.Replace("x=" + m.Groups["x"].Value, "x={0}");
                    url = url.Replace("y=" + m.Groups["y"].Value, "y={1}");
                    url = url.Replace("z=" + m.Groups["z"].Value, "z={2}");
                    if (url.Contains("&s="))
                        url = sMatch.Replace(url, "&s={3}&");
                    if (url.Contains("&token="))
                        url = tokenMatch.Replace(url, "&token={4}&");
                    if (url.Contains("&scale="))
                        url = scaleMath.Replace(url, "");

                    if (_mapType == GoogleV3TileSource.MapTypeId.HYBRID && url.StartsWith("http://mt"))
                    {
                        overlayUrls.Add(url);
                    }
                    else
                    {
                        if (!baseUrls.Contains(url))
                            baseUrls.Add(url);
                    }
                }
            }
            mapUrlTemplates = baseUrls.ToArray();
            overlayUrlTemplates = overlayUrls.ToArray();
        }
        private Extent parseTiles(Extent extent, int level, List<BruTile.TileInfo> tis, jsTileInfo[] tiles)
        {
            foreach (var ti in tiles)
            {
                Match m = rex.Match(ti.Url);
                if (m.Success)
                {
                    int x = Convert.ToInt32(m.Groups["x"].Value);
                    int y = Convert.ToInt32(m.Groups["y"].Value);
                    int z = Convert.ToInt32(m.Groups["z"].Value);

                    Extent e = new BruTile.Extent(
                        extent.MinX + ti.Left * Resolutions[level].UnitsPerPixel,
                        extent.MaxY - (ti.Top + 256) * Resolutions[level].UnitsPerPixel,
                        extent.MinX + (ti.Left + Width) * Resolutions[level].UnitsPerPixel,
                        extent.MaxY - (ti.Top) * Resolutions[level].UnitsPerPixel
                        );

                    if (e.Intersects(extent))
                    {

                        tis.Add(new BruTile.GoogleMaps.GoogleV3TileInfo()
                        {
                            Url = ti.Url,
                            Index = new TileIndex(x, y, ti.Url.GetHashCode()),
                            Extent = e,
                            ZIndex = ti.zIndex
                        });
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Could not match " + ti.Url);
                }
            }
            System.Diagnostics.Debug.WriteLine("got " + tis.Count + " tiles");
            return extent;
        }
        private jsTileInfo[] getCurrentTileURLs()
        {
            object ret = null;
            lock (locker)
            {
                try
                {
                    m_WebBrowser.Invoke(new MethodInvoker(delegate
                    {
                        ret = m_WebBrowser.Document.InvokeScript("getTileURLs");
                    }));
                }
                catch (Exception ee)
                {
                    logger.Warn(ee.Message, ee);
                    try
                    {
                        m_WebBrowser.Invoke(new MethodInvoker(delegate
                        {
                            ret = m_WebBrowser.Document.InvokeScript("getTileURLs");
                        }));
                    }
                    catch (Exception ee2)
                    {
                        logger.Warn("Exception again: " + ee2.Message, ee2);
                    }
                }

            }
            Type t = ret.GetType();
            int len = Convert.ToInt32(t.InvokeMember("length", BindingFlags.GetProperty, null, ret, null));
            jsTileInfo[] ti = new jsTileInfo[len];
            for (int i = 0; i < len; i++)
            {
                object item = t.InvokeMember("item_" + i, BindingFlags.GetProperty, null, ret, null);
                string url = t.InvokeMember("url", BindingFlags.GetProperty, null, item, null) as string;
                int left = (int)t.InvokeMember("left", BindingFlags.GetProperty, null, item, null);
                int top = (int)t.InvokeMember("top", BindingFlags.GetProperty, null, item, null);
                int index = (int)t.InvokeMember("index", BindingFlags.GetProperty, null, item, null);
                int zIndex = (int)t.InvokeMember("zIndex", BindingFlags.GetProperty, null, item, null);
                ti[i] = new jsTileInfo()
                {
                    Url = url,
                    Left = left,
                    Top = top,
                    Index = index,
                    zIndex = zIndex
                };
            }

            return ti;
        }