Index: tests/trampoline.py
===================================================================
--- tests/trampoline.py	(revision 0)
+++ tests/trampoline.py	(revision 0)
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+import exceptions
+import os
+import sys
+import weakref
+import types
+import collections
+
+# a simple coroutine trampoline; it's used by the
+# testCoroutinesApp() stress test in test_source
+class Trampoline(object):
+    freeze = object()
+
+    def __init__(self):
+        self._running = collections.deque()
+        self._frozen = {}
+
+    def add(self, coroutine):
+        thread_info = object()
+
+        self._running.append((thread_info, (coroutine, (), None, None)))
+
+        return thread_info
+
+    def run(self, thaw = [], values = {}, exceptions = {}):
+        self.thaw(*thaw)
+
+        while self._running:
+            (thread_info, (coroutine, stack, value, exception)) = self._running.popleft()
+
+            self._this_thread = thread_info
+
+            if values:
+                self._resume_coroutine(thread_info, coroutine, stack, value, values.pop(thread_info, None))
+            elif exceptions:
+                self._resume_coroutine(thread_info, coroutine, stack, value, exceptions.pop(thread_info, None))
+            else:
+                self._resume_coroutine(thread_info, coroutine, stack, value, exception)
+
+        try:
+            del self._this_thread
+        except AttributeError:
+            pass
+
+    def thaw(self, *threads_info):
+        for thread_info in threads_info:
+            self._running.append((thread_info, self._frozen[thread_info]))
+
+            del self._frozen[thread_info]
+
+    def _resume_coroutine(self, thread_info, coroutine, stack, value = None, exception = None):
+        try:
+            if exception:
+                returned = coroutine.throw(*exception)
+            else:
+                returned = coroutine.send(value)
+        except StopIteration:
+            if stack:
+                self._running.append((thread_info, (stack[0], stack[1], None, None)))
+        except:
+            if stack:
+                self._running.append((thread_info, (stack[0], stack[1], value, sys.exc_info())))
+            else:
+                raise
+        else:
+            if returned is Trampoline.freeze:
+                self._frozen[thread_info] = (coroutine, stack, None, None)
+            elif isinstance(returned, types.GeneratorType):
+                self._running.append((thread_info, (returned, (coroutine, stack), None, None)))
+            elif stack:
+                self._running.append((thread_info, (stack[0], stack[1], returned, None)))
+
+    def __get_this_thread(self):
+        return self._this_thread
+
+    this_thread = property(__get_this_thread)
+
