BUG: Various inconsistencies in DataFrame getitem/setitem behavior (fixes #2765)
fixes #2765 

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

(Will avoid the new PR next time...didn't realize I could force the rebased push without breaking GitHub)
 cherry picked this. thanks
