We present an approach to self-adaptive systems utilizing explicit models of the design-space of the application. The design-space is captured by allowing the specification of alternatives for any component at any level in the model hierarchy. Non-functional requirements and additional knowledge about the system are captured in the form of OCL constraints parameterized by operational parameters, such as latency, accuracy, error rate, etc, that are measured at run-time. The constraints and the models are embedded in the running system forming the operation-space of the application. When changes in the monitored parameters trigger a reconfiguration, the operation space is explored utilizing a symbolic constraint satisfaction method relying on OBDDs. Once a new configuration that satisfies all the constraints is found the reconfiguration takes place.