protected function user_print_r($subject, $ignore = array(), $depth = 1, $refChain = array())
    {
        static $maxDepth = 5;
        if ($depth > 20) {
            return;
        }
        if (is_object($subject)) {
            foreach ($refChain as $refVal) {
                if ($refVal === $subject) {
                    echo "*RECURSION*\n";

                    return;
                }
            }
            array_push($refChain, $subject);
            echo get_class($subject) . " Object ( \n";
            $subject = (array)$subject;
            foreach ($subject as $key => $val) {
                if (is_array($ignore) && !in_array($key, $ignore, 1)) {
                    echo str_repeat(" ", $depth * 4) . '[';
                    if ($key{0} == "\0") {
                        $keyParts = explode("\0", $key);
                        echo $keyParts[2] . (($keyParts[1] == '*')
                                ? ':protected'
                                : ':private');
                    } else {
                        echo $key;
                    }
                    echo '] => ';
                    if ($depth == $maxDepth) {
                        return;
                    }
                    $this->user_print_r($val, $ignore, $depth + 1, $refChain);
                }
            }
            echo str_repeat(" ", ($depth - 1) * 4) . ")\n";
            array_pop($refChain);
        } elseif (is_array($subject)) {
            echo "Array ( \n";
            foreach ($subject as $key => $val) {
                if (is_array($ignore) && !in_array($key, $ignore, 1)) {
                    echo str_repeat(" ", $depth * 4) . '[' . $key . '] => ';
                    if ($depth == $maxDepth) {
                        return;
                    }
                    $this->user_print_r($val, $ignore, $depth + 1, $refChain);
                }
            }
            echo str_repeat(" ", ($depth - 1) * 4) . ")\n";
        } else {
            echo $subject . "\n";
        }
    }