protected function to($what, &$out, $until = false, $allowNewline = false)
 {
     if (is_string($allowNewline)) {
         $validChars = $allowNewline;
     } else {
         $validChars = $allowNewline ? "." : "[^\n]";
     }
     if (!$this->match('(' . $validChars . '*?)' . GantryLessCompiler::preg_quote($what), $m, !$until)) {
         return false;
     }
     if ($until) {
         $this->count -= strlen($what);
     }
     // give back $what
     $out = $m[1];
     return true;
 }
 /**
  * @param string $lessfile
  * @param bool   $cssfile
  * @param int    $priority
  *
  * @param array  $options
  *
  * @throws RuntimeException
  */
 public function addLess($lessfile, $cssfile = null, $priority = self::DEFAULT_STYLE_PRIORITY, array $options = array())
 {
     $less_search_paths = array();
     // setup the less filename
     if (dirname($lessfile) == '.') {
         //set up the check for template with plartform based dirs
         $less_search_paths = $this->platform->getAvailablePlatformVersions($this->templatePath . '/less');
         foreach ($less_search_paths as $less_path) {
             if (is_dir($less_path)) {
                 $search_file = preg_replace('#[/\\\\]+#', '/', $less_path . '/' . $lessfile);
                 if (is_file($search_file)) {
                     $lessfile = $search_file;
                     break;
                 }
             }
         }
     }
     $less_file_md5 = md5($lessfile);
     $less_file_path = $this->convertToPath($lessfile);
     $less_file_url = $this->convertToUrl($less_file_path);
     // abort if the less file isnt there
     if (!is_file($less_file_path)) {
         return;
     }
     // get an md5 sum of any passed in options
     $tmp_options = $options;
     array_walk($tmp_options, create_function('&$v,$k', '$v = " * @".$k." = " .$v;'));
     $options_string = implode($tmp_options, "\n");
     $options_md5 = md5($options_string . (string) $this->get('less-compression', true));
     $css_append = '';
     if (!empty($options)) {
         $css_append = '-' . $options_md5;
     }
     $default_compiled_css_dir = $this->templatePath . '/css-compiled';
     if (!file_exists($default_compiled_css_dir)) {
         @JFolder::create($default_compiled_css_dir);
         if (!file_exists($default_compiled_css_dir)) {
             throw new Exception(sprintf('Unable to create default directory (%s) for compiled less files.  Please check your filesystem permissions.', $default_compiled_css_dir));
         }
     }
     // setup the output css file name
     if (is_null($cssfile)) {
         $css_file_path = $default_compiled_css_dir . '/' . pathinfo($lessfile, PATHINFO_FILENAME) . $css_append . '.css';
         $css_passed_path = pathinfo($css_file_path, PATHINFO_BASENAME);
     } else {
         if (dirname($cssfile) == '.') {
             $css_file_path = $default_compiled_css_dir . '/' . pathinfo($cssfile, PATHINFO_FILENAME) . $css_append . '.css';
             $css_passed_path = pathinfo($css_file_path, PATHINFO_BASENAME);
         } else {
             $css_file_path = dirname($this->convertToPath($cssfile)) . '/' . pathinfo($cssfile, PATHINFO_FILENAME) . $css_append . '.css';
             $css_passed_path = $css_file_path;
         }
     }
     $cssfile_md5 = md5($css_file_path);
     // set base compile modes
     $force_compile = false;
     $single_compile = false;
     $app = JFactory::getApplication();
     if (!$app->isAdmin()) {
         $cachegroup = self::LESS_SITE_CACHE_GROUP;
     } else {
         $cachegroup = self::LESS_ADMIN_CACHE_GROUP;
     }
     $runcompile = false;
     $cache_handler = GantryCache::getCache($cachegroup, null, true);
     $cached_less_compile = $cache_handler->get($cssfile_md5, false);
     if ($cached_less_compile === false || !file_exists($css_file_path)) {
         $cached_less_compile = $less_file_path;
         $runcompile = true;
     } elseif (is_array($cached_less_compile) && isset($cached_less_compile['root'])) {
         if (isset($cached_less_compile['files']) and is_array($cached_less_compile['files'])) {
             foreach ($cached_less_compile['files'] as $fname => $ftime) {
                 if (!file_exists($fname) or filemtime($fname) > $ftime) {
                     // One of the files we knew about previously has changed
                     // so we should look at our incoming root again.
                     $runcompile = true;
                     break;
                 }
             }
         }
     }
     if ($runcompile) {
         gantry_import('core.utilities.gantrylesscompiler');
         $quick_expire_cache = GantryCache::getCache($cachegroup, $this->get('less-compilewait', self::LESS_MAX_COMPILE_WAIT_TIME));
         $timewaiting = 0;
         while ($quick_expire_cache->get($cssfile_md5 . '-compiling') !== false) {
             $wait = 100000;
             // 1/10 of a second;
             usleep($wait);
             $timewaiting += $wait;
             if ($timewaiting >= $this->get('less-compilewait', self::LESS_MAX_COMPILE_WAIT_TIME) * 1000000) {
                 break;
             }
         }
         $less = new GantryLessCompiler();
         $less->setImportDir($less_search_paths);
         $less->addImportDir($this->gantryPath . '/assets');
         if (!empty($options)) {
             $less->setVariables($options);
         }
         if ($this->get('less-compression', true)) {
             $less->setFormatter("compressed");
         }
         $quick_expire_cache->set($cssfile_md5 . '-compiling', true);
         try {
             $new_cache = $less->cachedCompile($cached_less_compile, $force_compile);
         } catch (Exception $ex) {
             $quick_expire_cache->clear($cssfile_md5 . '-compiling');
             throw new RuntimeException('Less Parse Error: ' . $ex->getMessage());
         }
         if (!is_array($cached_less_compile) || $new_cache['updated'] > $cached_less_compile['updated']) {
             $cache_handler->set($cssfile_md5, $new_cache);
             $tmp_ouput_file = tempnam(dirname($css_file_path), 'gantry_less');
             $header = '';
             if ($this->get('less-debugheader', false)) {
                 $header .= sprintf("/*\n * Main File : %s", str_replace(JURI::root(true), '', $less_file_url));
                 if (!empty($options)) {
                     $header .= sprintf("\n * Variables :\n %s", $options_string);
                 }
                 if (count($new_cache['files']) > 1) {
                     $included_files = array_keys($new_cache['files']);
                     unset($included_files[0]);
                     array_walk($included_files, create_function('&$v,$k', 'global $gantry;$v=" * ".$gantry->convertToUrl($v);'));
                     $header .= sprintf("\n * Included Files : \n%s", implode("\n", str_replace(JURI::root(true), '', $included_files)));
                 }
                 $header .= "\n */\n";
             }
             file_put_contents($tmp_ouput_file, $header . $new_cache['compiled']);
             // Do the messed up file renaming for windows
             if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
                 $move_old_file_name = tempnam(dirname($css_file_path), 'gantry_less');
                 if (is_file($css_file_path)) {
                     @rename($css_file_path, $move_old_file_name);
                 }
                 @rename($tmp_ouput_file, $css_file_path);
                 @unlink($move_old_file_name);
             } else {
                 @rename($tmp_ouput_file, $css_file_path);
             }
             JPath::setPermissions($css_file_path);
         }
         $quick_expire_cache->clear($cssfile_md5 . '-compiling');
     }
     $this->addStyle($css_passed_path, $priority);
     if (!empty($css_append) && !is_null($cssfile) && dirname($cssfile) == '.') {
         $this->addStyle($cssfile, $priority);
     }
 }