Fundamentals of Software Architecture: An Engineering Approach