ENH: Make core/index exceptions more descriptive

* `assert_copy`: You can use `assert_copy` to check that two iterables
  produce copies that are not the same object. (uses `assert_almost_equal`
  under the hood).
* Fix assert_almost_equal to handle non-ndarrays (previously failed
  after iterable check)
* Fix test_mixed_panel to reflect true name behavior
ENH: Index inherits from FrozenNDArray + add FrozenList

* `FrozenNDArray` - thin wrapper around ndarray that disallows setting methods
  (will be used for levels on `MultiIndex`)
* `FrozenList` - thin wrapper around list that disallows setting methods
  (needed because of type checks elsewhere)

Index inherits from FrozenNDArray now and also actually copies for deepcopy.
Assumption is that underlying array is still immutable-ish
BUG/ENH: Make names, levels and labels properties.

* `names` is now a property *and* is set up as an immutable tuple.
* `levels` are always (shallow) copied now and it is deprecated to set directly
* `labels` are set up as a property now, moving all the processing of
  labels out of `__new__` + shallow-copied.
* `levels` and `labels` are immutable.
* Add names tests, motivating example from #3742, reflect tuple-ish
  output from names, and level names check to reindex test.
* Add set_levels, set_labels, set_names and rename to index
* Deprecate setting labels and levels directly

Similar to other set_* methods...allows mutation if necessary but
otherwise returns same object.

Labels are now converted to `FrozenNDArray` and wrapped in a
`FrozenList`. Should mostly resolve #3714 because you have to work to
actually make assignments to an `Index`.

BUG: Give MultiIndex its own astype method

Fixes issue with set_value forgetting names.
ENH: Additional keyword arguments for Index.copy()

* Index derivatives can set `name` or `names` as well as
  `dtype` on copy. MultiIndex can set `levels`, `labels`, and `names`.
* Also, `__deepcopy__` just calls `copy(deep=True)`
* Now, BlockManager.copy() takes an additional argument `copy_axes` which
  copies axes as well. Defaults to False.
* `Series.copy()` takes an optional deep argument, which causes it to
  copy its index.
* `DataFrame.copy()` passes `copy_axes=True` when deepcopying.
* Add copy kwarg to MultiIndex `__new__`
BUG: Fixes issue #3334: brittle margin computation in pivot_table

Adds support for margin computation when all columns are used in rows and cols.

DOC: Fixed release notes

BUG: Fixed failing test due to use of basestring in python 3
Merge branch 'guyrt-fix-brittle-pivot-margins'

Conflicts:
	doc/source/release.rst
	pandas/tools/pivot.py
Merge pull request #4513 from jreback/hdf_per

BUG: read_hdf was not respecting a passed mode (GH4504)
BUG: (GH4532) Fix bug in having a rhs of np.timedelta64 or np.offsets.DateOffset when operating
     with datetimes
BUG: (GH4134) Fix arithmetic with series/datetimeindex and np.timedelta64 not working the same
TST: add in @cpcloud tests related to GH4135