public void Register(AbstractEndpoint callback)
        {
            if (!callback.HasCallback)
            {
                return;
            }

            logger.Debug($"Register() {callback.Name} {callback.Url} {callback.SessionId}");


            if (string.IsNullOrEmpty(callback.Url))
            {
                Unregister(callback.Name, callback.SessionId);

                if (callback.Schedule != null)
                {
                    ScheduledEndpointManager?.SetEndpointSchedule(callback);
                }

                if (callback.SessionId == null)
                {
                    Endpoints.TryAdd(callback.Name, callback);
                }
                else
                {
                    if (!SessionManager.SessionExists(callback.SessionId))
                    {
                        SessionManager.StartSession(callback.SessionId);
                    }

                    if (SessionManager.SessionExists(callback.SessionId))
                    {
                        var session = SessionManager.GetSession(callback.SessionId);
                        session.Endpoints.TryAdd(callback.Name, callback);
                    }
                }
            }
            else
            {
                if (callback.UrlRegEx == null)
                {
                    callback.Parts = callback.Url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Select(m => new Part(m, m.StartsWith(":"))).ToArray();

                    if (callback.Parts.GroupBy(m => m.Value).Any(m => m.Count() > 1))
                    {
                        throw new Exception("Duplicate variable name in URL.");
                    }
                }

                var existingEndpoint = RestEndpoints.FirstOrDefault(m => m.Method == callback.Method && m.Url.Equals(callback.Url, StringComparison.OrdinalIgnoreCase));

                if (existingEndpoint != null)
                {
                    RestEndpoints.Remove(existingEndpoint);
                }

                RestEndpoints.Add(callback);
            }
        }
        public AbstractEndpoint GetByUrl(string url, string method, Dictionary <string, object> matchedVariables)
        {
            foreach (var endpoint in RestEndpoints.Where(m => m.Method.Equals(method, StringComparison.OrdinalIgnoreCase)))
            {
                Dictionary <string, object> variables = new Dictionary <string, object>();

                if (endpoint.UrlRegEx != null)
                {
                    var matches = endpoint.UrlRegEx.Matches(url);
                    if (matches != null && matches.Count != 0)
                    {
                        foreach (Match match in matches)
                        {
                            for (int i = 1; i < match.Groups.Count; i++)
                            {
                                var    group = match.Groups[i];
                                string name  = endpoint.UrlRegEx.GroupNameFromNumber(i);

                                if (matchedVariables.ContainsKey(name))
                                {
                                    matchedVariables[name] = group.Value;
                                }
                                else
                                {
                                    matchedVariables.Add(name, group.Value);
                                }
                            }
                        }

                        return(endpoint);
                    }
                }

                if (IsMatch(endpoint, url, variables))
                {
                    foreach (var kvp in variables)
                    {
                        if (matchedVariables.ContainsKey(kvp.Key))
                        {
                            matchedVariables[kvp.Key] = kvp.Value;
                        }
                        else
                        {
                            matchedVariables.Add(kvp.Key, kvp.Value);
                        }
                    }
                    return(endpoint);
                }
            }

            return(null);
        }