Block redistribution

Working implementation of block (and no-dist) redistribution.

Two main cases:

* global shape preserving redistribution, and
* reshaping redistribution.

Both cases support redistribution on a different set of targets.  The source and destination targets can be identical, overlapping, or disjoint.  

Some small performance optimizations are implemented, but there is much room for improvement.   This version just gets general redistribution working; future work will need to address performance and optimizations.
Should also be test_ipython_with_coverage