Modeling Software with Finite State Machines: A Practical Approach