/// <summary>
        /// Handle custom resource request and forward it to the appropriate frame.
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private void HandleCustomResourceRequested(ResourceHandler resourceHandler)
        {
            var url = resourceHandler.Url;

            if (Uri.TryCreate(url, UriKind.Absolute, out var uri) && uri.Segments.Length > 1 && uri.Host.Equals(CustomResourceBaseUrl, StringComparison.InvariantCultureIgnoreCase))
            {
                var frameName = uri.Segments.ElementAt(1).TrimEnd(ResourceUrl.PathSeparator.ToCharArray());
                if (frameName != null && Frames.TryGetValue(frameName, out var frame))
                {
                    var customResourceRequestedHandlers = GetCustomResourceHandlers(frame);
                    if (customResourceRequestedHandlers.Any())
                    {
                        resourceHandler.BeginAsyncResponse(() => {
                            // get resource key from the query params
                            var resourceKeyAndOptions = uri.Query.TrimStart('?').Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries).Select(p => Uri.UnescapeDataString(p));
                            var resourceKey           = resourceKeyAndOptions.FirstOrDefault();
                            var options = resourceKeyAndOptions.Skip(1).ToArray();

                            // get response from first handler that returns a stream
                            var response = customResourceRequestedHandlers.Select(h => h(resourceKey, options)).FirstOrDefault(r => r?.Content != null);

                            if (response != null)
                            {
                                var extension = (response.Extension ?? Path.GetExtension(resourceKey)).TrimStart('.');
                                resourceHandler.RespondWith(response.Content, extension);
                            }
                            else
                            {
                                resourceHandler.RespondWith(MemoryStream.Null);
                            }
                        });
                    }
                }
            }
        }