Applying Case-Based Reasoning to Code Understanding and Generation