A model-based framework for building self-adaptive distributed software