BUG: Various inconsistencies in DataFrame __getitem__ and __setitem__ behavior (fixes #2765) (merged commits)

see #2765, #2766 (previous version of this PR)

Note, to address " __getitem__ does not reindex boolean Series key but __setitem__ does ", I have changed the __getitem__ behavior rather than the __setitem__ behavior because it is more consistent with other indexing behavior and does not break any tests...just in case, I have inserted a warning about this happening (which only triggers when a reindex is actually required)

Also, in addition to resolving the bugs, I have refactored the code to make __getitem__ and __setitem__ code paths as symmetric as possible, in order to help prevent more issues in the future.

Unit test coverage added, and performance tests show no impact