function list_files()
 {
     global $option;
     // filesystem functions
     jimport('joomla.filesystem.folder');
     jimport('joomla.filesystem.file');
     // variables
     global $mainframe;
     $options = Language_manager::getOptions();
     $user =& JFactory::getUser();
     $userid = $user->get('id', 0);
     // build client_lang select box
     foreach ($options['languages'] as $k => $v) {
         $sel_lang[] = JHTML::_('select.option', $k, $v);
     }
     $lists['client_lang'] = JHTML::_('select.genericlist', $sel_lang, 'client_lang', 'class="inputbox" size="1" onchange="document.adminForm.limitstart.value=0;document.adminForm.submit( );"', 'value', 'text', $options['client_lang']);
     // validate all the filters (specific to this view)
     $allowed = array('client_lang' => '', 'filter_search' => '', 'filter_state' => '*|U|P', 'filter_status' => '*|NS|IP|C', 'filter_order' => 'name|status|strings|version|datetime|author', 'filter_order_Dir' => 'asc|desc', 'limit' => $mainframe->getCfg('list_limit'));
     $filters = Language_manager::_buildfilters($allowed, $option . '.files.');
     // copy to $options
     $options = array_merge($options, $filters);
     // copy to $lists
     $lists['order'] = $options['filter_order'];
     $lists['order_Dir'] = $options['filter_order_Dir'];
     // validate and build the filter_search box
     $options['dosearch'] = '';
     if ($options['filter_search']) {
         // 1: turn it into a case-insensitive regexp
         // 2: check and use a submitted regexp
         // 3: invalid regexp
         if ($options['filter_search'][0] != '/') {
             $options['dosearch'] = '/.*' . trim($options['filter_search'], '/') . '.*/i';
         } else {
             if (@preg_match($options['filter_search'], '') !== false) {
                 $options['dosearch'] = $options['filter_search'];
             } else {
                 $mainframe->enqueueMessage(JText::_('Search') . ': ' . sprintf(JText::_('Invalid RegExp'), htmlentities($options['filter_search'])), 'error');
                 $options['filter_search'] = '';
             }
         }
     }
     $lists['search'] = '<input name="filter_search" id="filter_search" class="inputbox" "type="text" value="' . htmlspecialchars($options['filter_search'], ENT_QUOTES) . '" onchange="this.form.submit();" size="15" />';
     // build the filter_state select box
     $extra = 'class="inputbox" size="1" onchange="document.adminForm.submit();"';
     $sel_state[] = JHTML::_('select.option', '*', JText::_('Any State'));
     $sel_state[] = JHTML::_('select.option', 'P', JText::_('Published'));
     $sel_state[] = JHTML::_('select.option', 'U', JText::_('Not Published'));
     $lists['state'] = JHTML::_('select.genericlist', $sel_state, 'filter_state', $extra, 'value', 'text', $options['filter_state']);
     // build the filter_status select box
     $sel_status[] = JHTML::_('select.option', '*', JText::_('Any Status'));
     $sel_status[] = JHTML::_('select.option', 'NS', JText::_('Not Started'));
     $sel_status[] = JHTML::_('select.option', 'IP', JText::_('In Progress'));
     $sel_status[] = JHTML::_('select.option', 'C', JText::_('Complete'));
     if ($options['isReference']) {
         $options['filter_status'] = '*';
     }
     if ($options['lang'] == $options['refLang']) {
         $extra .= ' disabled';
     }
     $lists['status'] = JHTML::_('select.genericlist', $sel_status, 'filter_status', $extra, 'value', 'text', $options['filter_status']);
     // create objects for loading data
     $refLangLoader = new JLanguage($options['refLang']);
     $LangLoader = $options['lang'] == $options['refLang'] ? $refLangLoader : new JLanguage($options['lang']);
     // load all the the ini filenames (published or unpublished) from the reference directory
     // load the same from the selected language directory
     $opt_name = substr($option, 4);
     $refLangFiles = JFolder::files($options['refLangPath'], '^(xx|' . $options['refLang'] . ')[.].*' . $opt_name . '[.].*ini$');
     if ($options['isReference']) {
         $LangFiles = array_flip($refLangFiles);
     } else {
         $LangFiles = JFolder::files($options['langPath'], '^(xx|' . $options['lang'] . ')[.].*' . $opt_name . '[.].*ini$');
         $LangFiles = array_flip($LangFiles);
     }
     // build a composite filename list, keyed using the filename without language tag
     $allFiles = array();
     foreach ($refLangFiles as $v) {
         $k = preg_replace('/^(xx[.])*' . $options['refLang'] . '[.]/', '', $v);
         $allFiles[$k]['refLang'] = $v;
     }
     foreach ($LangFiles as $v => $k) {
         $k = preg_replace('/^(xx[.])*' . $options['lang'] . '[.]/', '', $v);
         $allFiles[$k]['lang'] = $v;
     }
     // get default metadata for the selected language
     $xmlData = TranslationsHelper::getXMLMeta($options['langPath'] . DS . $options['lang'] . '.xml');
     // process the reference language INI files and compare them against the files for the selected language
     $rows = array();
     $rowid = 1;
     foreach ($allFiles as $k => $v) {
         // get the content, bare filename, Meta and Strings from the reference language INI file
         // in some cases there may not be a reference language INI file
         if (isset($v['refLang'])) {
             $refContent = file($options['refLangPath'] . DS . $v['refLang']);
             $refFileName = substr($v['refLang'], 0, 3) == 'xx.' ? substr($v['refLang'], 3) : $v['refLang'];
             $fileName = $options['lang'] . substr($refFileName, $options['refLangLen']);
             $refStrings = array();
             $refMeta = TranslationsHelper::getINIMeta($refContent, $refStrings);
         } else {
             $refContent = array();
             $fileName = substr($v['lang'], 0, 3) == 'xx.' ? substr($v['lang'], 3) : $v['lang'];
             $refFileName = $options['refLang'] . substr($fileName, $options['langLen']);
             $refStrings = array();
             $refMeta = array('author' => '', 'date' => '', 'strings' => '', 'time' => '', 'version' => '');
         }
         // initialise the row
         $row = new StdClass();
         $row->author = $refMeta['author'];
         $row->bom = 'UTF-8';
         $row->checkedout = 0;
         $row->changed = 0;
         $row->date = $refMeta['date'];
         $row->extra = 0;
         $row->filename = $fileName;
         $row->id = $rowid++;
         $row->name = substr($row->filename, $options['langLen'] + 1, -4);
         $row->refexists = intval(isset($v['refLang']));
         $row->reffilename = $refFileName;
         $row->refstrings = $refMeta['strings'];
         $row->searchfound = 0;
         $row->status = 0;
         $row->strings = $refMeta['strings'];
         $row->time = $refMeta['time'];
         $row->unchanged = 0;
         $row->unpub_filename = 'xx.' . $row->filename;
         $row->version = $refMeta['version'];
         // 1: file is published
         // 2: file is unpublished
         // 3: file does not exist
         if (JFile::exists($options['langPath'] . DS . $row->filename)) {
             $row->exists = 1;
             $row->path_file = $options['langPath'] . DS . $row->filename;
             $row->published = 1;
             $row->writable = is_writable($row->path_file);
         } else {
             if (JFile::exists($options['langPath'] . DS . $row->unpub_filename)) {
                 $row->exists = 1;
                 $row->path_file = $options['langPath'] . DS . $row->unpub_filename;
                 $row->published = 0;
                 $row->writable = is_writable($row->path_file);
             } else {
                 $row->author = '';
                 $row->date = '';
                 $row->exists = 0;
                 $row->path_file = $options['langPath'] . DS . $row->unpub_filename;
                 $row->published = 0;
                 $row->status = 0;
                 $row->version = '';
                 $row->writable = 1;
             }
         }
         // get the checkout status of the selected file
         if ($content = @file_get_contents($options['langPath'] . DS . 'chk.' . $row->filename)) {
             $row->checkedout = strpos($content, '#' . $userid . '#') || strpos($content, '#0#') ? 0 : 1;
         }
         // scan an existing language file
         if (!$options['isReference'] && $row->exists) {
             $fileContent = file($row->path_file);
             $fileStrings = array();
             $fileMeta = TranslationsHelper::getINIMeta($fileContent, $fileStrings, $refStrings);
             if ($fileMeta['bom'] == 'UTF-8') {
                 foreach ($fileMeta as $k => $v) {
                     $row->{$k} = $v;
                 }
             } else {
                 $row->bom = $fileMeta['bom'];
                 $row->writable = 0;
             }
         } else {
             $fileContent = array();
             $fileStrings = array();
             $fileMeta = array();
         }
         // search the files
         // $refContent and $fileContent are arrays containing each line of the reference and translation file
         if ($options['dosearch']) {
             $row->searchfound_ref = preg_match_all($options['dosearch'], implode("\n", $refContent), $arr);
             if (!$options['isReference']) {
                 $row->searchfound_tran = preg_match_all($options['dosearch'], implode("\n", $fileContent), $arr);
             } else {
                 $row->searchfound_tran = $row->searchfound_ref;
             }
             $row->searchfound = $row->searchfound_ref + $row->searchfound_tran;
         }
         // set the datetime
         $row->datetime = $row->date . $row->time;
         // change the name
         if ($row->name == '') {
             $row->name = ' [core]';
         }
         // store the file
         $rows[$row->name] = $row;
     }
     // build the fileset totals and filter out rows we don't need/want
     $options['fileset-files'] = 0;
     $options['fileset-exists'] = 0;
     $options['fileset-published'] = 0;
     $options['fileset-refstrings'] = 0;
     $options['fileset-changed'] = 0;
     foreach ($rows as $k => $row) {
         // add to totals
         $options['fileset-files']++;
         $options['fileset-exists'] += $row->exists;
         $options['fileset-published'] += $row->published;
         $options['fileset-refstrings'] += $row->refstrings;
         $options['fileset-changed'] += $row->changed;
         // filter out searched items
         // filter out published or unpublished items
         // filter out status of items
         if ($options['dosearch'] && $row->searchfound == 0 || $options['filter_state'] == 'P' && $row->published != 1 || $options['filter_state'] == 'U' && $row->published != 0 || $options['filter_status'] == 'NS' && $row->status > 0 || $options['filter_status'] == 'IP' && ($row->status <= 0 || $row->status >= 100) || $options['filter_status'] == 'C' && $row->status < 100) {
             unset($rows[$k]);
         }
     }
     // set fileset status
     if ($options['fileset-changed'] == 0) {
         $options['fileset-status'] = 0;
     }
     if ($options['fileset-refstrings'] == $options['fileset-changed']) {
         $options['fileset-status'] = 100;
     } else {
         $options['fileset-status'] = floor($options['fileset-changed'] / $options['fileset-refstrings'] * 100);
     }
     // build the pagination
     jimport('joomla.html.pagination');
     $pageNav = new JPagination(count($rows), $options['limitstart'], $options['limit'], 'index.php?option=' . $option . '&amp;task=language_files');
     // sort the $rows array
     $order_Int = strtolower($lists['order_Dir']) == 'desc' ? -1 : 1;
     JArrayHelper::sortObjects($rows, $lists['order'], $order_Int);
     // slice the array so we only show one page
     $rows = array_slice($rows, $pageNav->limitstart, $pageNav->limit);
     // call the html view
     Language_manager_html::Show_files($rows, $options, $lists, $pageNav);
 }