public function outputModule($module, $args = array(), $moduleSettings = array(), $echo = true)
    {
        if (!isset($args['id'])) {
            $args['id'] = 'no-id';
        }

        if (!is_object($module)) {
            return false;
        }

        $class = \Modularity\ModuleManager::$classes[$module->post_type];
        $module = new $class($module, $args);
        $module = $this->fillMissingParams($module, $moduleSettings);

        if (!$echo || !isset($moduleSettings['cache_ttl'])) {
            $moduleSettings['cache_ttl'] = 0;
        }

        $cache = new \Modularity\Helper\Cache($module->ID, array($module, $args['id']), $moduleSettings['cache_ttl']);

        if (empty($moduleSettings['cache_ttl']) || $cache->start()) {
            $moduleMarkup = $this->getModuleMarkup($module, $args);

            if (isset($module->columnWidth) && !empty($module->columnWidth)) {
                $moduleMarkup .= apply_filters('Modularity/Display/AfterModule', '</div>', $args, $module->post_type, $module->ID);
            } elseif (isset($this->options[$args['id']]['after_module']) && !empty($this->options[$args['id']]['after_module'])) {
                $moduleMarkup .= apply_filters('Modularity/Display/AfterModule', '</div>', $args, $module->post_type, $module->ID);
            } elseif (isset($args['after_widget'])) {
                $moduleMarkup .= apply_filters('Modularity/Display/AfterModule', $args['after_widget'], $args, $module->post_type, $module->ID);
            }

            $moduleMarkup = apply_filters('Modularity/Display/Markup', $moduleMarkup, $module);
            $moduleMarkup = apply_filters('Modularity/Display/' . $module->post_type . '/Markup', $moduleMarkup, $module);

            if (!$echo) {
                return $moduleMarkup;
            }

            echo $moduleMarkup;

            if (!empty($moduleSettings['cache_ttl'])) {
                $cache->stop();
            }
        }

        return true;
    }