CLN/INT: remove Index as a sub-class of NDArray

make ``Index`` now subclass ``PandasObject/IndexOpsMixin`` rather than ``ndarray``
should allow much easier new Index classes (e.g. #7640)

This doesn't change the public API at all, and provides compat (with exception of a very minor ``DatetimeIndex`` comparison with ndarrays)

closes #5080, preserves pickle compat for >= 0.8.0
back compat for pickles is now way simpler

This removed pickle compat for < 0.8.0 (well I think it does but can't really prove it). maybe can add it back if strong interest.

ToDo:

- docs
  - [x] release note
  - [x] warnings in io.rst about this change
  - [x] pickle compat now > 0.8.0
  - [x] fixes ``.repeat`` on MultiIndex (broken in master)
  - [x] minor API compat issue with comparisons of ``DatetimeIndex`` with ``NaT`` vs ndarrays
- [x] merge with searchsorted issues/PR ( #6712, #7447, #6469)
- [x] tests fixed (FIXMES), just a few left
- [x] perf
- [x] json completely broken ATM
- [x] #7796 FIXME (PeriodIndex not supported in HDF), not really a big deal
- [x] #7439 since ``Index`` now doesn't have implicit ops (aside from ``__sub__/__add__``, these need to be added in (e.g. ``__mul__,__div__,__truediv__``).
- [x] bool(Index/MultiIndex) : https://github.com/pydata/pandas/issues/7897 (will address this later)

closes #5155 (perf fix for Period creation), slight increase on the plotting
because of the the plottling routines holding array of Periods (rather than PeriodIndex).
```
-------------------------------------------------------------------------------
Test name                                    | head[ms] | base[ms] |  ratio   |
-------------------------------------------------------------------------------
period_setitem                               |  16.2210 | 122.9340 |   0.1319 |
timeseries_iter_periodindex                  | 1197.7839 | 6906.1464 |   0.1734 |
timeseries_iter_periodindex_preexit          |  12.4850 |  69.8563 |   0.1787 |
timeseries_period_downsample_mean            |  11.2850 |  11.1457 |   1.0125 |
plot_timeseries_period                       | 107.6056 |  86.5277 |   1.2436 |
```
this was all a kludge to avoid repeating code, their is exacttly 1 case where I need this: ``reduce.pyx/Reducer``. Basically need to make a complete copy of an object including a deep copy of its index.

``deep=True`` does not copy the actual data, rather it is a view on it. This preserves numpy semantics so memory is shared. We never actually *need* to copy index data memory as these are immutable and so cannot be changed. We always just create a new object (with possibly shared memory).

Meta-data is a different story (e.g. ``.name``), where we almost always want/need to copy this (e.g. ``.view`` uses ``._shallow_copy`` for this purpose).

However, in this reducer because of how it actually messes with the pointers, I do actually need to copy the memory.

I needed a 'private' way of doing that. So either make ``axes`` private, or just overload ``deep`` (default is still always ``True``). Will change to ``deep=True|False|'all'``. 

The user *never* needs to actually copy the index data as it is a view and numpy takes care of that. This is an internal usage.