#include <iomanip>
#include <iostream>

class ScopedIndent
{
public:
    ScopedIndent() : _indent(_indentLevel) { _indentLevel += 4 ; }
    ~ScopedIndent() { _indentLevel -= 4 ; }

    friend std::ostream& operator<<(std::ostream& os, const ScopedIndent& id) ;

private:
    unsigned _indent ;
    static unsigned _indentLevel ;
};

unsigned ScopedIndent::_indentLevel = 0 ;

std::ostream& operator<<(std::ostream& os, const ScopedIndent& id )
{
    return os << std::setw(id._indent) << "" ;
}


struct Node {
   int data;
   Node* left ;
   Node* right ;

   Node(int i) : data(i), left(0), right(0) {}
};


void add( Node*& root, int num )
{
    if ( root == 0 )
    {
        root = new Node(num) ;
        return ;
    }

    if ( num < root->data )
        add(root->left, num) ;
    else
        add(root->right, num) ;
}

void destroy(Node* root)
{
    if (root != 0)
    {
        destroy(root->left) ;
        destroy(root->right) ;
        delete root ;
    }
}

void inOrder( const Node* node )
{
    ScopedIndent id ;
    if ( node )
        std::cout << id << "Begin inOrder: " << node << '\n' << id << "{\n" ;
    else
        std::cout << id << "NULL\n" ;

    if ( node != 0 )
    {
        ScopedIndent id ;
        std::cout << id << "Left:\n" ;
        inOrder(node->left) ;

        std::cout << '\n' << id << "Data: " << node->data << "\n\n" ;

        std::cout << id << "Right:\n" ;
        inOrder(node->right) ;
    }

    if ( node )
        std::cout << id << "}\n" ;
}

int main ()
{
    Node * root = new Node(1) ;
    add(root, -3) ;
    add(root, 2) ;
    add(root, 5) ;

    inOrder(root) ;
    destroy(root) ;
}