/**
  * @param string[] $server
  * @param string $path
  * @param Perflog|bool $perfLog
  */
 public function Process($server, $path, $perfLog = false)
 {
     if ($perfLog) {
         $log = "Session Started\r\n";
         $log .= "ID:            " . session_id() . "\r\n";
         $log .= "IP Address:    " . $_SERVER['REMOTE_ADDR'] . "\r\n";
         $perfLog->Log($log);
     }
     $headers = getallheaders();
     $method = isset($server['REQUEST_METHOD']) ? $server['REQUEST_METHOD'] : false;
     if ($this->LoggedIn()) {
         if (!empty($path)) {
             $item = array_shift($path);
             switch ($item) {
                 case 'books':
                     if (empty($path)) {
                         switch ($method) {
                             case "GET":
                             case "POST":
                                 $handler = $method . "_Books";
                                 if (method_exists($this, $handler)) {
                                     $this->{$handler}();
                                 } else {
                                     APIResponse(RESPONSE_404, "Could not find books handler {$handler}.");
                                 }
                                 break;
                             default:
                                 APIResponse(RESPONSE_400, "Bad book request method.");
                                 break;
                         }
                     } else {
                         $bookID = array_shift($path);
                         if (!array_key_exists($bookID, $this->Books)) {
                             $this->RefreshBooks();
                         }
                         if (array_key_exists($bookID, $this->Books)) {
                             $this->Books[$bookID]->Process($server, $path, $headers);
                         } else {
                             APIResponse(RESPONSE_404, "Book {$bookID} not found.");
                         }
                     }
                     break;
                 case 'bars':
                     if (empty($path)) {
                         switch ($method) {
                             case "GET":
                             case "POST":
                                 $handler = $method . "_Bars";
                                 if (method_exists($this, $handler)) {
                                     $this->{$handler}();
                                 } else {
                                     APIResponse(RESPONSE_404, "Could not find bars handler {$handler}.");
                                 }
                                 break;
                             default:
                                 APIResponse(RESPONSE_400, "Bad bar request method.");
                                 break;
                         }
                     } else {
                         $barID = array_shift($path);
                         if (!array_key_exists($barID, $this->Bars)) {
                             $this->RefreshBars();
                         }
                         if (array_key_exists($barID, $this->Bars)) {
                             $this->Bars[$barID]->Process($server, $path, $headers);
                         } else {
                             APIResponse(RESPONSE_404, "Bar {$barID} not found.");
                         }
                     }
                     break;
                 case 'ingredients':
                     if (empty($path)) {
                         switch ($method) {
                             case "GET":
                             case "POST":
                                 $handler = $method . "_Ingredients";
                                 if (method_exists($this, $handler)) {
                                     $this->{$handler}();
                                 } else {
                                     APIResponse(RESPONSE_404, "Could not find ingredients handler {$handler}.");
                                 }
                                 break;
                             default:
                                 APIResponse(RESPONSE_400, "Bad ingredient request method.");
                                 break;
                         }
                     } else {
                         $ingredientID = array_shift($path);
                         if (!array_key_exists($ingredientID, $this->Ingredients)) {
                             $this->RefreshIngredients();
                         }
                         if (array_key_exists($ingredientID, $this->Ingredients)) {
                             $this->Ingredients[$ingredientID]->Process($server, $path, $headers);
                         } else {
                             APIResponse(RESPONSE_404, "Ingredient {$ingredientID} not found.");
                         }
                     }
                     break;
                 case 'logout':
                     $this->auth = false;
                     header("Clear-Authorization: true");
                     APIResponse(RESPONSE_200);
                     //TODO: Destroy the session as well.
                     break;
                 default:
                     break;
             }
         } else {
             switch ($method) {
                 case "GET":
                 case "PUT":
                     $handler = $method;
                     if (method_exists($this, $handler)) {
                         $this->{$handler}();
                     } else {
                         APIResponse(RESPONSE_404, "Could not find session handler {$handler}.");
                     }
                     break;
             }
         }
     } else {
         if (!empty($path)) {
             $item = array_shift($path);
             switch ($item) {
                 case 'login':
                     $username = getParam('username');
                     $password = getParam('password');
                     if ($username && $password) {
                         $username = $this->DB->Quote($username);
                         $password = $this->DB->Quote($password);
                         $login = $this->DB->GetRow("SELECT * FROM tblUsers WHERE username={$username} AND password={$password};");
                         if ($login && (int) $login['id']) {
                             $this->auth = sha1(uniqid('randomsalt', true));
                             $this->ID = (int) $login['id'];
                             $this->Username = $login['username'];
                             $this->DisplayName = $login['displayName'];
                             header("Set-Authorization: {$this->auth}");
                             APIResponse(RESPONSE_200, "Your name is {$this->DisplayName}");
                         } else {
                             APIResponse(RESPONSE_401, 'Invalid Credentials');
                         }
                     } else {
                         APIResponse(RESPONSE_401, 'No user or password given.  ' . file_get_contents('php://input'));
                     }
                     break;
                 default:
                     APIResponse(RESPONSE_401, 'You are not logged in.');
                     break;
             }
         } else {
             switch ($method) {
                 default:
                     APIResponse(RESPONSE_401, 'You are not logged in.');
                     break;
             }
         }
     }
     APIResponse(RESPONSE_400);
 }