public function render( $file = null, $eol = null )
    {
        static $escape = array( '"' => '\\"' );
        $renderer   = AbstractRenderer::factory( $file, $eol );
        $eol        = $renderer->getEol();

        $renderer->writeLine(
            '@charset "' . strtr( static::RENDER_CHARSET, $escape ) . '";'
        );

        if ( ! $this->comment && $this->extra && $this->extra->updated )
        {
            $this->comment = $this->extra
                                  ->updated
                                  ->format( DateTime::ISO8601 );
        }

        if ( $this->comment )
        {
            $commentLines = array_map(
                function ( $line ) {
                    return ' * ' . $line;
                },
                preg_split( '/\s*[\n\r]+\s*/', $this->comment )
            );

            array_unshift( $commentLines, $eol . '/**' );
            array_push( $commentLines, ' */' );

            foreach ( $commentLines as $comment )
            {
                $renderer->writeLine( $comment );
            }
        }

        foreach ( $this->imports as $import )
        {
            $renderer->writeLine(
                '@import url("' . strtr( $import, $escape ) . '");' . $eol
            );
        }

        $media = '';
        foreach ( $this->rules as $rule )
        {
            $newMedia = (string) $rule->media;

            if ( $media != $newMedia )
            {
                if ( $media )
                {
                    $renderer->writeLine( '}' . $eol );
                }

                $media = $newMedia;
                $renderer->writeLine( '@media ' . $media . $eol . '{' . $eol );
            }

            $rawPropertyNames = $rule->getRawPropertyNames();

            if ( ! empty( $rawPropertyNames ) )
            {
                $renderer->writeLine(
                    ( $media ? "\t" : '' ) .
                    $rule->selector . $eol .
                    ( $media ? "\t" : '' ) . '{'
                );

                foreach ( $rawPropertyNames as $propery )
                {
                    $renderer->writeLine(
                        ( $media ? "\t" : '' ) .
                        "\t" . $propery . ': ' .
                        $rule->getRawPropertyValue( $propery ) .
                        $rule->getRawPropertyPostfix( $propery ) . ';'
                    );
                }

                $renderer->writeLine( ( $media ? "\t" : '' ) . '}' . $eol );
            }
        }

        if ( $media )
        {
            $renderer->writeLine( '}' );
        }

        if ( $this->hasExtraContent() )
        {
            $renderer->writeLine( $eol . $this->getExtraContent() );
        }

        return $renderer;
    }