public static int MigrateData()
        {
            if (!GetUrlTrackerTableExists())
                throw new Exception("Url Tracker table not found.");
            if (!GetUrlTrackeOldTableExists())
                throw new Exception("Old Url Tracker table not found.");

            int newUrlTrackerEntriesCount = 0;
            List<OldUrlTrackerModel> oldUrlTrackerEntries = new List<OldUrlTrackerModel>();
            string query = string.Format("SELECT * FROM {0}", UrlTrackerSettings.OldTableName);
            IRecordsReader recordsReader = _sqlHelper.ExecuteReader(query);
            while(recordsReader.Read())
            {
                oldUrlTrackerEntries.Add(new OldUrlTrackerModel()
                {
                    NodeId = recordsReader.GetInt("NodeID"),
                    OldUrl = recordsReader.GetString("OldUrl"),
                    IsCustom = recordsReader.GetBoolean("IsCustom"),
                    Message = recordsReader.GetString("Message"),
                    Inserted = recordsReader.GetDateTime("Inserted"),
                    IsRegex = recordsReader.GetBoolean("IsRegex")
                });
            }

            foreach (OldUrlTrackerModel oldUrlTrackerEntry in oldUrlTrackerEntries)
            {
                Node node = new Node(oldUrlTrackerEntry.NodeId);
                if ((node.Id > 0 || true) && !string.IsNullOrEmpty(oldUrlTrackerEntry.OldUrl) && oldUrlTrackerEntry.OldUrl != "#")
                {
                    string oldUrl = oldUrlTrackerEntry.OldUrl;
                    Uri oldUri = null;
                    if (!oldUrlTrackerEntry.IsRegex)
                    {
                        if (!oldUrl.StartsWith(Uri.UriSchemeHttp))
                            oldUri = new Uri(_baseUri, oldUrl);
                        else
                            oldUri = new Uri(oldUrl);
                        oldUrl = UrlTrackerHelper.ResolveShortestUrl(oldUri.AbsolutePath);
                    }
                    else
                    {
                        if (oldUrl.StartsWith("^/"))
                            oldUrl = string.Concat("^", oldUrl.Substring(2));
                        if (oldUrl.StartsWith("/"))
                            oldUrl = oldUrl.Substring(1);
                        if (oldUrl.EndsWith("/$"))
                            oldUrl = string.Concat(oldUrl.Substring(0, oldUrl.Length - 2), "$");
                        if (oldUrl.EndsWith("/"))
                            oldUrl = oldUrl.Substring(0, oldUrl.Length - 1);
                    }

                    UrlTrackerModel newUrlTrackerEntry = new UrlTrackerModel(
                        !oldUrlTrackerEntry.IsRegex ? oldUrl : string.Empty,
                        oldUri != null ? !string.IsNullOrEmpty(oldUri.Query) && oldUri.Query.StartsWith("?") ? oldUri.Query.Substring(1) : oldUri.Query : string.Empty,
                        oldUrlTrackerEntry.IsRegex ? oldUrl : string.Empty,
                        node.GetDomainRootNode().Id,
                        oldUrlTrackerEntry.NodeId,
                        string.Empty,
                        301,
                        true,
                        false,
                        oldUrlTrackerEntry.Message);
                    newUrlTrackerEntry.Inserted = oldUrlTrackerEntry.Inserted;

                    AddUrlTrackerEntry(newUrlTrackerEntry);

                    newUrlTrackerEntriesCount++;
                }
            }

            return newUrlTrackerEntriesCount;
        }
        public static void AddUrlTrackerEntry(UrlTrackerModel urlTrackerModel)
        {
            string query = "INSERT INTO icUrlTracker (OldUrl, OldUrlQueryString, OldRegex, RedirectRootNodeId, RedirectNodeId, RedirectUrl, RedirectHttpCode, RedirectPassThroughQueryString, ForceRedirect, Notes) VALUES (@oldUrl, @oldUrlQueryString, @oldRegex, @redirectRootNodeId, @redirectNodeId, @redirectUrl, @redirectHttpCode, @redirectPassThroughQueryString, @forceRedirect, @notes)";
            _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateStringParameter("oldUrl", urlTrackerModel.OldUrl), _sqlHelper.CreateStringParameter("oldUrlQueryString", urlTrackerModel.OldUrlQueryString), _sqlHelper.CreateStringParameter("oldRegex", urlTrackerModel.OldRegex), _sqlHelper.CreateParameter("redirectRootNodeId", urlTrackerModel.RedirectRootNodeId), _sqlHelper.CreateNullableParameter("redirectNodeId", urlTrackerModel.RedirectNodeId), _sqlHelper.CreateStringParameter("redirectUrl", urlTrackerModel.RedirectUrl), _sqlHelper.CreateParameter("redirectHttpCode", urlTrackerModel.RedirectHttpCode), _sqlHelper.CreateParameter("redirectPassThroughQueryString", urlTrackerModel.RedirectPassThroughQueryString), _sqlHelper.CreateParameter("forceRedirect", urlTrackerModel.ForceRedirect), _sqlHelper.CreateStringParameter("notes", urlTrackerModel.Notes));

            if (urlTrackerModel.ForceRedirect)
                ReloadForcedRedirectsCache();
        }
        public static void UpdateUrlTrackerEntry(UrlTrackerModel urlTrackerModel)
        {
            string query = "UPDATE icUrlTracker SET OldUrl = @oldUrl, OldUrlQueryString = @oldUrlQueryString, OldRegex = @oldRegex, RedirectRootNodeId = @redirectRootNodeId, RedirectNodeId = @redirectNodeId, RedirectUrl = @redirectUrl, RedirectHttpCode = @redirectHttpCode, RedirectPassThroughQueryString = @redirectPassThroughQueryString, ForceRedirect = @forceRedirect, Notes = @notes, Is404 = @is404 WHERE Id = @id";
            _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateStringParameter("oldUrl", urlTrackerModel.OldUrl), _sqlHelper.CreateStringParameter("oldUrlQueryString", urlTrackerModel.OldUrlQueryString), _sqlHelper.CreateStringParameter("oldRegex", urlTrackerModel.OldRegex), _sqlHelper.CreateParameter("redirectRootNodeId", urlTrackerModel.RedirectRootNodeId), _sqlHelper.CreateNullableParameter<int?>("redirectNodeId", urlTrackerModel.RedirectNodeId), _sqlHelper.CreateStringParameter("redirectUrl", urlTrackerModel.RedirectUrl), _sqlHelper.CreateParameter("redirectHttpCode", urlTrackerModel.RedirectHttpCode), _sqlHelper.CreateParameter("redirectPassThroughQueryString", urlTrackerModel.RedirectPassThroughQueryString), _sqlHelper.CreateParameter("forceRedirect", urlTrackerModel.ForceRedirect), _sqlHelper.CreateStringParameter("notes", urlTrackerModel.Notes), _sqlHelper.CreateParameter("is404", urlTrackerModel.Is404), _sqlHelper.CreateParameter("id", urlTrackerModel.Id));

            if (urlTrackerModel.ForceRedirect)
                ReloadForcedRedirectsCache();
        }