I am interested in distributed computing systems, especially loosely-coupled, heterogeneous and failure-prone ones. My research approach encompasses formal models, algorithm design and analysis, and lower bounds and impossibility proofs. I am interested in problems that arise in a wide variety of contexts, whose common thread is the difficulties that arise from concurrency and uncertainty, especially that due to asynchrony and/or failures. The problems I have studied generally arise in providing infrastructure services (or "middleware") that can be used by end-user distributed applications, as opposed to the applications themselves. In more theoretical language, I have focused on ways to simulate more powerful (or better-behaved) systems on top of less powerful (or more poorly-behaved) systems. My papers can be divided (a little arbitrarily) into the following categories: providing clock synchronization and understanding the differences in computational power between different timing models; providing more reliable message-passing communication in networks; providing more powerful kinds of shared objects on top of weaker kinds of shared object or on top of message passing; and using modularity in the design and analysis of distributed algorithms. Recently I have been applying some of these ideas and approaches in new situations: mobile ad hoc networks, metamorphic robot systems, and randomized distributed data structures.