private Response HandleFileRequest(FileRequest fileRequest, string rawUrl)
        {
            try
            {
                var contentType = "text/plain";
                var ext = Path.GetExtension(fileRequest.ResourceName).ToLower();
                if (ext == ".htm" || ext == ".html") contentType = "text/html";
                else if (ext == ".css") contentType = "text/css";
                else if (ext == ".js") contentType = "text/javascript";
                else if (ext == ".png") contentType = "image/png";
                else if (ext == ".jpg" || ext == ".jpeg") contentType = "image/jpg";

                var assemblyWithResources = _registeredAssemblies[fileRequest.AssemblyFilename];
                var stream = assemblyWithResources.GetManifestResourceStream(fileRequest.ResourceName);

                if (stream == null)
                    throw new Exception();

                return new Response(new TypedStream(stream, contentType));
            }
            catch (Exception)
            {
                Env.Log("Webserver 404: file '" + rawUrl + "' not found.");
                return new Response(new TextString(rawUrl + " not found."), HttpStatusCode.NotFound);
            }
        }
        private FileRequest ParseFileUrl(Uri url)
        {
            var path = url.AbsolutePath.Substring(1);
            var result = new FileRequest();

            if (path.Contains("/"))
            {
                var firstPart = path.Substring(0, path.IndexOf('/'));
                if (urlMappings.ContainsKey(firstPart))
                {
                    var mapping = urlMappings[firstPart];
                    result.AssemblyFilename = mapping.AssemblyName;

                    var secondPart = path.Substring(firstPart.Length + 1).Replace('/', '.');

                    if (string.IsNullOrEmpty(secondPart) || secondPart.EndsWith("."))
                        secondPart += "Index.htm";

                    result.ResourceName = StringExtensions.ConcatenateWithSeparator(mapping.ResourcePrefix, ".", secondPart);
                    return result;
                }
            }

            // First part is not a registered assembly. Treat it as a directory from the default assembly then.
            var defaultMapping = urlMappings[""];
            result.AssemblyFilename = defaultMapping.AssemblyName;

            path = path.Replace('/', '.');

            if (string.IsNullOrEmpty(path) || path.EndsWith("."))
                path += "Index.htm";

            result.ResourceName = StringExtensions.ConcatenateWithSeparator(defaultMapping.ResourcePrefix, ".", path);
            return result;
        }