ENH: Add FrozenList and FrozenNDArray types

* `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)

TST: Additional test cases for immutable containers
ENH: Have index inherit from FrozenNDArray

Index inherits from FrozenNDArray now and also returns a shallow copy
through deep copy (otherwise, could deepcopy and change metadata).
Assumption is that underlying array is still immutable-ish
ENH: Levels, labels immutable + add set methods.

ENH: Use FrozenList for levels, labels in index

ENH: Add set_levels, set_names and rename to index

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`.

ENH: Actual deprecation of direct setting of levels and labels
ENH: Index.copy() now takes keyword arguments.

Index derivatives can set `name` or `names` as well as
`dtype` on copy. MultiIndex can set `levels`, `labels`, and `names`.
DOC: Changes to Index and MultiIndex
workaround for FrozenList strict type check
ENH: Add deep=True kwarg to copy and fix copying.

Also, `__deepcopy__` just calls `copy()`
ENH: Add copy kwarg to MultiIndex direct constructor