Recovering Use Case models from Object-Oriented Code: a Thread-based Approach