public static function trace(array $trace, $return = false, $html = true, $withArgs = true)
        {
            $out    = '';
            if ($html) {
                $out .= '<pre>';
            }

            foreach ($trace as $i => $data) {
                // skip self
                if ($i == 0) {
                    continue;
                }

                // prepare method argments
                $args = array();
                if (isset($data['args']) && true === $withArgs) {
                    foreach ($data['args'] as $arg) {
                        $args[] = static::_formatCalledArgument($arg);
                    }
                }

                // prepare method's name
                if (isset($data['class']) && isset($data['function'])) {
                    if (isset($data['object']) && get_class($data['object']) != $data['class']) {
                        $className = get_class($data['object']) . '[' . $data['class'] . ']';
                    } else {
                        $className = $data['class'];
                    }
                    if (isset($data['object'])) {
                        $className .= sprintf('#%s#', spl_object_hash($data['object']));
                    }

                    $methodName = sprintf('%s%s%s(%s)',
                        $className,
                        isset($data['type']) ? $data['type'] : '->',
                        $data['function'],
                        join(', ', $args)
                    );
                } else if (isset($data['function'])) {
                    $methodName = sprintf('%s(%s)', $data['function'], join(', ', $args));
                }

                if (isset($data['file'])) {
                    $pos = strpos($data['file'], static::getRootPath());
                    if ($pos !== false) {
                        $data['file'] = substr($data['file'], strlen(static::getRootPath()) + 1);
                    }
                    $fileName = sprintf('%s:%d', $data['file'], $data['line']);
                } else {
                    $fileName = false;
                }

                if ($fileName) {
                    $out .= sprintf('#%d %s called at [%s]', $i, $methodName, $fileName);
                } else {
                    $out .= sprintf('#%d %s', $i, $methodName);
                }

                $out .= "\n";
            }

            if (true === $html) {
                $out .= '</pre>';
            }

            if (true === $return) {
                return $out;
            } else {
                echo $out;
                return true;
            }
        }