CompareFilter uses a combination of composition and inheritance that implicitly encourages changing the object's behavior after construction time.
We can clean this up by deprecating getCompareString and getEncodedValue and requiring those in a protected constructor. In this way, all the data that CompareFilter needs is in final fields.