Add a unified and optionally more constrained API for expressing filters on columns

This is a re-opened version of:
https://github.com/Parquet/parquet-mr/pull/412

The idea behind this pull request is to add a way to express filters on columns using DSL that allows parquet visibility into what is being filtered and how. This visibility will allow us to make optimizations at read time, the biggest one being filtering entire row groups or pages of records without even reading them based on the statistics / metadata that is stored along with each row group or page.

Included in this api are interfaces for user defined predicates, which must operate at the value level by may opt in to operating at the row group / page level as well. This should make this new API a superset of the `parquet.filter` package. This new api will need to be reconciled with the column filters currently in the `parquet.filter` package, but I wanted to get feedback on this first.

A limitation in both this api and the old one is that you can't do cross-column filters, eg: columX > columnY.
So, this Optional is a stand-in for the one in Guava (but we don't want to depend on guava -- though maybe we should do ourselves a favor and just depend on it + shade it). It presents a very similar API.

Side note: Guava does take the approach of having a subclass `Absent` and `Present` though as I was writing this I wasn't really sure what that buys you?

The reasoning behind Optional even without lambdas is that carries the equivalent information of a `@Nullable` wherever it goes. If you have a large method that takes a `@Nullable` as a parameter, you may forget that your variable was nullable, but you can't forget that an Optional is Optional. Also, using `@Nullable` still promotes heavy use of nulls which I'm not a huge fan of.

As for using `@NotNull` I think that'd be great.

If you think this Optional is overkill we can delete it. Null is used fairly frequently in the rest of the codebase. If you look at where I use Optional in this PR though, you'll see it's for a variable that gets passed through about three different layers of constructors / methods etc. We would need to make all those `@Nullable` as well, which is not compiler enforced.