In software environments that are built from separate modules, interactions frequently happen to be limited to well-defined interfaces between modules. Being able to interpose functionality in the midst of these boundaries, preserving physical encapsulation, has been recognized as very convenient from the extensibility point of view. This has motivated many different approaches to the problem, which are reviewed in this section.
In the first place, many systems provide interposition facilities for the system-call interface. Classical microkernels like Mach or recent kernels like Pebble are examples of it. It is possible to use these facilities to enable profiling (like strace in Linux) as well as functionality extension (like UFO). The usefulness of this kind of interposition has been the motivation for developing extension-enabling frameworks using system-call redirection, like COLA, Interposition Agents or SLIC.
Our approach differs from the above extension-enabling frameworks in that we do not rely on operating-system provided interposition services. Moreover, we are providing these facilities for interfaces between user-level modules.
Many of the techniques used inside operating-system kernels in order to dynamically accommodate functionality (like device drivers, stackable file systems  or other kernel modules) are working examples of extensibility and flexible composition. However, these techniques are focused to specific kernel interfaces, and its use is typically restricted to privileged users. There is a considerable amount of research on building extensible systems, a kind of systems that would allow generic, safe, and application-specific extensions (e.g. SPIN, VINO), although this research is biased towards safety concerns of in-kernel extensions.
In contrast to the above techniques, we are taking a generic approach. Our goal is to enable extensions to be attached at any available interface, by providing convenient binding mechanisms for these extensions. In addition, we are looking at backwards-compatible ways of extending the execution environment of today programs, without new kernel services.
Finally, there are also approaches to structured dynamic extension at user-level procedure-call boundaries. We can found it within advanced runtime environments (also known as ``component platforms''), like ORB implementations  and COM+ . These platforms allow subclassing of binary components, and their mechanisms (cross-component inheritance, containment or aggregation) can be seen as specialized forms of interposition. These platforms aim to provide component interoperability.
DITOOLS derives its extension and dynamic loading abilities directly from the system's ABI, exploiting physical encapsulation, and being largely independent of language and program development issues. In contrast, component platforms are tied to language encapsulation, and they usually need to enforce boundaries using object-oriented programming and interface definition languages. They are neither appropriate to extend nor to customize the execution environment of each and every program that runs in a given system.
We found also tools oriented to enable interposition aside of any object middleware, like Detours for Win32  and SLI for Solaris . In Detours, function calls are dynamically intercepted by re-writing function images in order to redirect the control flow to different locations. In contrast, SLI interposition is based on symbol preemption in the resolution mechanism. In this way, SLI can dynamically introduce profiling and tracing functionality into dynamically-linked programs without changing the program image. Last releases of Solaris include support for modifying bindings done by the runtime linker .
Tools like Detours and SLI are similar to DITOOLS in that they work at application-level and provide similar interposition facilities. However, they exhibit limitations on their abilities to control definitions and bindings that do not exist in our framework. In particular, we allow selective rebinding of references, while these tools can only do global redefinitions. Detours requires altering the text pages and performs very intrusive changes in the program (e.g. it changes memory references for the original definition). Symbols redefined by SLI will persist until the program exits. On the other hand, the Solaris runtime-linker support is a platform-specific approach that focuses on process monitoring.