Issue #20 - hashjoin implementation

1. JoinCompiler:
    Basically organizes conditions in "on clause" into three categories: a) join conditions, b) pre-filters that can be done with scan filters; c) post-filters that should be applied against the joined result.
    Also provides facilities for re-constructing a subquery out of a join table, testing star-join types, etc.

2. Runtime projection:
    One of the biggest problem with join is column name conflicts in a joined result. Currently we are using column family renaming strategy by prefixing column families with its corresponding table name (or table alias name).
    With rowkey columns, it can be even trickier. We search for a specific rowkey column by locating a KeyValue in the result list with the specified column family prefix. For that purpose, we had to add a new method in Tuple:
    public boolean getKey(ImmutableBytesWritable ptr, byte[] cfPrefix)