My submission for the Aconex 1800 coding challenge. It was rejected with the following reason: “The code suffers from long methods and missed abstraction opportunities. These would probably have presented themselves more obviously in a truly test-driven solution.”