ClientConfig and related class act more like values

If an application keeps a ClientConfig object around for any non-trivial amount of time, or wants to control changes to it, or needs to check whether it has changed, it's not very easy: the class is mutable, it doesn't allow straightforward copying, and it doesn't allow easy comparison. I addressed most of those concerns by making sure that it, and its related types, act more like proper "value" POJOs: they all now provide `toString`, `equals`, `hashCode`, and copy construction. (Immutability will have to wait for another day.)