public static function hostfile($hostfile)
 {
     $config = csscrush::$config;
     $options = csscrush::$options;
     $regex = csscrush::$regex;
     // Keep track of all import file info for later logging
     $mtimes = array();
     $filenames = array();
     // Determine input; string or file
     // Extract the comments then strings
     $stream = isset($hostfile->string) ? $hostfile->string : file_get_contents($hostfile->path);
     // If there's a prepend file, prepend it
     if ($prependFile = csscrush_util::find('Prepend-local.css', 'Prepend.css')) {
         $stream = file_get_contents($prependFile) . $stream;
     }
     $stream = csscrush::extractComments($stream);
     $stream = csscrush::extractStrings($stream);
     // This may be set non-zero during the script if an absolute URL is encountered
     $searchOffset = 0;
     // Recurses until the nesting heirarchy is flattened and all files are combined
     while (preg_match($regex->import, $stream, $match, PREG_OFFSET_CAPTURE, $searchOffset)) {
         $fullMatch = $match[0][0];
         // Full match
         $matchStart = $match[0][1];
         // Full match offset
         $matchEnd = $matchStart + strlen($fullMatch);
         $mediaContext = trim($match[2][0]);
         // The media context if specified
         $preStatement = substr($stream, 0, $matchStart);
         $postStatement = substr($stream, $matchEnd);
         // If just stripping the import statements
         if (isset($hostfile->importIgnore)) {
             $stream = $preStatement . $postStatement;
             continue;
         }
         $url = trim($match[1][0]);
         // Url may be a string token
         if (preg_match($regex->token->string, $url)) {
             $import_url_token = new csscrush_string($url);
             $url = $import_url_token->value;
             // $import_url_token = csscrush::$storage->tokens->strings[ $url ];
             // $url = trim( $import_url_token, '\'"' );
         }
         // csscrush::log( $url );
         // Pass over absolute urls
         // Move the search pointer forward
         if (preg_match($regex->absoluteUrl, $url)) {
             $searchOffset = $matchEnd;
             continue;
         }
         // Create import object
         $import = new stdClass();
         $import->url = $url;
         $import->mediaContext = $mediaContext;
         $import->hostDir = $hostfile->dir;
         // Check to see if the url is root relative
         // Flatten import path for convenience
         if (strpos($import->url, '/') === 0) {
             $import->path = realpath($config->docRoot . $import->url);
         } else {
             $import->path = realpath("{$hostfile->dir}/{$import->url}");
         }
         $import->content = @file_get_contents($import->path);
         // Failed to open import, just continue with the import line removed
         if (!$import->content) {
             csscrush::log("Import file '{$import->url}' not found");
             $stream = $preStatement . $postStatement;
             continue;
         } else {
             // Start with extracting comments in the import
             $import->content = csscrush::extractComments($import->content);
             $import->dir = dirname($import->url);
             // Store import file info for cache validation
             $mtimes[] = filemtime($import->path);
             $filenames[] = $import->url;
             // Alter all the url strings to be paths relative to the hostfile:
             //   Match all @import statements in the import content
             //   Store the replacements we might find
             $matchCount = preg_match_all($regex->import, $import->content, $matchAll, PREG_OFFSET_CAPTURE);
             $replacements = array();
             for ($index = 0; $index < $matchCount; $index++) {
                 $fullMatch = $matchAll[0][$index][0];
                 $urlMatch = $matchAll[1][$index][0];
                 $search = $urlMatch;
                 $replace = "{$import->dir}/{$urlMatch}";
                 // Try to resolve absolute paths
                 // On failure strip the @import statement
                 if (strpos($urlMatch, '/') === 0) {
                     $replace = self::resolveAbsolutePath($urlMatch);
                     if (!$replace) {
                         $search = $fullMatch;
                         $replace = '';
                     }
                 }
                 // Trim the statement and set the resolved path
                 $statement = trim(str_replace($search, $replace, $fullMatch));
                 // Normalise import statement to be without url() syntax:
                 //   This is so relative urls can easily be targeted later
                 $statement = self::normalizeImportStatement($statement);
                 $replacements[$fullMatch] = $statement;
             }
             // If we've stored any altered @import strings then we need to apply them
             if (count($replacements)) {
                 $import->content = str_replace(array_keys($replacements), array_values($replacements), $import->content);
             }
             // Now @import urls have been adjusted extract strings
             $import->content = csscrush::extractStrings($import->content);
             // Optionally rewrite relative url and custom function data-uri references
             if ($options['rewrite_import_urls']) {
                 $import->content = self::rewriteImportRelativeUrls($import);
             }
             // Add media context if it exists
             if ($import->mediaContext) {
                 $import->content = "@media {$import->mediaContext} {" . $import->content . '}';
             }
             $stream = $preStatement . $import->content . $postStatement;
         }
     }
     // End while
     // Save only if the hostfile object is associated with a real file
     if ($hostfile->path) {
         self::save(array('imports' => $filenames, 'datem_sum' => array_sum($mtimes) + $hostfile->mtime, 'options' => $options));
     }
     return $stream;
 }