public static function getAvailableViewDataTables()
    {
        $cache = Cache::getTransientCache();
        $cacheId = 'ViewDataTable.getAvailableViewDataTables';
        $dataTables = $cache->fetch($cacheId);

        if (!empty($dataTables)) {
            return $dataTables;
        }

        $klassToExtend = '\\Piwik\\Plugin\\ViewDataTable';

        /** @var string[] $visualizations */
        $visualizations = PluginManager::getInstance()->findMultipleComponents('Visualizations', $klassToExtend);

        $result = array();

        foreach ($visualizations as $viz) {
            if (!class_exists($viz)) {
                throw new \Exception("Invalid visualization class '$viz' found in Visualization.getAvailableVisualizations.");
            }

            if (!is_subclass_of($viz, $klassToExtend)) {
                throw new \Exception("ViewDataTable class '$viz' does not extend Plugin/ViewDataTable");
            }

            $vizId = $viz::getViewDataTableId();

            if (isset($result[$vizId])) {
                throw new \Exception("ViewDataTable ID '$vizId' is already in use!");
            }

            $result[$vizId] = $viz;
        }

        /**
         * Triggered to filter available DataTable visualizations.
         *
         * Plugins that want to disable certain visualizations should subscribe to
         * this event and remove visualizations from the incoming array.
         *
         * **Example**
         *
         *     public function filterViewDataTable(&$visualizations)
         *     {
         *         unset($visualizations[HtmlTable::ID]);
         *     }
         *
         * @param array &$visualizations An array of all available visualizations indexed by visualization ID.
         * @since Piwik 3.0.0
         */
        Piwik::postEvent('ViewDataTable.filterViewDataTable', array(&$result));

        $cache->save($cacheId, $result);

        return $result;
    }