function uninstall(&$STACK, $addon)
{
    $INSTALLED = array();
    $STACK->rewind();
    foreach ($STACK as $item) {
        $INSTALLED[] = $item;
    }
    // Check dependencies for this $addon - recurse if necessary
    $dependencies = SchemesManager::getUninstallDependencies($addon);
    if (!empty($dependencies)) {
        foreach ($dependencies as $shortcode => $name) {
            // print "$addon depends on $shortcode\n";
            if (!in_array($shortcode, $INSTALLED)) {
                uninstall($STACK, $shortcode);
            } else {
                echo "warning: {$addon} already uninstalled\n";
            }
        }
    }
    if (!isset($INSTALLED) || !in_array($addon, $INSTALLED)) {
        $result = fn_uninstall_addon($addon, true);
        if (empty($result)) {
            echo "could not uninstall '{$addon}' - aborting...\n\n";
            echo "Re-installing previously uninstalled addons to restore system to good state\n";
            foreach ($STACK as $item) {
                $addon = $STACK->pop();
                fn_install_addon($addon, true, false);
                fn_update_addon_status($addon, 'A', true, false);
                print "INSTALL: {$addon}\n";
            }
            exit;
        }
        echo "UNINSTALL: {$addon}\n";
        $STACK->push($addon);
    }
}
/**
 * Uninstalles addon
 *
 * @param string $addon_name Addon name to be uninstalled
 * @param bool $show_message If defined as true, additionally show notification
 * @return bool True if addons uninstalled successfully, false otherwise
 */
function fn_uninstall_addon($addon_name, $show_message = true)
{
    $addon_scheme = SchemesManager::getScheme($addon_name);
    if ($addon_scheme != false) {
        // Unmanaged addons can be uninstalled via console only
        if ($addon_scheme->getUnmanaged() && !defined('CONSOLE')) {
            return false;
        }
        // Check dependencies
        $dependencies = SchemesManager::getUninstallDependencies($addon_name);
        if (!empty($dependencies)) {
            fn_set_notification('W', __('warning'), __('text_addon_uninstall_dependencies', array('[addons]' => implode(',', $dependencies))));
            return false;
        }
        // Execute custom functions for uninstall
        $addon_scheme->callCustomFunctions('uninstall');
        $addon_description = db_get_field("SELECT name FROM ?:addon_descriptions WHERE addon = ?s and lang_code = ?s", $addon_name, CART_LANGUAGE);
        // Delete options
        db_query("DELETE FROM ?:addons WHERE addon = ?s", $addon_name);
        db_query("DELETE FROM ?:addon_descriptions WHERE addon = ?s", $addon_name);
        // Delete settings
        $section = Settings::instance()->getSectionByName($addon_name, Settings::ADDON_SECTION);
        if (isset($section['section_id'])) {
            Settings::instance()->removeSection($section['section_id']);
        }
        // Delete language variables
        $addon_scheme->uninstallLanguageValues();
        // Revert database structure
        $addon_scheme->processQueries('uninstall', Registry::get('config.dir.addons') . $addon_name);
        // Remove product tabs
        ProductTabs::instance()->deleteAddonTabs($addon_name);
        fn_uninstall_addon_templates(fn_basename($addon_name));
        if (file_exists(Registry::get('config.dir.addons') . $addon_name . '/layouts.xml')) {
            $xml = simplexml_load_file(Registry::get('config.dir.addons') . $addon_name . '/layouts.xml', '\\Tygh\\ExSimpleXmlElement', LIBXML_NOCDATA);
            foreach ($xml->location as $location) {
                if (fn_allowed_for('ULTIMATE')) {
                    foreach (fn_get_all_companies_ids() as $company) {
                        $layouts = Layout::instance($company)->getList();
                        foreach ($layouts as $layout_id => $layout) {
                            Location::instance($layout_id)->removeByDispatch((string) $location['dispatch']);
                        }
                    }
                } else {
                    $layouts = Layout::instance()->getList();
                    foreach ($layouts as $layout_id => $layout) {
                        Location::instance($layout_id)->removeByDispatch((string) $location['dispatch']);
                    }
                }
            }
        }
        if ($show_message) {
            fn_set_notification('N', __('notice'), __('text_addon_uninstalled', array('[addon]' => $addon_scheme->getName())));
        }
        //Clean Registry
        Registry::del('addons.' . $addon_name);
        $hooks = Registry::get('hooks');
        Registry::del('hooks');
        if (!empty($hooks)) {
            foreach ($hooks as $hook_name => $hooks_data) {
                foreach ($hooks_data as $key => $hook_data) {
                    if ($hook_data['addon'] === $addon_name) {
                        unset($hooks[$hook_name][$key]);
                    }
                }
            }
        }
        Registry::set('hooks', $hooks);
        // Clean cache
        fn_clear_cache();
        return true;
    } else {
        return false;
    }
}