protected function combineMinify()
    {
        $type = $this->options['contentType']; // ease readability

        // when combining scripts, make sure all statements separated and
        // trailing single line comment is terminated
        $implodeSeparator = ($type === self::TYPE_JS) ? "\n;" : '';

        // allow the user to pass a particular array of options to each
        // minifier (designated by type). source objects may still override
        // these
        if (isset($this->options['minifierOptions'][$type])) {
            $defaultOptions = $this->options['minifierOptions'][$type];
        } else {
            $defaultOptions = array();
        }

        // if minifier not set, default is no minification. source objects
        // may still override this
        if (isset($this->options['minifiers'][$type])) {
            $defaultMinifier = $this->options['minifiers'][$type];
        } else {
            $defaultMinifier = false;
        }

        // process groups of sources with identical minifiers/options
        $content = array();
        $i = 0;
        $l = count($this->sources);
        $groupToProcessTogether = array();
        $lastMinifier = null;
        $lastOptions = null;
        do {
            // get next source
            $source = null;
            if ($i < $l) {
                $source = $this->sources[$i];
                $sourceContent = $source->getContent();

                // allow the source to override our minifier and options
                $minifier = $source->getMinifier();
                if (!$minifier) {
                    $minifier = $defaultMinifier;
                }
                $options = array_merge($defaultOptions, $source->getMinifierOptions());
            }
            // do we need to process our group right now?
            if ($i > 0                               // yes, we have at least the first group populated
                && (
                    ! $source                        // yes, we ran out of sources
                    || $type === self::TYPE_CSS      // yes, to process CSS individually (avoiding PCRE bugs/limits)
                    || $minifier !== $lastMinifier   // yes, minifier changed
                    || $options !== $lastOptions)) { // yes, options changed
                // minify previous sources with last settings
                $imploded = implode($implodeSeparator, $groupToProcessTogether);
                $groupToProcessTogether = array();
                if ($lastMinifier) {
                    try {
                        $content[] = call_user_func($lastMinifier, $imploded, $lastOptions);
                    } catch (Exception $e) {
                        throw new Exception("Exception in minifier: " . $e->getMessage());
                    }
                } else {
                    $content[] = $imploded;
                }
            }
            // add content to the group
            if ($source) {
                $groupToProcessTogether[] = $sourceContent;
                $lastMinifier = $minifier;
                $lastOptions = $options;
            }
            $i++;
        } while ($source);

        $content = implode($implodeSeparator, $content);

        if ($type === self::TYPE_CSS && false !== strpos($content, '@import')) {
            $content = $this->handleCssImports($content);
        }

        // do any post-processing (esp. for editing build URIs)
        if ($this->options['postprocessorRequire']) {
            require_once $this->options['postprocessorRequire'];
        }
        if ($this->options['postprocessor']) {
            $content = call_user_func($this->options['postprocessor'], $content, $type);
        }

        return $content;
    }