Self-adaptation enables a software-intensive system to adapt autonomously to achieve its goals, regardless of uncertainties the system faces during operation. Self-adaptation has been the subject of active research for over two decades, and has gained momentum only recently. As a result, there is now a broad consensus in the software engineering community that self-adaptation will be the key enabling feature to tackle the challenges of managing uncertainty of new emerging and future software-intensive systems. Currently, there is no comprehensive book available for students, researchers and engineers that introduces the foundations and engineering principles of self-adaptation. This book aims to close this gap. It is unique in taking a systematic and holistic approach, and includes a set of applications to illustrate the material with actual examples.