private Dir422 TraverseToDirectory(Dir422 currentLocation, string[] uriPieces, WebRequest req)
        {
            File422 fileAtRoot = null;

            //Iterate over all path parts until we get to the file or directory wanted
            for (int item = 0; item < uriPieces.Length - 1; item++)
            {
                fileAtRoot = currentLocation.GetFile(uriPieces[item]);

                if (fileAtRoot == null)
                {
                    currentLocation = currentLocation.GetDir(uriPieces[item]);

                    if (currentLocation == null)
                    {
                        req.WriteNotFoundResponse("<html>404 File Not Found<br>" + "</html>");
                    }
                }
                else
                {
                    break;
                }
            }

            return(currentLocation);
        }
        public override void Handler(WebRequest req)
        {
            //If the request URI doesn't start with the proper service URI
            if (!req.GetUri().StartsWith(this.ServiceURI, StringComparison.CurrentCulture))
            {
                throw new InvalidOperationException();
            }

            //Get Uri pieces
            string[] uriPieces = GetUriPeices(req);

            //Decode path
            uriPieces = DecodePath(uriPieces);

            //Get the root directory
            Dir422 currentLocation = FileSystem.GetRoot();

            //Handle PUT requests
            if (req.GetHTTPType() == "PUT")
            {
                FileStream newFileStream = null;

                try
                {
                    currentLocation = TraverseToDirectory(currentLocation, uriPieces, req);

                    if (currentLocation.ContainsFile(uriPieces[uriPieces.Length - 1], false) == true)
                    {
                        req.WriteNotFoundResponse("<html>File Already Exists!</html>");
                    }
                    else
                    {
                        File422 newFile = currentLocation.CreateFile(uriPieces[uriPieces.Length - 1]);
                        newFileStream = (FileStream)newFile.OpenReadWrite();

                        CopyBytes(req.GetBody(), newFileStream, req.GetBody().Length);

                        newFileStream.Close();

                        string response = "<html>File Uploaded!</html>";
                        string header   = string.Format(putHeaderTemplate, req.GetHTTPVersion(), "text/html", response.Length);

                        req.WriteHTMLResponse(header + response);
                    }
                }
                catch (Exception e)
                {
                    if (newFileStream != null)
                    {
                        newFileStream.Close();
                    }
                }
            }
            //Handle GET requests
            else
            {
                //If we're at the root directory, respond with a list
                if (uriPieces.Length == 0)
                {
                    string response = BuildDirHTML(FileSystem.GetRoot());

                    string header = string.Format(dirHeaderTemplate, req.GetHTTPVersion(), "text/html", response.Length);

                    req.WriteHTMLResponse(header + response);
                }
                else
                {
                    currentLocation = TraverseToDirectory(currentLocation, uriPieces, req);

                    //If the wanted item is a file, respond with a file
                    if (currentLocation.GetFile(uriPieces[uriPieces.Length - 1]) != null)
                    {
                        //If we have a range header, we need to use a partial response header
                        if (req.GetHeaders().ContainsKey("range"))
                        {
                            string header = GetRangeHeader(req, currentLocation, uriPieces);

                            req.WriteHTMLResponse(header);
                        }
                        //Write repsonse for displaying file contents
                        else
                        {
                            Stream selectedFile = currentLocation.GetFile(uriPieces[uriPieces.Length - 1]).OpenReadOnly();
                            string header       = string.Format(fileHeaderTemplate, req.GetHTTPVersion(), GetContentType(currentLocation.GetFile(uriPieces[uriPieces.Length - 1]).Name), selectedFile.Length);
                            selectedFile.Close();

                            req.WriteHTMLResponse(header);
                        }

                        BuildFileHTML(currentLocation.GetFile(uriPieces[uriPieces.Length - 1]), req);
                    }
                    //If the wanted item is a directory, respond with a directory listing
                    else
                    {
                        //Write response for displaying directory
                        if (currentLocation.GetDir(uriPieces[uriPieces.Length - 1]) != null)
                        {
                            string response = BuildDirHTML(currentLocation.GetDir(uriPieces[uriPieces.Length - 1]));

                            string header = string.Format(dirHeaderTemplate, req.GetHTTPVersion(), "text/html", response.ToString().Length);

                            req.WriteHTMLResponse(header + response);
                        }
                        //Request item could not be found
                        else
                        {
                            req.WriteNotFoundResponse("<html>404 File Not Found<br>" + "</html>");
                        }
                    }
                }
            }
        }