Dependency Directed Reasoning in the Analysis of Programs which Modify Complex Data Structures