A Framework for Checking Programmer-Defined Constraints on the Definition and Use of Program Elements in Java