Distributed systems now encounter extreme heterogeneity in the form of diverse devices, network types etc., and also need to dynamically adapt to changing environmental conditions. Self-adaptive middleware is ideally situated to address these challenges. However, developing such software is a complex task. In this paper, we present the Gridkit self* approach to the engineering of reflective middleware; this embraces state of the art software engineering practices, and flexible dynamic adaptation mechanisms to better support system developers. Domain specific frameworks are modeled and developed to enhance configurability and reconfigurability. We evaluate this approach using case studies in the domains of service discovery and network overlays. These demonstrate the benefits of the approach in terms of aiding and simplifying the process of creating self-configuring and self-adaptive software.