Big refctor of rez.rex:  merged recording and interpreting.  There is now a CommandExecutor, which receiveds a CommandInterpreter for a specific shell on instantiation.  As the executor receives each callback from the Rex python session, it handles all of the book-keeping -- tracking env, recording changes -- and then calls the interpreter's callback immediately.  Thus there is no more concept of a list of recorded command which are then interpreted at a later time. Commands are interpreted immediately.  This should eliminate the order-of-execution gotchas we keep encountering, including now the ability to make decisions based on shell: i.e. if system.shell: do something.

other changes:
- move all command execution from rez.config into rez.rex
- Resolver.resolve() has more results to return now, so changed it to return a ResolveResult class for attribute-based access.  may change this to a dict to keep it simple.