diff --git a/Modules/cPickle.c b/Modules/cPickle.c
index c90b2492d38343..931557e95a2f36 100644
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -2,7 +2,6 @@
 #include "cStringIO.h"
 #include "structmember.h"
 #include "core/stackless_impl.h"
-#include "platf/slp_platformselect.h"
 
 PyDoc_STRVAR(cPickle_module_documentation,
 "C implementation and optimization of the Python pickle module.");
@@ -2571,9 +2570,9 @@ save(Picklerobject *self, PyObject *args, int pers_save)
     int res = -1;
     int tmp;
 
-#ifdef STACKLESS
+#if defined STACKLESS
     /* but we save the stack after a fixed watermark */
-    if (CSTACK_SAVE_NOW(PyThreadState_GET(), self)) {
+    if (slp_cstack_save_now(PyThreadState_GET())) {
         res = slp_safe_pickling((int(*)(PyObject *, PyObject *, int))&save,
                                 (PyObject *)self, args, pers_save);
         goto finally;
diff --git a/PCbuild/pythoncore.vcproj b/PCbuild/pythoncore.vcproj
index 146d89baac291f..0afc880e286c36 100644
--- a/PCbuild/pythoncore.vcproj
+++ b/PCbuild/pythoncore.vcproj
@@ -16,6 +16,9 @@
 		/>
 	</Platforms>
 	<ToolFiles>
+		<DefaultToolFile
+			FileName="masm.rules"
+		/>
 	</ToolFiles>
 	<Configurations>
 		<Configuration
@@ -31,6 +34,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -105,6 +111,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -181,6 +190,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -258,6 +270,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -336,6 +351,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -410,6 +428,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -486,6 +507,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -560,6 +584,9 @@
 			<Tool
 				Name="VCCustomBuildTool"
 			/>
+			<Tool
+				Name="MASM"
+			/>
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
@@ -655,11 +682,11 @@
 				>
 			</File>
 			<File
-				RelativePath="..\Include\bytes_methods.h"
+				RelativePath="..\Include\bytearrayobject.h"
 				>
 			</File>
 			<File
-				RelativePath="..\Include\bytearrayobject.h"
+				RelativePath="..\Include\bytes_methods.h"
 				>
 			</File>
 			<File
@@ -1411,11 +1438,11 @@
 				>
 			</File>
 			<File
-				RelativePath="..\Objects\bytes_methods.c"
+				RelativePath="..\Objects\bytearrayobject.c"
 				>
 			</File>
 			<File
-				RelativePath="..\Objects\bytearrayobject.c"
+				RelativePath="..\Objects\bytes_methods.c"
 				>
 			</File>
 			<File
@@ -1937,10 +1964,6 @@
 					RelativePath="..\Stackless\core\cframeobject.c"
 					>
 				</File>
-				<File
-					RelativePath="..\Stackless\core\slp_transfer.c"
-					>
-				</File>
 				<File
 					RelativePath="..\Stackless\core\stackless_impl.h"
 					>
@@ -1954,155 +1977,135 @@
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\core\stackless_tstate.h"
+					RelativePath="..\Stackless\core\stackless_tealet.c"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\core\stackless_util.c"
+					RelativePath="..\Stackless\core\stackless_tealet.h"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\core\stacklesseval.c"
-					>
-				</File>
-			</Filter>
-			<Filter
-				Name="platf"
-				>
-				<File
-					RelativePath="..\Stackless\platf\slp_platformselect.h"
-					>
-				</File>
-				<File
-					RelativePath="..\Stackless\platf\switch_amd64_unix.h"
+					RelativePath="..\Stackless\core\stackless_tstate.h"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\platf\switch_arm32_gcc.h"
+					RelativePath="..\Stackless\core\stackless_util.c"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\platf\switch_arm_thumb_gcc.h"
+					RelativePath="..\Stackless\core\stacklesseval.c"
 					>
 				</File>
+			</Filter>
+			<Filter
+				Name="pickling"
+				>
 				<File
-					RelativePath="..\Stackless\platf\switch_ppc_macosx.h"
+					RelativePath="..\Stackless\pickling\prickelpit.c"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\platf\switch_ppc_unix.h"
+					RelativePath="..\Stackless\pickling\prickelpit.h"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\platf\switch_s390_unix.h"
+					RelativePath="..\Stackless\pickling\safe_pickle.c"
 					>
 				</File>
+			</Filter>
+			<Filter
+				Name="tealet"
+				>
 				<File
-					RelativePath="..\Stackless\platf\switch_sparc_sun_gcc.h"
+					RelativePath="..\Stackless\tealet\slp_platformselect.h"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\platf\switch_x64_masm.asm"
+					RelativePath="..\Stackless\tealet\switch_x64_msvc.asm"
 					>
 					<FileConfiguration
 						Name="Release|Win32"
 						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 					<FileConfiguration
-						Name="Release|x64"
+						Name="Debug|Win32"
+						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
-							Description="Running ml64"
-							CommandLine="ml64 /nologo /c /Zi /Fo &quot;$(IntDir)\$(InputName) .obj&quot; &quot;$(InputPath)&quot;"
-							Outputs="$(IntDir)\$(InputName) .obj"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 					<FileConfiguration
-						Name="Debug|Win32"
+						Name="PGInstrument|Win32"
 						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 					<FileConfiguration
-						Name="Debug|x64"
+						Name="PGUpdate|Win32"
+						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
-							Description="Running ml64"
-							CommandLine="ml64 /nologo /c /Zi /Fo &quot;$(IntDir)\$(InputName) .obj&quot; &quot;$(InputPath)&quot;"
-							Outputs="$(IntDir)\$(InputName) .obj"
+							Name="MASM"
 						/>
 					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\Stackless\tealet\switch_x64_msvc.h"
+					>
+				</File>
+				<File
+					RelativePath="..\Stackless\tealet\switch_x86_msvc.asm"
+					>
 					<FileConfiguration
-						Name="PGInstrument|Win32"
+						Name="Release|x64"
 						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 					<FileConfiguration
-						Name="PGInstrument|x64"
+						Name="Debug|x64"
+						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
-							Description="Running ml64"
-							CommandLine="ml64 /nologo /c /Zi /Fo &quot;$(IntDir)\$(InputName) .obj&quot; &quot;$(InputPath)&quot;"
-							Outputs="$(IntDir)\$(InputName) .obj"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 					<FileConfiguration
-						Name="PGUpdate|Win32"
+						Name="PGInstrument|x64"
 						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 					<FileConfiguration
 						Name="PGUpdate|x64"
+						ExcludedFromBuild="true"
 						>
 						<Tool
-							Name="VCCustomBuildTool"
-							Description="Running ml64"
-							CommandLine="ml64 /nologo /c /Zi /Fo &quot;$(IntDir)\$(InputName) .obj&quot; &quot;$(InputPath)&quot;"
-							Outputs="$(IntDir)\$(InputName) .obj"
+							Name="MASM"
 						/>
 					</FileConfiguration>
 				</File>
 				<File
-					RelativePath="..\Stackless\platf\switch_x64_msvc.h"
-					>
-				</File>
-				<File
-					RelativePath="..\Stackless\platf\switch_x86_msvc.h"
-					>
-				</File>
-				<File
-					RelativePath="..\Stackless\platf\switch_x86_unix.h"
+					RelativePath="..\Stackless\tealet\switch_x86_msvc.h"
 					>
 				</File>
-			</Filter>
-			<Filter
-				Name="pickling"
-				>
 				<File
-					RelativePath="..\Stackless\pickling\prickelpit.c"
+					RelativePath="..\Stackless\tealet\tealet.c"
 					>
 				</File>
 				<File
-					RelativePath="..\Stackless\pickling\prickelpit.h"
-					>
-				</File>
-				<File
-					RelativePath="..\Stackless\pickling\safe_pickle.c"
+					RelativePath="..\Stackless\tealet\tealet.h"
 					>
 				</File>
 			</Filter>
diff --git a/Python/ceval.c b/Python/ceval.c
index f0addb5d3ee4b3..3f98a4b2f984ad 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -17,7 +17,6 @@
 #include "opcode.h"
 #include "structmember.h"
 #include "core/stackless_impl.h"
-#include "platf/slp_platformselect.h" /* for stack saving */
 
 #include <ctype.h>
 
@@ -906,7 +905,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
         return NULL;
 
 #ifdef STACKLESS
-    if (CSTACK_SAVE_NOW(tstate, f))
+    if (slp_cstack_save_now(tstate))
         return slp_eval_frame_newstack(f, throwflag, retval);
 
     /* push frame */
diff --git a/Stackless/core/slp_transfer.c b/Stackless/core/slp_transfer.c
index 2fc8b189f029b1..efac1a1152b330 100644
--- a/Stackless/core/slp_transfer.c
+++ b/Stackless/core/slp_transfer.c
@@ -80,35 +80,6 @@ extern int slp_switch(void);
 
 #endif
 
-/* a write only variable used to prevent overly optimisation */
-intptr_t *global_goobledigoobs;
-static int
-climb_stack_and_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
-                         PyTaskletObject *prev)
-{
-    /*
-     * there are cases where we have been initialized
-     * in some deep stack recursion, but later on we
-     * need to switch from a higher stacklevel, and the
-     * needed stack size becomes *negative* :-))
-     */
-    PyThreadState *ts = PyThreadState_GET();
-    intptr_t probe;
-    register ptrdiff_t needed = &probe - ts->st.cstack_base;
-    /* in rare cases, the need might have vanished due to the recursion */
-    register intptr_t *goobledigoobs;
-    if (needed > 0) {
-        goobledigoobs = alloca(needed * sizeof(intptr_t));
-        if (goobledigoobs == NULL)
-            return -1;
-        /* hinder the compiler to optimise away 
-           goobledigoobs and the alloca call. 
-           This happens with gcc 4.7.x and -O2 */
-        global_goobledigoobs = goobledigoobs;
-    }
-    return slp_transfer(cstprev, cst, prev);
-}
-
 /* This function returns -1 on error, 1 if a switch occurred and 0
  * if only a stack save was performed
  */
@@ -122,9 +93,7 @@ slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
     /* since we change the stack we must assure that the protocol was met */
     STACKLESS_ASSERT();
 
-    if ((intptr_t *) &ts > ts->st.cstack_base)
-        return climb_stack_and_transfer(cstprev, cst, prev);
-    if (cst == NULL || cst->ob_size == 0)
+    if (cst == NULL)
         cst = ts->st.initial_stub;
     if (cst != NULL) {
         if (cst->tstate != ts) {
@@ -145,6 +114,10 @@ slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
         if (cstprev && *cstprev == cst && cst->ob_refcnt == 1)
             cst = NULL;
     }
+    /* allocate a fresh 
+    if (!slp_cstack_new(cstprev, NULL, t))
+        return NULL;
+    
     _cstprev = cstprev;
     _cst = cst;
     _prev = prev;
diff --git a/Stackless/core/stackless_impl.h b/Stackless/core/stackless_impl.h
index 62fbaa6ab4fa7c..2e39ed8f2c5f39 100644
--- a/Stackless/core/stackless_impl.h
+++ b/Stackless/core/stackless_impl.h
@@ -36,23 +36,7 @@ extern "C" {
 PyAPI_DATA(int) slp_enable_softswitch;
 PyAPI_DATA(int) slp_in_psyco;
 PyAPI_DATA(int) slp_try_stackless;
-PyAPI_DATA(PyCStackObject *) slp_cstack_chain;
-
-PyAPI_FUNC(PyCStackObject *) slp_cstack_new(PyCStackObject **cst,
-                                            intptr_t *stackref,
-                                            PyTaskletObject *task);
-PyAPI_FUNC(size_t) slp_cstack_save(PyCStackObject *cstprev);
-PyAPI_FUNC(void) slp_cstack_restore(PyCStackObject *cst);
-
-PyAPI_FUNC(int) slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
-                             PyTaskletObject *prev);
-
-#ifdef Py_DEBUG
-PyAPI_FUNC(int) slp_transfer_return(PyCStackObject *cst);
-#else
-#define slp_transfer_return(cst) \
-                slp_transfer(NULL, (cst), NULL)
-#endif
+PyAPI_DATA(PyTaskletObject *) slp_tasklet_chain;
 
 PyAPI_FUNC(int) _PyStackless_InitTypes(void);
 PyAPI_FUNC(void) _PyStackless_Init(void);
diff --git a/Stackless/core/stackless_structs.h b/Stackless/core/stackless_structs.h
index e4c31505d680e3..8bf5325a9e48d4 100644
--- a/Stackless/core/stackless_structs.h
+++ b/Stackless/core/stackless_structs.h
@@ -5,10 +5,7 @@
 extern "C" {
 #endif
 
-/* platform specific constants (mainly SEH stuff to store )*/
-#include "platf/slp_platformselect.h"
-
-
+#include "stackless_tealet.h"
 
 /*** important structures: tasklet ***/
 
@@ -62,7 +59,7 @@ extern "C" {
 
  ***************************************************************************/
 
-typedef struct _tasklet_flags {
+typedef struct PyTaskletObject_flags {
     int blocked: 2;
     unsigned int atomic: 1;
     unsigned int ignore_nesting: 1;
@@ -73,46 +70,25 @@ typedef struct _tasklet_flags {
 } PyTaskletFlagStruc;
 
 
-typedef struct _tasklet {
+typedef struct PyTaskletObject {
     PyObject_HEAD
-    struct _tasklet *next;
-    struct _tasklet *prev;
+    struct PyTaskletObject *next;
+    struct PyTaskletObject *prev;
     union {
         struct _frame *frame;
         struct _cframe *cframe;
     } f;
     PyObject *tempval;
     /* bits stuff */
-    struct _tasklet_flags flags;
+    struct PyTaskletObject_flags flags;
     int recursion_depth;
-    struct _cstack *cstate;
+    int nesting_level;
+    PyThreadState *tstate;
+    struct tealet_t *cstate;
     PyObject *def_globals;
     PyObject *tsk_weakreflist;
 } PyTaskletObject;
 
-
-/*** important structures: cstack ***/
-
-typedef struct _cstack {
-    PyObject_VAR_HEAD
-    struct _cstack *next;
-    struct _cstack *prev;
-#ifdef have_long_long
-    long_long serial;
-#else
-    long serial;
-#endif
-    struct _tasklet *task;
-    int nesting_level;
-    PyThreadState *tstate;
-#ifdef _SEH32
-    DWORD exception_list; /* SEH handler on Win32 */
-#endif
-    intptr_t *startaddr;
-    intptr_t stack[1];
-} PyCStackObject;
-
-
 /*** important structures: bomb ***/
 
 typedef struct _bomb {
@@ -156,8 +132,8 @@ typedef struct _channel_flags {
 typedef struct _channel {
     PyObject_HEAD
     /* make sure that these fit tasklet's next/prev */
-    struct _tasklet *head;
-    struct _tasklet *tail;
+    struct PyTaskletObject *head;
+    struct PyTaskletObject *tail;
     int balance;
     struct _channel_flags flags;
     PyObject *chan_weakreflist;
@@ -204,9 +180,6 @@ typedef struct _slpmodule {
 PyAPI_DATA(PyTypeObject) PyCFrame_Type;
 #define PyCFrame_Check(op) ((op)->ob_type == &PyCFrame_Type)
 
-PyAPI_DATA(PyTypeObject) PyCStack_Type;
-#define PyCStack_Check(op) ((op)->ob_type == &PyCStack_Type)
-
 PyAPI_DATA(PyTypeObject) PyBomb_Type;
 #define PyBomb_Check(op) ((op)->ob_type == &PyBomb_Type)
 
diff --git a/Stackless/core/stackless_tealet.c b/Stackless/core/stackless_tealet.c
new file mode 100644
index 00000000000000..a1e1ddd5e33d29
--- /dev/null
+++ b/Stackless/core/stackless_tealet.c
@@ -0,0 +1,366 @@
+
+#include "stackless_tealet.h"
+
+#include <python.h>
+#include "frameobject.h"
+#include "stackless_impl.h"
+
+PyTealet_data *slp_tealet_list = NULL;
+
+static void
+slp_tealet_link(tealet_t *t, PyTaskletObject *tasklet)
+{
+    PyTealet_data *td = TEALET_EXTRA(t, PyTealet_data);
+    if (slp_tealet_list) {
+        td->next = slp_tealet_list;
+        td->prev = td->next->prev;
+        td->next->prev = td;
+        td->prev->next = td;
+    } else
+        td->next = td->prev = td;
+    slp_tealet_list = td;
+    td->tasklet = tasklet;
+}
+
+static void
+slp_tealet_unlink(tealet_t *t)
+{
+    PyTealet_data *td = TEALET_EXTRA(t, PyTealet_data);
+    if (td->next != td) {
+        slp_tealet_list = td->next;
+        td->next->prev = td->prev;
+        td->prev->next = td->next;
+    } else
+        slp_tealet_list = NULL;
+}
+
+/****************************************************************
+ *Implement copyable tealet stubs by using a trampoline
+ */
+struct slp_stub_arg
+{
+    tealet_t *current;
+    tealet_run_t run;
+    void *runarg;
+};
+
+static tealet_t *slp_stub_main(tealet_t *current, void *arg)
+{
+    void *myarg = 0;
+    /* the caller is in arg, return right back to him */
+    tealet_switch((tealet_t*)arg, &myarg);
+    /* now we are back, myarg should contain the arg to the run function.
+     * We were possibly duplicated, so can't trust the original function args.
+     */
+    {
+        struct slp_stub_arg sarg = *(struct slp_stub_arg*)myarg;
+        tealet_free(sarg.current, myarg);
+        return (sarg.run)(sarg.current, sarg.runarg);
+    }
+}
+
+/* create a stub and return it */
+tealet_t *slp_stub_new(tealet_t *t, size_t extrasize)
+{
+    void *arg = (void*)tealet_current(t);
+    return tealet_new(t, slp_stub_main, &arg, extrasize);
+}
+
+/* find the stack far point if a stub were created here */
+void * slp_stub_far(tealet_t *dummy1, size_t dummy2)
+{
+    void *arg = 0;
+    return tealet_new_far(dummy1, NULL, &arg, dummy2);
+}
+
+
+/* run a stub */
+int slp_stub_run(tealet_t *stub, tealet_run_t run, void **parg)
+{
+    int result;
+    void *myarg;
+    
+    /* we cannot pass arguments to a different tealet on the stack */
+    struct slp_stub_arg *psarg = (struct slp_stub_arg*)tealet_malloc(stub, sizeof(struct slp_stub_arg));
+    if (!psarg)
+        return TEALET_ERR_MEM;
+    psarg->current = stub;
+    psarg->run = run;
+    psarg->runarg = parg ? *parg : NULL;
+    myarg = (void*)psarg;
+    result = tealet_switch(stub, &myarg);
+    if (result) {
+        /* failure */
+        tealet_free(stub, psarg);
+        return result;
+    }
+    /* pass back the arg value from the switch */
+    if (parg)
+        *parg = myarg;
+    return 0;
+}
+
+/* end of generic tealet stub code */
+
+/* translate tealet errors into python errors */
+static int
+slp_tealet_error(int err)
+{
+    assert(err);
+    if (err == TEALET_ERR_MEM)
+        PyErr_NoMemory();
+    assert(err == TEALET_ERR_DEFUNCT);
+    PyErr_SetString(PyExc_RuntimeError, "Tealet corrupt");
+    return -1;
+}
+
+/* the current mechanism is based on the generic callable stubs
+ * above.  This is useful, because it allows us to call arbitrary
+ * callbacks, e.g. when doing stack spilling.
+ */
+int
+slp_make_initial_stub(PyThreadState *ts)
+{
+    if (ts->st.tealet_main == NULL) {
+        tealet_alloc_t ta = {
+            (tealet_malloc_t)&PyMem_Malloc,
+            (tealet_free_t)&PyMem_Free,
+            0};
+        ts->st.tealet_main = tealet_initialize(&ta, sizeof(PyTealet_data));
+        if (!ts->st.tealet_main)
+            goto err;
+
+    }
+    if (ts->st.initial_stub) {
+        /* recreate stub, if it was deeper on the stack, otherwise, we just leave it */
+        /* note, this approach needs to be subject to tuning.  Maybe the absolute position
+         * of the stub makes no difference.  But for stack spilling, a "high" stub makes
+         * perfect sense.
+         */
+        void *a;
+        void *b;
+        a = tealet_get_far(ts->st.initial_stub);
+        b = slp_stub_far(ts->st.tealet_main, 0);
+        if (tealet_stack_diff(a, b) < 0) {
+            /* new stub will be higher up, recreate it */
+            tealet_delete(ts->st.initial_stub);
+            ts->st.initial_stub = NULL;
+        }
+    }
+
+    if (!ts->st.initial_stub) {
+        ts->st.initial_stub = slp_stub_new(ts->st.tealet_main, sizeof(PyTealet_data));
+        if (!ts->st.initial_stub)
+            goto err;
+#if 0 /* just to verify predicted pos */
+        {
+            void *c
+            c = slp_stub_far(ts->st.tealet_main, 0);
+            c = c;
+        }
+#endif
+    }
+    return 0;
+err:
+    PyErr_NoMemory();
+    return -1;
+}
+
+/* clean up tealet state for this thread */
+void slp_tealet_cleanup(PyThreadState *ts)
+{
+    slp_destroy_initial_stub(ts);
+    if (ts->st.tealet_main) {
+        /* we may be calling Py_Exit from a tasklet or otherwise
+         * from a sub-tealet.  Therefore we can't make sanity checks
+         * like testing that we are the main tealet.  Accept that we
+         * may leak suspended tealets in this case
+         */
+        if (TEALET_CURRENT_IS_MAIN(ts->st.tealet_main))
+            tealet_finalize(ts->st.tealet_main);
+        ts->st.tealet_main = NULL;
+    }
+}
+
+void
+slp_destroy_initial_stub(PyThreadState *ts)
+{
+    if (ts->st.initial_stub)
+        tealet_delete(ts->st.initial_stub);
+    ts->st.initial_stub = NULL;
+}
+
+/* The function that runs tasklet loop in a tealet */
+static tealet_t *tasklet_stub_func(tealet_t *me, void *arg)
+{
+    PyThreadState *ts = PyThreadState_GET();
+    PyFrameObject *f = ts->frame;
+    PyObject *result;
+    ts->frame = NULL;
+    ts->st.nesting_level = 0;
+    Py_CLEAR(ts->st.del_post_switch);
+    result = slp_run_tasklet(f);
+    
+    /* this tealet is returning, which means that main is returning. Switch back
+     * to the main tealet.  The result is passed to the target
+     */
+    tealet_exit(ts->st.tealet_main, (void*)result, TEALET_EXIT_DEFAULT);
+    /* this should never fail */
+    assert(0);
+    return NULL;
+}
+
+/* Running a function in the top level stub.  If NULL is provided,
+ * use the tasklet evaluation loop
+ */
+
+/* Running a function in the top level stub */
+int
+slp_run_initial_stub(PyThreadState *ts, tealet_run_t func, void **arg)
+{
+    tealet_t *stub;
+    int result;
+    stub = tealet_duplicate(ts->st.initial_stub, sizeof(PyTealet_data));
+    if (!stub) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    result = slp_stub_run(stub, func, arg);
+    if (result)
+        return slp_tealet_error(result);
+    return 0;
+}
+
+/* call the top level loop as a means of starting a new such loop, hardswitching out
+ * of a tasklet.  This invocation does not expect a return value
+ */
+int
+slp_run_stub_from_worker(PyThreadState *ts)
+{
+    return slp_run_initial_stub(ts, &tasklet_stub_func, NULL);
+}
+
+/* hard switching of tasklets */
+
+int
+slp_transfer(PyThreadState *ts, tealet_t *cst, PyTaskletObject *prev)
+{
+    int result;
+    int nesting_level;
+    tealet_t *current;
+
+    assert(prev->cstate == NULL);
+    nesting_level = prev->tstate->st.nesting_level;
+    prev->nesting_level = nesting_level;
+
+    /* mark the old tasklet as having cstate, and link it in */
+    current = tealet_current(ts->st.tealet_main);
+    prev->cstate = current;
+    slp_tealet_link(current, prev);
+
+    if (cst) {
+        /* make sure we are not trying to jump between threads */
+        assert(TEALET_RELATED(ts->st.tealet_main, cst));
+        result = tealet_switch(cst, NULL);
+    } else {
+        assert(TEALET_RELATED(ts->st.tealet_main, ts->st.initial_stub));
+        result = slp_run_stub_from_worker(ts);
+    }
+
+    /* we are back, or failed, no cstate in tasklet */
+    slp_tealet_unlink(current);
+    prev->cstate = NULL;
+    prev->tstate->st.nesting_level = nesting_level;
+    if (!result) {
+        if (ts->st.del_post_switch) {
+            PyObject *tmp;
+            TASKLET_CLAIMVAL(ts->st.current, &tmp);
+            Py_CLEAR(ts->st.del_post_switch);
+            TASKLET_SETVAL_OWN(ts->st.current, tmp);
+        }
+        return 0;
+    }
+    if (result == TEALET_ERR_MEM)
+        PyErr_NoMemory();
+    else
+        PyErr_SetString(PyExc_RuntimeError, "Invalid tasklet");
+    return -1;
+}
+
+int
+slp_transfer_return(tealet_t *cst)
+{
+    int result = tealet_exit(cst, NULL, TEALET_EXIT_DEFAULT);
+    if (result) {
+        /* emergency switch back to main tealet */
+        PyThreadState *ts = PyThreadState_GET();
+        PyErr_SetString(PyExc_RuntimeError, "Invalid tealet");
+        tealet_exit(ts->st.tealet_main, NULL, TEALET_EXIT_DEFAULT);
+        /* emergency!.  Transfer to the _real_ main */
+        tealet_exit(TEALET_MAIN(ts->st.tealet_main), NULL, TEALET_EXIT_DEFAULT);
+    }
+    assert(0); /* never returns */
+    return 0;
+}
+
+int
+slp_transfer_with_exc(PyThreadState *ts, tealet_t *cst, PyTaskletObject *prev)
+{
+    int tracing = ts->tracing;
+    int use_tracing = ts->use_tracing;
+
+    Py_tracefunc c_profilefunc = ts->c_profilefunc;
+    Py_tracefunc c_tracefunc = ts->c_tracefunc;
+    PyObject *c_profileobj = ts->c_profileobj;
+    PyObject *c_traceobj = ts->c_traceobj;
+
+    PyObject *exc_type = ts->exc_type;
+    PyObject *exc_value = ts->exc_value;
+    PyObject *exc_traceback = ts->exc_traceback;
+    int ret;
+
+    ts->exc_type = ts->exc_value = ts->exc_traceback = NULL;
+    ts->c_profilefunc = ts->c_tracefunc = NULL;
+    ts->c_profileobj = ts->c_traceobj = NULL;
+    ts->use_tracing = ts->tracing = 0;
+
+    /* note that trace/profile are set without ref */
+    Py_XINCREF(c_profileobj);
+    Py_XINCREF(c_traceobj);
+
+    ret = slp_transfer(ts, cst, prev);
+
+    ts->tracing = tracing;
+    ts->use_tracing = use_tracing;
+
+    ts->c_profilefunc = c_profilefunc;
+    ts->c_tracefunc = c_tracefunc;
+    ts->c_profileobj = c_profileobj;
+    ts->c_traceobj = c_traceobj;
+    Py_XDECREF(c_profileobj);
+    Py_XDECREF(c_traceobj);
+
+    ts->exc_type = exc_type;
+    ts->exc_value = exc_value;
+    ts->exc_traceback = exc_traceback;
+    return ret;
+}
+
+#ifndef CSTACK_WATERMARK
+#define CSTACK_WATERMARK 16384
+#endif
+int slp_cstack_save_now(PyThreadState *ts)
+{
+    void *a, *b;
+    ptrdiff_t diff;
+    if (!ts->st.initial_stub)
+        return 0;
+    assert(ts->st.initial_stub);
+    a = tealet_get_far(ts->st.initial_stub);
+    b = slp_stub_far(NULL, 0);
+    diff = tealet_stack_diff(a, b);
+#if 0 /* enable this for testing, a low threshold */
+    return diff > 1000;
+#endif
+    return diff > CSTACK_WATERMARK;
+}
\ No newline at end of file
diff --git a/Stackless/core/stackless_tealet.h b/Stackless/core/stackless_tealet.h
new file mode 100644
index 00000000000000..1baf871ba5fc64
--- /dev/null
+++ b/Stackless/core/stackless_tealet.h
@@ -0,0 +1,33 @@
+/* interface to the stack switching routines used by stackless */
+#ifndef _STACKLESS_TEALET_H
+#define _STACKLESS_TEALET_H
+
+#include <tealet/tealet.h>
+#include <python.h>
+
+/* a list of tealets. Currently these are suspended tealets with their
+ * suspended tasklets indicated.
+ */
+typedef struct PyTealet_data {
+    struct PyTealet_data *prev;
+    struct PyTealet_data *next;
+    struct PyTaskletObject *tasklet;
+} PyTealet_data;
+
+PyTealet_data *slp_tealet_list; /* head of the tealet list */
+
+int slp_make_initial_stub(PyThreadState *ts);
+void slp_destroy_initial_stub(PyThreadState *ts);
+int slp_run_initial_stub(PyThreadState *ts, tealet_run_t func, void **arg);
+int slp_run_stub_from_worker(PyThreadState *ts);
+void slp_tealet_cleanup(PyThreadState *ts);
+
+/* hard switching of tasklets */
+int slp_transfer(PyThreadState *ts, tealet_t *cst, struct PyTaskletObject *prev);
+int slp_transfer_with_exc(PyThreadState *ts, tealet_t *cst, struct PyTaskletObject *prev);
+int slp_transfer_return(tealet_t *cst);
+
+/* stack spilling */
+int slp_cstack_save_now(PyThreadState *ts);
+
+#endif
\ No newline at end of file
diff --git a/Stackless/core/stackless_tstate.h b/Stackless/core/stackless_tstate.h
index c0fc2f12c249e7..6eb3c14c48fbac 100644
--- a/Stackless/core/stackless_tstate.h
+++ b/Stackless/core/stackless_tstate.h
@@ -1,29 +1,12 @@
 /*** addition to tstate ***/
 
 typedef struct _sts {
-    /* the blueprint for new stacks */
-    struct _cstack *initial_stub;
-    /* "serial" is incremented each time we create a new stub.
-     * (enter "stackless" from the outside)
-     * and "serial_last_jump" indicates to which stub the current
-     * stack belongs.  This is used to find out if a stack switch
-     * is required when the main tasklet exits
-     */
-#ifdef have_long_long
-    long_long serial;
-    long_long serial_last_jump;
-#else
-    long serial;
-    long serial_last_jump;
-#endif
-    /* the base address for hijacking stacks. XXX deprecating */
-    intptr_t *cstack_base;
-    /* stack overflow check and init flag */
-    intptr_t *cstack_root;
+    struct tealet_t *initial_stub;  /* stub for creating new tealets */
+    struct tealet_t *tealet_main;   /* the current "main" tealet */
     /* main tasklet */
-    struct _tasklet *main;
+    struct PyTaskletObject *main;
     /* runnable tasklets */
-    struct _tasklet *current;
+    struct PyTaskletObject *current;
     int runcount;
 
     /* scheduling */
@@ -53,10 +36,7 @@ typedef struct _sts {
 /* these macros go into pystate.c */
 #define __STACKLESS_PYSTATE_NEW \
     tstate->st.initial_stub = NULL; \
-    tstate->st.serial = 0; \
-    tstate->st.serial_last_jump = 0; \
-    tstate->st.cstack_base = NULL; \
-    tstate->st.cstack_root = NULL; \
+    tstate->st.tealet_main = NULL; \
     tstate->st.ticker = 0; \
     tstate->st.interval = 0; \
     tstate->st.interrupt = NULL; \
@@ -79,12 +59,13 @@ typedef struct _sts {
 struct _ts; /* Forward */
 
 void slp_kill_tasks_with_stacks(struct _ts *tstate);
+void slp_tealet_cleanup(struct _ts *tstate);
 
 #define __STACKLESS_PYSTATE_CLEAR \
     slp_kill_tasks_with_stacks(tstate); \
-    Py_CLEAR(tstate->st.initial_stub); \
     Py_CLEAR(tstate->st.del_post_switch); \
-    Py_CLEAR(tstate->st.interrupted);
+    Py_CLEAR(tstate->st.interrupted); \
+    slp_tealet_cleanup(tstate);
 
 #ifdef WITH_THREAD
 
diff --git a/Stackless/core/stacklesseval.c b/Stackless/core/stacklesseval.c
index fe7a77959ebb41..ec330be2574fac 100644
--- a/Stackless/core/stacklesseval.c
+++ b/Stackless/core/stacklesseval.c
@@ -8,8 +8,7 @@
 #include "stackless_impl.h"
 #include "pickling/prickelpit.h"
 
-/* platform specific constants */
-#include "platf/slp_platformselect.h"
+#include "stackless_tealet.h"
 
 /* Stackless extension for ceval.c */
 
@@ -37,8 +36,8 @@ int slp_in_psyco = 0;
  */
 int slp_try_stackless = 0;
 
-/* the list of all stacks of all threads */
-struct _cstack *slp_cstack_chain = NULL;
+/* the list of all tasklets of all threads */
+PyTaskletObject *slp_tasklet_chain = NULL;
 
 
 /******************************************************
@@ -47,232 +46,11 @@ struct _cstack *slp_cstack_chain = NULL;
 
  ******************************************************/
 
-static PyCStackObject *cstack_cache[CSTACK_SLOTS] = { NULL };
-static int cstack_cachecount = 0;
 
 /* this function will get called by PyStacklessEval_Fini */
-static void slp_cstack_cacheclear(void)
-{
-    int i;
-    PyCStackObject *stack;
-
-    for (i=0; i < CSTACK_SLOTS; i++) {
-        while (cstack_cache[i] != NULL) {
-            stack = cstack_cache[i];
-            cstack_cache[i] = (PyCStackObject *) stack->startaddr;
-            PyObject_Del(stack);
-        }
-    }
-    cstack_cachecount = 0;
-}
-
-static void
-cstack_dealloc(PyCStackObject *cst)
-{
-    slp_cstack_chain = cst;
-    SLP_CHAIN_REMOVE(PyCStackObject, &slp_cstack_chain, cst, next,
-                     prev);
-    if (cst->ob_size >= CSTACK_SLOTS) {
-        PyObject_Del(cst);
-    }
-    else {
-        if (cstack_cachecount >= CSTACK_MAXCACHE)
-            slp_cstack_cacheclear();
-    cst->startaddr = (intptr_t *) cstack_cache[cst->ob_size];
-        cstack_cache[cst->ob_size] = cst;
-        ++cstack_cachecount;
-    }
-}
-
-
-PyCStackObject *
-slp_cstack_new(PyCStackObject **cst, intptr_t *stackref, PyTaskletObject *task)
-{
-    PyThreadState *ts = PyThreadState_GET();
-    intptr_t *stackbase = ts->st.cstack_base;
-    ptrdiff_t size = stackbase - stackref;
-
-    assert(size >= 0);
-
-    if (*cst != NULL) {
-        if ((*cst)->task == task)
-            (*cst)->task = NULL;
-        Py_DECREF(*cst);
-    }
-    if (size < CSTACK_SLOTS && ((*cst) = cstack_cache[size])) {
-        /* take stack from cache */
-        cstack_cache[size] = (PyCStackObject *) (*cst)->startaddr;
-        --cstack_cachecount;
-        _Py_NewReference((PyObject *)(*cst));
-    }
-    else
-        *cst = PyObject_NewVar(PyCStackObject, &PyCStack_Type, size);
-    if (*cst == NULL) return NULL;
-
-    (*cst)->startaddr = stackbase;
-    (*cst)->next = (*cst)->prev = NULL;
-    SLP_CHAIN_INSERT(PyCStackObject, &slp_cstack_chain, *cst, next, prev);
-    (*cst)->serial = ts->st.serial_last_jump;
-    (*cst)->task = task;
-    (*cst)->tstate = ts;
-    (*cst)->nesting_level = ts->st.nesting_level;
-#ifdef _SEH32
-    //save the SEH handler
-    (*cst)->exception_list = (DWORD)
-                __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
-#endif
-    return *cst;
-}
-
-size_t
-slp_cstack_save(PyCStackObject *cstprev)
-{
-    size_t stsizeb = (cstprev)->ob_size * sizeof(intptr_t);
-
-    memcpy((cstprev)->stack, (cstprev)->startaddr -
-                             (cstprev)->ob_size, stsizeb);
-#ifdef _SEH32
-    //save the SEH handler
-    cstprev->exception_list = (DWORD)
-                __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
-#endif
-    return stsizeb;
-}
-
-void
-#ifdef _SEH32
-#pragma warning(disable:4733) /* disable warning about modifying FS[0] */
-#endif
-slp_cstack_restore(PyCStackObject *cst)
-{
-    cst->tstate->st.nesting_level = cst->nesting_level;
-    /* mark task as no longer responsible for cstack instance */
-    cst->task = NULL;
-    memcpy(cst->startaddr - cst->ob_size, &cst->stack,
-           (cst->ob_size) * sizeof(intptr_t));
-#ifdef _SEH32
-    //restore the SEH handler
-    __writefsdword(FIELD_OFFSET(NT_TIB, ExceptionList), (DWORD)(cst->exception_list));
-    #pragma warning(default:4733)
-#endif
-}
-
-
-static char cstack_doc[] =
-"A CStack object serves to save the stack slice which is involved\n\
-during a recursive Python call. It will also be used for pickling\n\
-of program state. This structure is highly platform dependant.\n\
-Note: For inspection, str() can dump it as a string.\
-";
-
-#if SIZEOF_VOIDP == SIZEOF_INT
-#define T_ADDR T_UINT
-#else
-#define T_ADDR T_ULONG
-#endif
-
 
-static PyMemberDef cstack_members[] = {
-    {"size", T_INT, offsetof(PyCStackObject, ob_size), READONLY},
-    {"next", T_OBJECT, offsetof(PyCStackObject, next), READONLY},
-    {"prev", T_OBJECT, offsetof(PyCStackObject, prev), READONLY},
-    {"task", T_OBJECT, offsetof(PyCStackObject, task), READONLY},
-    {"startaddr", T_ADDR, offsetof(PyCStackObject, startaddr), READONLY},
-    {0}
-};
 
-/* simple string interface for inspection */
 
-static PyObject *
-cstack_str(PyObject *o)
-{
-    PyCStackObject *cst = (PyCStackObject*)o;
-    return PyString_FromStringAndSize((char*)&cst->stack,
-        cst->ob_size*sizeof(cst->stack[0]));
-}
-
-PyTypeObject PyCStack_Type = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,
-    "stackless.cstack",
-    sizeof(PyCStackObject),
-    sizeof(PyObject *),
-    (destructor)cstack_dealloc,         /* tp_dealloc */
-    0,                                  /* tp_print */
-    0,                                  /* tp_getattr */
-    0,                                  /* tp_setattr */
-    0,                                  /* tp_compare */
-    0,                                  /* tp_repr */
-    0,                                  /* tp_as_number */
-    0,                                  /* tp_as_sequence */
-    0,                                  /* tp_as_mapping */
-    0,                                  /* tp_hash */
-    0,                                  /* tp_call */
-    (reprfunc)cstack_str,               /* tp_str */
-    PyObject_GenericGetAttr,            /* tp_getattro */
-    PyObject_GenericSetAttr,            /* tp_setattro */
-    0,                                  /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
-    cstack_doc,                         /* tp_doc */
-    0,                                  /* tp_traverse */
-    0,                                  /* tp_clear */
-    0,                                  /* tp_richcompare */
-    0,                                  /* tp_weaklistoffset */
-    0,                                  /* tp_iter */
-    0,                                  /* tp_iternext */
-    0,                                  /* tp_methods */
-    cstack_members,                     /* tp_members */
-};
-
-
-static int
-make_initial_stub(void)
-{
-    PyThreadState *ts = PyThreadState_GET();
-    int result;
-
-    if (ts->st.initial_stub != NULL) {
-        Py_DECREF(ts->st.initial_stub);
-        ts->st.initial_stub = NULL;
-    }
-    ts->st.serial_last_jump = ++ts->st.serial;
-    result = slp_transfer(&ts->st.initial_stub, NULL, NULL);
-    if (result < 0)
-        return result;
-    /*
-     * from here, we always arrive with a compatible cstack
-     * that also can be used by main, if it is running
-     * in soft-switching mode.
-     * To insure that, it was necessary to re-create the
-     * initial stub for *every* run of a new main.
-     * This will vanish with greenlet-like stack management.
-     */
-
-    return result;
-}
-
-static PyObject *
-climb_stack_and_eval_frame(PyFrameObject *f)
-{
-    /*
-     * a similar case to climb_stack_and_transfer,
-     * but here we need to incorporate a gap in the
-     * stack into main and keep this gap on the stack.
-     * This way, initial_stub is always valid to be
-     * used to return to the main c stack.
-     */
-    PyThreadState *ts = PyThreadState_GET();
-    intptr_t probe;
-    ptrdiff_t needed = &probe - ts->st.cstack_base;
-    /* in rare cases, the need might have vanished due to the recursion */
-    intptr_t *goobledigoobs;
-    if (needed > 0) {
-    goobledigoobs = alloca(needed * sizeof(intptr_t));
-        if (goobledigoobs == NULL)
-            return NULL;
-    }
-    return slp_eval_frame(f);
-}
 
 
 PyObject *
@@ -280,42 +58,19 @@ slp_eval_frame(PyFrameObject *f)
 {
     PyThreadState *ts = PyThreadState_GET();
     PyFrameObject *fprev = f->f_back;
-    intptr_t * stackref;
 
     if (fprev == NULL && ts->st.main == NULL) {
-        int returning;
-        /* this is the initial frame, so mark the stack base */
-
-        /*
-         * careful, this caused me a major headache.
-         * it is *not* sufficient to just check for fprev == NULL.
-         * Reason: (observed with wxPython):
-         * A toplevel frame is run as a tasklet. When its frame
-         * is deallocated (in tasklet_end), a Python object
-         * with a __del__ method is destroyed. This __del__
-         * will run as a toplevel frame, with f_back == NULL!
+        /* this is the initial frame.  From here we must
+         * run the evaluation loop on a separate tealet, so that
+         * all such tealets are equivalent and can jump back to main
+         * when they exit.
          */
-
-        stackref = STACK_REFPLUS + (intptr_t *) &f;
-        if (ts->st.cstack_base == NULL)
-            ts->st.cstack_base = stackref - CSTACK_GOODGAP;
-        if (stackref > ts->st.cstack_base)
-            return climb_stack_and_eval_frame(f);
-
-        returning = make_initial_stub();
-        if (returning < 0)
+        PyObject *result;
+        if (slp_make_initial_stub(ts))
             return NULL;
-        /* returning will be 1 if we "switched back" to this stub, and 0
-         * if this is the original call that just created the stub.
-         * If the stub is being reused, the argument, i.e. the frame,
-         * is in ts->frame
-         */
-        if (returning == 1) {
-            f = ts->frame;
-            ts->frame = NULL;
-        }
         return slp_run_tasklet(f);
     }
+
     Py_INCREF(Py_None);
     return slp_frame_dispatch(f, fprev, 0, Py_None);
 }
@@ -327,32 +82,29 @@ void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
 
     /* a loop to kill tasklets on the local thread */
     while (1) {
-        PyCStackObject *csfirst = slp_cstack_chain, *cs;
+        PyTealet_data *tdfirst = slp_tealet_list, *td;
         PyTaskletObject *t;
 
-        if (csfirst == NULL)
+        if (tdfirst == NULL)
             break;
-        for (cs = csfirst; ; cs = cs->next) {
-            if (count && cs == csfirst) {
+        for (td = tdfirst; ; td = td->next) {
+            if (count && td == tdfirst) {
                 /* nothing found */
                 return;
             }
             ++count;
-            if (cs->task == NULL)
+            if (td->tasklet == NULL)
                 continue;
             /* can't kill tasklets from other threads here */
-            if (cs->tstate != ts)
-                continue;
-            /* were we asked to kill tasklet on our thread? */
-            if (target_ts != NULL && cs->tstate != target_ts)
+            if (td->tasklet->tstate != ts)
                 continue;
             /* Not killable, another thread's frameless main? */
-            if (slp_get_frame(cs->task) == NULL)
+            if (slp_get_frame(td->tasklet) == NULL)
                 continue;
             break;
         }
         count = 0;
-        t = cs->task;
+        t = td->tasklet;
         Py_INCREF(t); /* cs->task is a borrowed ref */
 
         /* We need to ensure that the tasklet 't' is in the scheduler
@@ -365,7 +117,7 @@ void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
          * killed, they will be implicitly placed before this one,
          * leaving it to run next.
          */
-        if (!t->flags.blocked && t != cs->tstate->st.current) {
+        if (!t->flags.blocked && t != t->tstate->st.current) {
             PyTaskletObject *tmp;
             PyTaskletObject **chain;
             /* unlink from runnable queue if it wasn't previously remove()'d */
@@ -373,12 +125,12 @@ void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
                 assert(t->prev);
                 chain = &t;
                 SLP_CHAIN_REMOVE(PyTaskletObject, chain, tmp, next, prev);
-                ts->st.runcount--;
                 t = tmp;
+                ts->st.runcount--;
             } else
                 Py_INCREF(t); /* a new reference for the runnable queue */
             /* insert into the 'current' chain without modifying 'current' */
-            tmp = cs->tstate->st.current;
+            tmp = t->tstate->st.current;
             chain = &tmp;
             SLP_CHAIN_INSERT(PyTaskletObject, chain, t, next, prev);
             ts->st.runcount++;
@@ -387,10 +139,6 @@ void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
         PyTasklet_Kill(t);
         PyErr_Clear();
 
-        if (t->cstate != NULL) {
-            /* ensure a valid tstate */
-            t->cstate->tstate = slp_initial_tstate;
-        }
         Py_DECREF(t);
     }
 
@@ -400,18 +148,24 @@ void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
      * exit this function
      */
     {
-        PyCStackObject *csfirst = slp_cstack_chain, *cs;
+        PyTealet_data *tdfirst = slp_tealet_list, *td;
         PyTaskletObject *t;
         
-        if (csfirst == NULL)
+        if (tdfirst == NULL)
             return;
         count = 0;
-        for (cs = csfirst; ; cs = cs->next) {
-            if (count && cs == csfirst) {
+        for (td = tdfirst; ; td = td->next) {
+            if (count && td == tdfirst) {
                 return;
             }
+            if (td->tasklet == NULL)
+                continue;
+            t = td->tasklet;
+            if (t->tstate == ts)
+                continue; /* ignore this thread's tasklets */
+            if (target_ts && t->tstate != target_ts)
+                continue; /* want a specific thread */
             count++;
-            t = cs->task;
             Py_INCREF(t); /* cs->task is a borrowed ref */
             PyTasklet_Kill(t);
             PyErr_Clear();
@@ -423,6 +177,9 @@ void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
 void PyStackless_kill_tasks_with_stacks(int allthreads)
 {
     PyThreadState *ts = PyThreadState_Get();
+    int init = 0;
+    if (slp_tealet_list == NULL)
+        return;
 
     if (ts->st.main == NULL) {
         if (initialize_main_and_current()) {
@@ -431,118 +188,72 @@ void PyStackless_kill_tasks_with_stacks(int allthreads)
             Py_XDECREF(s);
             return;
         }
+        init = 1;
     }
     slp_kill_tasks_with_stacks(allthreads ? NULL : ts);
+
+    if (init) {
+        PyTaskletObject *m = ts->st.main, *c;
+        ts->st.main = NULL;
+        c = slp_current_remove();
+        Py_XDECREF(m);
+        Py_XDECREF(c);
+    }
 }
 
 
 /* cstack spilling for recursive calls */
-
-static PyObject *
-eval_frame_callback(PyFrameObject *f, int exc, PyObject *retval)
+typedef struct eval_args
 {
-    PyThreadState *ts = PyThreadState_GET();
-    PyTaskletObject *cur = ts->st.current;
-    PyCStackObject *cst;
-    PyCFrameObject *cf = (PyCFrameObject *) f;
-    intptr_t *saved_base;
-
-    //make sure we don't try softswitching out of this callstack
-    ts->st.nesting_level = cf->n + 1;
-    ts->frame = f->f_back;
-
-    //this tasklet now runs in this tstate.
-    cst = cur->cstate; //The calling cstate
-    cur->cstate = ts->st.initial_stub;
-    Py_INCREF(cur->cstate);
-
-    /* We must base our new stack from here, because otherwise we might find
-     * ourselves in an infinite loop of stack spilling.
-     */
-    saved_base = ts->st.cstack_root;
-    ts->st.cstack_root = STACK_REFPLUS + (intptr_t *) &f;
-
-    /* pull in the right retval and tempval from the arguments */
-    Py_DECREF(retval);
-    retval = cf->ob1;
-    cf->ob1 = NULL;
-    TASKLET_SETVAL_OWN(cur, cf->ob2);
-    cf->ob2 = NULL;
+    PyThreadState *ts;
+    tealet_t *return_to;
+    PyFrameObject *f;
+    int exc;
+    PyObject *retval;
+} eval_args;
 
-    retval = PyEval_EvalFrameEx_slp(ts->frame, exc, retval);
-    ts->st.cstack_root = saved_base;
-
-    /* store retval back into the cstate object */
-    if (retval == NULL)
-        retval = slp_curexc_to_bomb();
-    if (retval == NULL)
-        goto fatal;
-    cf->ob1 = retval;
-
-    /* jump back */
-    Py_DECREF(cur->cstate);
-    cur->cstate = cst;
-    slp_transfer_return(cst);
-    /* should never come here */
-fatal:
-    Py_DECREF(cf); /* since the caller won't do it */
-    return NULL;
+static tealet_t *
+eval_frame_callback(tealet_t *current, void *arg)
+{
+    eval_args *args = (eval_args*)arg;
+    PyThreadState *ts = args->ts;
+    
+    /*make sure we don't try softswitching out of this callstack
+    /* TODO: find a way to keep this tasklet pickleable, but not softswitchable */
+    ts->st.nesting_level++;
+    
+    /* perform the call */
+    args->retval = PyEval_EvalFrameEx_slp(args->f, args->exc, args->retval);
+    ts->st.nesting_level--;
+    return args->return_to;
 }
 
 PyObject *
 slp_eval_frame_newstack(PyFrameObject *f, int exc, PyObject *retval)
 {
     PyThreadState *ts = PyThreadState_GET();
-    PyTaskletObject *cur = ts->st.current;
-    PyCFrameObject *cf = NULL;
-    PyCStackObject *cst;
-
-    if (cur == NULL || PyErr_Occurred()) {
-        /* Bypass this during early initialization or if we have a pending
-         * exception, such as the one set via gen_close().  Doing the stack
-         * magic here will clear that exception.
-         */
-        intptr_t *old = ts->st.cstack_root;
-        ts->st.cstack_root = STACK_REFPLUS + (intptr_t *) &f;
-        retval = PyEval_EvalFrameEx_slp(f,exc, retval);
-        ts->st.cstack_root = old;
-        return retval;
-    }
-    if (ts->st.cstack_root == NULL) {
-        /* this is a toplevel call.  Store the root of stack spilling */
-        ts->st.cstack_root = STACK_REFPLUS + (intptr_t *) &f;
-        retval = PyEval_EvalFrameEx_slp(f, exc, retval);
-        /* and reset it.  We may reenter stackless at a completely different
-         * depth later
-         */
-        ts->st.cstack_root = NULL;
-        return retval;
+    eval_args *args = PyMem_MALLOC(sizeof(eval_args));
+    int result;
+    void *argp;
+    if (!args) {
+        PyErr_NoMemory();
+        return NULL;
     }
-
-    ts->frame = f;
-    cf = slp_cframe_new(eval_frame_callback, 1);
-    if (cf == NULL)
+    args->ts = ts;
+    args->return_to = tealet_current(ts->st.tealet_main);
+    args->f = f;
+    args->exc = exc;
+    args->retval = retval;
+
+    argp = (void*)args;
+    result = slp_run_initial_stub(ts, eval_frame_callback, &argp);
+    if (result) {
+        Py_XDECREF(retval);
+        PyMem_FREE(args);
         return NULL;
-    cf->n = ts->st.nesting_level;
-    cf->ob1 = retval;
-    /* store the tmpval here so that it won't get clobbered
-     * by slp_run_tasklet()
-     */
-    TASKLET_CLAIMVAL(cur, &(cf->ob2));
-    ts->frame = (PyFrameObject *) cf;
-    cst = cur->cstate;
-    cur->cstate = NULL;
-    if (slp_transfer(&cur->cstate, NULL, cur) < 0)
-        goto finally; /* fatal */
-    Py_XDECREF(cur->cstate);
-
-    retval = cf->ob1;
-    cf->ob1 = NULL;
-    if (PyBomb_Check(retval))
-        retval = slp_bomb_explode(retval);
-finally:
-    Py_DECREF(cf);
-    cur->cstate = cst;
+    }
+    retval = args->retval;
+    PyMem_FREE(args);
     return retval;
 }
 
@@ -817,7 +528,6 @@ slp_frame_dispatch_top(PyObject *retval)
 void
 slp_stacklesseval_fini(void)
 {
-    slp_cstack_cacheclear();
 }
 
 #endif /* STACKLESS */
diff --git a/Stackless/module/channelobject.c b/Stackless/module/channelobject.c
index 17e3c9c796e2c8..e2541becc90a76 100644
--- a/Stackless/module/channelobject.c
+++ b/Stackless/module/channelobject.c
@@ -450,7 +450,7 @@ generic_channel_action(PyChannelObject *self, PyObject *arg, int dir, int stackl
     PyTaskletObject *source = ts->st.current;
     PyTaskletObject *target = self->head;
     int cando = dir > 0 ? self->balance < 0 : self->balance > 0;
-    int interthread = cando ? target->cstate->tstate != ts : 0;
+    int interthread = cando ? target->tstate != ts : 0;
     PyObject *tmpval, *retval;
     int fail;
 
@@ -493,7 +493,7 @@ generic_channel_cando(PyThreadState *ts, PyObject **result, PyChannelObject *sel
     /* swap data and perform necessary scheduling */
 
     switchto = target = slp_channel_remove(self, NULL, NULL, &next);
-    interthread = target->cstate->tstate != ts;
+    interthread = target->tstate != ts;
     /* exchange data */
     TASKLET_SWAPVAL(source, target);
 
diff --git a/Stackless/module/scheduling.c b/Stackless/module/scheduling.c
index a74474f2908b94..9e8b71d96f96e7 100644
--- a/Stackless/module/scheduling.c
+++ b/Stackless/module/scheduling.c
@@ -2,6 +2,7 @@
 
 #ifdef STACKLESS
 #include "core/stackless_impl.h"
+#include "core/stackless_tealet.h"
 
 #ifdef WITH_THREAD
 #include "pythread.h"
@@ -330,51 +331,6 @@ PyTypeObject PyBomb_Type = {
 slp_schedule_hook_func *_slp_schedule_fasthook;
 PyObject *_slp_schedule_hook;
 
-static int
-transfer_with_exc(PyCStackObject **cstprev, PyCStackObject *cst, PyTaskletObject *prev)
-{
-    PyThreadState *ts = PyThreadState_GET();
-
-    int tracing = ts->tracing;
-    int use_tracing = ts->use_tracing;
-
-    Py_tracefunc c_profilefunc = ts->c_profilefunc;
-    Py_tracefunc c_tracefunc = ts->c_tracefunc;
-    PyObject *c_profileobj = ts->c_profileobj;
-    PyObject *c_traceobj = ts->c_traceobj;
-
-    PyObject *exc_type = ts->exc_type;
-    PyObject *exc_value = ts->exc_value;
-    PyObject *exc_traceback = ts->exc_traceback;
-    int ret;
-
-    ts->exc_type = ts->exc_value = ts->exc_traceback = NULL;
-    ts->c_profilefunc = ts->c_tracefunc = NULL;
-    ts->c_profileobj = ts->c_traceobj = NULL;
-    ts->use_tracing = ts->tracing = 0;
-
-    /* note that trace/profile are set without ref */
-    Py_XINCREF(c_profileobj);
-    Py_XINCREF(c_traceobj);
-
-    ret = slp_transfer(cstprev, cst, prev);
-
-    ts->tracing = tracing;
-    ts->use_tracing = use_tracing;
-
-    ts->c_profilefunc = c_profilefunc;
-    ts->c_tracefunc = c_tracefunc;
-    ts->c_profileobj = c_profileobj;
-    ts->c_traceobj = c_traceobj;
-    Py_XDECREF(c_profileobj);
-    Py_XDECREF(c_traceobj);
-
-    ts->exc_type = exc_type;
-    ts->exc_value = exc_value;
-    ts->exc_traceback = exc_traceback;
-    return ret;
-}
-
 /* scheduler monitoring */
 
 int
@@ -525,17 +481,6 @@ jump_soft_to_hard(PyFrameObject *f, int exc, PyObject *retval)
 
 /* combined soft/hard switching */
 
-int
-slp_ensure_linkage(PyTaskletObject *t)
-{
-    if (t->cstate->task == t)
-        return 0;
-    if (!slp_cstack_new(&t->cstate, t->cstate->tstate->st.cstack_base, t))
-        return -1;
-    t->cstate->nesting_level = 0;
-    return 0;
-}
-
 
 /* check whether a different thread can be run */
 
@@ -749,7 +694,7 @@ schedule_task_interthread(PyObject **result,
                             int stackless,
                             int *did_switch)
 {
-    PyThreadState *nts = next->cstate->tstate;
+    PyThreadState *nts = next->tstate;
     int fail;
 
     /* get myself ready, since the previous task is going to continue on the
@@ -846,8 +791,7 @@ slp_schedule_task(PyObject **result, PyTaskletObject *prev, PyTaskletObject *nex
         return schedule_task_block(result, prev, stackless, did_switch);
 
 #ifdef WITH_THREAD
-    /* note that next->cstate is undefined if it is ourself */
-    if (next->cstate != NULL && next->cstate->tstate != ts) {
+    if (next->tstate != ts) {
         return schedule_task_interthread(result, prev, next, stackless, did_switch);
     }
 #endif
@@ -891,10 +835,8 @@ static int
 slp_schedule_task_prepared(PyThreadState *ts, PyObject **result, PyTaskletObject *prev, PyTaskletObject *next, int stackless,
                   int *did_switch)
 {
-    PyCStackObject **cstprev;
-
     PyObject *retval;
-    int (*transfer)(PyCStackObject **, PyCStackObject *, PyTaskletObject *);
+    int (*transfer)(PyThreadState *, tealet_t *, PyTaskletObject *);
 
     /* remove the no-soft-irq flag from the runflags */
     int no_soft_irq = ts->st.runflags & PY_WATCHDOG_NO_SOFT_IRQ;
@@ -920,18 +862,16 @@ slp_schedule_task_prepared(PyThreadState *ts, PyObject **result, PyTaskletObject
     if (!stackless || ts->st.nesting_level != 0)
         goto hard_switching;
 
-    /* start of soft switching code */
+    /* We never soft switch out of the main tasklet.  Otherwise, we might end up soft switching
+     * back to the mani tasklet from another stack, but that screws up with assumptions
+     * of the caller.  e.g. the main tasklet might make callbacks back into the program, but
+     * it really shouln't do that from a different stack.  For example, the main stack might
+     * have structured exception handlers installed.
+     */
+    if (prev == ts->st.main)
+        goto hard_switching;
 
-    if (prev->cstate != ts->st.initial_stub) {
-        Py_DECREF(prev->cstate);
-        prev->cstate = ts->st.initial_stub;
-        Py_INCREF(prev->cstate);
-    }
-    if (ts != slp_initial_tstate) {
-        /* ensure to get all tasklets into the other thread's chain */
-        if (slp_ensure_linkage(prev) || slp_ensure_linkage(next))
-            return -1;
-    }
+    /* start of soft switching code */
 
     /* handle exception */
     if (ts->exc_type == Py_None) {
@@ -973,9 +913,8 @@ slp_schedule_task_prepared(PyThreadState *ts, PyObject **result, PyTaskletObject
         ts->c_traceobj = ts->c_profileobj = NULL;
         ts->tracing = ts->use_tracing = 0;
     }
-    assert(next->cstate != NULL);
 
-    if (next->cstate->nesting_level != 0) {
+    if (next->cstate) {
         /* can soft switch out of this tasklet, but the target tasklet
          * was in a hard switched state, so we need a helper frame to
          * jump to the destination stack
@@ -1021,9 +960,8 @@ slp_schedule_task_prepared(PyThreadState *ts, PyObject **result, PyTaskletObject
     /* since we change the stack we must assure that the protocol was met */
     STACKLESS_ASSERT();
 
-    /* note: nesting_level is handled in cstack_new */
-    cstprev = &prev->cstate;
-
+    /* note: nesting_level is handled in slp_transfer */
+    
     ts->st.current = next;
 
     if (ts->exc_type == Py_None) {
@@ -1036,11 +974,11 @@ slp_schedule_task_prepared(PyThreadState *ts, PyObject **result, PyTaskletObject
 
     ++ts->st.nesting_level;
     if (ts->exc_type != NULL || ts->use_tracing || ts->tracing)
-        transfer = transfer_with_exc;
+        transfer = slp_transfer_with_exc;
     else
         transfer = slp_transfer;
 
-    if (transfer(cstprev, next->cstate, prev) >= 0) {
+    if (transfer(ts, next->cstate, prev) >= 0) {
         --ts->st.nesting_level;
         TASKLET_CLAIMVAL(prev, &retval);
         if (PyBomb_Check(retval))
@@ -1086,7 +1024,9 @@ initialize_main_and_current(void)
                 &PyTasklet_Type, noargs, NULL);
     Py_DECREF(noargs);
     if (task == NULL) return -1;
-    assert(task->cstate != NULL);
+    task->cstate = NULL;
+    task->tstate = ts;
+    task->nesting_level = 0;
     ts->st.main = task;
     Py_INCREF(task);
     slp_current_insert(task);
@@ -1213,17 +1153,6 @@ tasklet_end(PyObject *retval)
      */
     TASKLET_SETVAL(task, retval);
 
-    if (ismain) {
-        /*
-         * Because of soft switching, we may find ourself in the top level of a stack that was created
-         * using another stub (another entry point into stackless).  If so, we need a final return to
-         * the original stub if necessary. (Meanwhile, task->cstate may be an old nesting state and not
-         * the original stub, so we take the stub from the tstate)
-         */
-        if (ts->st.serial_last_jump != ts->st.initial_stub->serial)
-            slp_transfer_return(ts->st.initial_stub);
-    }
-
     /* remove from runnables */
     slp_current_remove();
 
diff --git a/Stackless/module/stacklessmodule.c b/Stackless/module/stacklessmodule.c
index 7d2ea7dd5cd672..9f9bd563fc20d9 100644
--- a/Stackless/module/stacklessmodule.c
+++ b/Stackless/module/stacklessmodule.c
@@ -6,7 +6,6 @@
 #include "core/stackless_impl.h"
 
 #define IMPLEMENT_STACKLESSMODULE
-#include "platf/slp_platformselect.h"
 #include "core/cframeobject.h"
 #include "taskletobject.h"
 #include "channelobject.h"
@@ -659,6 +658,9 @@ This can be used to measure the execution time of 1.000.000 switches.");
 
 #define STACK_MAX_USEFUL 64000
 #define STACK_MAX_USESTR "64000"
+#ifdef MS_WINDOWS
+#define alloca _alloca
+#endif
 
 static
 PyObject *
@@ -705,13 +707,12 @@ PyObject *
 test_outside(PyObject *self)
 {
     PyThreadState *ts = PyThreadState_GET();
-    PyTaskletObject *stmain = ts->st.main;
-    PyCStackObject *cst = ts->st.initial_stub;
+    PyTaskletObject *stcurrent, *stmain = ts->st.main;
+    tealet_t *cst = ts->st.initial_stub;
     PyFrameObject *f = ts->frame;
     int recursion_depth = ts->recursion_depth;
     int nesting_level = ts->st.nesting_level;
     PyObject *ret = Py_None;
-    int jump = ts->st.serial_last_jump;
 
     Py_INCREF(ret);
     ts->st.main = NULL;
@@ -719,6 +720,7 @@ test_outside(PyObject *self)
     ts->st.nesting_level = 0;
     ts->frame = NULL;
     ts->recursion_depth = 0;
+    stcurrent = ts->st.current;
     slp_current_remove();
     while (ts->st.runcount > 0) {
         Py_DECREF(ret);
@@ -728,13 +730,12 @@ test_outside(PyObject *self)
         }
     }
     ts->st.main = stmain;
-    Py_XDECREF(ts->st.initial_stub);
+    slp_destroy_initial_stub(ts);
     ts->st.initial_stub = cst;
     ts->frame = f;
-    slp_current_insert(stmain);
+    slp_current_insert(stcurrent);
     ts->recursion_depth = recursion_depth;
     ts->st.nesting_level = nesting_level;
-    ts->st.serial_last_jump = jump;
     return ret;
 }
 
@@ -978,7 +979,6 @@ PyStackless_CallMethod_Main(PyObject *o, char *name, char *format, ...)
             return NULL;
         }
     } else {
-        /* direct call, no method lookup */
         func = o;
         Py_INCREF(func);
     }
@@ -1396,19 +1396,21 @@ static PyObject *
 slpmodule_getuncollectables(PySlpModuleObject *mod, void *context)
 {
     PyObject *lis = PyList_New(0);
-    PyCStackObject *cst = slp_cstack_chain;
-
+    PyTealet_data *data = slp_tealet_list;
+    
     if (lis == NULL)
         return NULL;
-    do {
-        if (cst->task != NULL) {
-            if (PyList_Append(lis, (PyObject *) cst->task)) {
-                Py_DECREF(lis);
-                return NULL;
+    if (data) {
+        do {
+            if (data->tasklet) {
+                if (PyList_Append(lis, (PyObject*)data->tasklet)) {
+                    Py_DECREF(lis);
+                    return NULL;
+                }
             }
-        }
-        cst = cst->next;
-    } while (cst != slp_cstack_chain);
+            data = data->next;
+        } while (data != slp_tealet_list);
+    }
     return lis;
 }
 
@@ -1604,7 +1606,6 @@ _PyStackless_Init(void)
 
     INSERT("slpmodule", PySlpModule_TypePtr);
     INSERT("cframe",    &PyCFrame_Type);
-    INSERT("cstack",    &PyCStack_Type);
     INSERT("bomb",          &PyBomb_Type);
     INSERT("tasklet",   &PyTasklet_Type);
     INSERT("channel",   &PyChannel_Type);
diff --git a/Stackless/module/taskletobject.c b/Stackless/module/taskletobject.c
index 9b9dcff0fabe8a..13c739c732388c 100644
--- a/Stackless/module/taskletobject.c
+++ b/Stackless/module/taskletobject.c
@@ -13,7 +13,7 @@
 void
 slp_current_insert(PyTaskletObject *task)
 {
-    PyThreadState *ts = task->cstate->tstate;
+    PyThreadState *ts = task->tstate;
     PyTaskletObject **chain = &ts->st.current;
 
     SLP_CHAIN_INSERT(PyTaskletObject, chain, task, next, prev);
@@ -23,7 +23,7 @@ slp_current_insert(PyTaskletObject *task)
 void
 slp_current_insert_after(PyTaskletObject *task)
 {
-    PyThreadState *ts = task->cstate->tstate;
+    PyThreadState *ts = task->tstate;
     PyTaskletObject *hold = ts->st.current;
     PyTaskletObject **chain = &ts->st.current;
 
@@ -36,7 +36,7 @@ slp_current_insert_after(PyTaskletObject *task)
 void
 slp_current_uninsert(PyTaskletObject *task)
 {
-    PyThreadState *ts = task->cstate->tstate;
+    PyThreadState *ts = task->tstate;
     PyTaskletObject *hold = ts->st.current;
     PyTaskletObject **chain = &ts->st.current;
     
@@ -74,7 +74,7 @@ slp_current_unremove(PyTaskletObject* task)
 static int
 tasklet_has_c_stack(PyTaskletObject *t)
 {
-    return t->f.frame && t->cstate && t->cstate->nesting_level != 0 ;
+    return t->f.frame && t->cstate;
 }
 
 static int
@@ -93,7 +93,6 @@ tasklet_traverse(PyTaskletObject *t, visitproc visit, void *arg)
         Py_VISIT(f);
     }
     Py_VISIT(t->tempval);
-    Py_VISIT(t->cstate);
     return 0;
 }
 
@@ -117,11 +116,6 @@ tasklet_clear(PyTaskletObject *t)
 {
     tasklet_clear_frames(t);
     TASKLET_SETVAL(t, Py_None); /* always non-zero */
-
-    /* unlink task from cstate */
-    if (t->cstate != NULL && t->cstate->task == t)
-        t->cstate->task = NULL;
-    Py_CLEAR(t->cstate);
 }
 
 /*
@@ -140,7 +134,7 @@ kill_finally (PyObject *ob)
 {
     PyThreadState *ts = PyThreadState_GET();
     PyTaskletObject *self = (PyTaskletObject *) ob;
-    int is_mine = ts == self->cstate->tstate;
+    int is_mine = ts == self->tstate;
 
     /* this could happen if we have a refcount bug, so catch it here.
     assert(self != ts->st.current);
@@ -182,34 +176,18 @@ tasklet_dealloc(PyTaskletObject *t)
     tasklet_clear_frames(t);
     if (t->tsk_weakreflist != NULL)
         PyObject_ClearWeakRefs((PyObject *)t);
-    if (t->cstate != NULL) {
-        assert(t->cstate->task != t || t->cstate->ob_size == 0);
-        Py_DECREF(t->cstate);
-    }
     Py_DECREF(t->tempval);
     Py_XDECREF(t->def_globals);
     t->ob_type->tp_free((PyObject*)t);
 }
 
 
-static PyTaskletObject *
-PyTasklet_New_M(PyTypeObject *type, PyObject *func)
-{
-    char *fmt = "(O)";
-
-    if (func == NULL) fmt = NULL;
-    return (PyTaskletObject *) PyStackless_CallMethod_Main(
-        (PyObject*)type, NULL, fmt, func);
-}
-
 PyTaskletObject *
 PyTasklet_New(PyTypeObject *type, PyObject *func)
 {
     PyThreadState *ts = PyThreadState_GET();
     PyTaskletObject *t;
 
-    /* we always need a cstate, so be sure to initialize */
-    if (ts->st.initial_stub == NULL) return PyTasklet_New_M(type, func);
     if (func != NULL && !PyCallable_Check(func))
         TYPE_ERROR("tasklet function must be a callable", NULL);
     if (type == NULL) type = &PyTasklet_Type;
@@ -223,19 +201,13 @@ PyTasklet_New(PyTypeObject *type, PyObject *func)
         if (func == NULL)
             func = Py_None;
         Py_INCREF(func);
-        t->tempval = func;
+        t->tempval = func; 
         t->tsk_weakreflist = NULL;
-        Py_INCREF(ts->st.initial_stub);
-        t->cstate = ts->st.initial_stub;
+        t->cstate = 0;
+        t->tstate = ts;
+        t->nesting_level = 0;
         t->def_globals = PyEval_GetGlobals();
         Py_XINCREF(t->def_globals);
-        if (ts != slp_initial_tstate) {
-            /* make sure to kill tasklets with their thread */
-            if (slp_ensure_linkage(t)) {
-                Py_DECREF(t);
-                return NULL;
-            }
-        }
     }
     return t;
 }
@@ -324,12 +296,11 @@ tasklet_reduce(PyTaskletObject * t)
         f = f->f_back;
     }
     if (PyList_Reverse(lis)) goto err_exit;
-    assert(t->cstate != NULL);
     tup = Py_BuildValue("(O()(" TASKLET_TUPLEFMT "))",
                         t->ob_type,
                         t->flags,
                         t->tempval,
-                        t->cstate->nesting_level,
+                        t->nesting_level,
                         lis
                         );
 err_exit:
@@ -516,14 +487,14 @@ static TASKLET_INSERT_HEAD(impl_tasklet_insert)
     if (task->next == NULL) {
         if (task->f.frame == NULL && task != ts->st.current)
             RUNTIME_ERROR("You cannot run an unbound(dead) tasklet", -1);
-        if (task->cstate->tstate->st.main == NULL)
+        if (task->tstate->st.main == NULL)
             RUNTIME_ERROR("Target thread isn't initialized", -1);
         Py_INCREF(task);
         slp_current_insert(task);
         /* The tasklet may belong to a different thread, and that thread may
          * be blocked, waiting for something to do!
          */
-        slp_thread_unblock(task->cstate->tstate);
+        slp_thread_unblock(task->tstate);
     }
     return 0;
 }
@@ -584,7 +555,7 @@ static TASKLET_RUN_HEAD(impl_tasklet_run)
     if (ts->st.main == NULL) return PyTasklet_Run_M(task);
     inserted = task->next == NULL;
 
-    if (ts == task->cstate->tstate) {
+    if (ts == task->tstate) {
         /* same thread behaviour.  Insert at the end of the queue and then
          * switch to that task.  Notice that this behaviour upsets FIFO
          * order
@@ -592,7 +563,7 @@ static TASKLET_RUN_HEAD(impl_tasklet_run)
         fail = impl_tasklet_insert(task);
     } else {
         /* interthread. */
-        PyThreadState *rts = task->cstate->tstate;
+        PyThreadState *rts = task->tstate;
         PyTaskletObject *current = rts->st.current;
         if (rts->st.thread.is_idle) {
             /* remote thread is blocked, or unblocked and hasn't got the GIL yet.
@@ -741,20 +712,13 @@ tasklet_set_ignore_nesting(PyObject *self, PyObject *flag)
 static int
 bind_tasklet_to_frame(PyTaskletObject *task, PyFrameObject *frame)
 {
-    PyThreadState *ts = task->cstate->tstate;
-
+    PyThreadState *ts = PyThreadState_GET();
+    
     if (task->f.frame != NULL)
         RUNTIME_ERROR("tasklet is already bound to a frame", -1);
     task->f.frame = frame;
-    if (task->cstate != ts->st.initial_stub) {
-        PyCStackObject *hold = task->cstate;
-        task->cstate = ts->st.initial_stub;
-        Py_INCREF(task->cstate);
-        Py_DECREF(hold);
-        if (ts != slp_initial_tstate)
-            if (slp_ensure_linkage(task))
-                return -1;
-    }
+    task->tstate = ts;
+    task->nesting_level = 0;
     return 0;
     /* note: We expect that f_back is NULL, or will be adjusted immediately */
 }
@@ -861,7 +825,7 @@ static TASKLET_THROW_HEAD(impl_tasklet_throw)
      * f.frame is null for the running tasklet and a dead tasklet
      * A new tasklet has a CFrame
      */
-    if (self->f.frame == NULL && self != self->cstate->tstate->st.current) {
+    if (self->f.frame == NULL && self != self->tstate->st.current) {
         /* however, allow tasklet exit errors for already dead tasklets */
         if (PyObject_IsSubclass(((PyBombObject*)bomb)->curexc_type, PyExc_TaskletExit)) {
             Py_DECREF(bomb);
@@ -1176,8 +1140,7 @@ tasklet_get_recursion_depth(PyTaskletObject *task)
 {
     PyThreadState *ts;
 
-    assert(task->cstate != NULL);
-    ts = task->cstate->tstate;
+    ts = task->tstate;
     return PyInt_FromLong(ts->st.current == task ? ts->recursion_depth
                                                  : task->recursion_depth);
 }
@@ -1187,8 +1150,7 @@ PyTasklet_GetRecursionDepth(PyTaskletObject *task)
 {
     PyThreadState *ts;
 
-    assert(task->cstate != NULL);
-    ts = task->cstate->tstate;
+    ts = task->tstate;
     return ts->st.current == task ? ts->recursion_depth
                                   : task->recursion_depth;
 }
@@ -1199,11 +1161,10 @@ tasklet_get_nesting_level(PyTaskletObject *task)
 {
     PyThreadState *ts;
 
-    assert(task->cstate != NULL);
-    ts = task->cstate->tstate;
+    ts = task->tstate;
     return PyInt_FromLong(
         ts->st.current == task ? ts->st.nesting_level
-                               : task->cstate->nesting_level);
+                               : task->nesting_level);
 }
 
 int
@@ -1211,10 +1172,9 @@ PyTasklet_GetNestingLevel(PyTaskletObject *task)
 {
     PyThreadState *ts;
 
-    assert(task->cstate != NULL);
-    ts = task->cstate->tstate;
+    ts = task->tstate;
     return ts->st.current == task ? ts->st.nesting_level
-                                  : task->cstate->nesting_level;
+                                  : task->nesting_level;
 }
 
 
@@ -1264,11 +1224,10 @@ tasklet_restorable(PyTaskletObject *task)
 {
     PyThreadState *ts;
 
-    assert(task->cstate != NULL);
-    ts = task->cstate->tstate;
+    ts = task->tstate;
     return PyBool_FromLong(
         0 == (ts->st.current == task ? ts->st.nesting_level
-                                     : task->cstate->nesting_level) );
+                                     : task->nesting_level) );
 }
 
 int
@@ -1276,10 +1235,9 @@ PyTasklet_Restorable(PyTaskletObject *task)
 {
     PyThreadState *ts;
 
-    assert(task->cstate != NULL);
-    ts = task->cstate->tstate;
+    ts = task->tstate;
     return 0 == (ts->st.current == task ? ts->st.nesting_level
-                                        : task->cstate->nesting_level);
+                                        : task->nesting_level);
 }
 
 static PyObject *
@@ -1322,14 +1280,10 @@ tasklet_get_prev(PyTaskletObject *task)
 static PyObject *
 tasklet_thread_id(PyTaskletObject *task)
 {
-    return PyInt_FromLong(task->cstate->tstate->thread_id);
+    return PyInt_FromLong(task->tstate->thread_id);
 }
 
 static PyMemberDef tasklet_members[] = {
-    {"cstate", T_OBJECT, offsetof(PyTaskletObject, cstate), READONLY,
-     PyDoc_STR("the C stack object associated with the tasklet.\n\
-     Every tasklet has a cstate, even if it is a trivial one.\n\
-     Please see the cstate doc and the stackless documentation.")},
     {"tempval", T_OBJECT, offsetof(PyTaskletObject, tempval), 0},
     /* blocked, slicing_lock, atomic and such are treated by tp_getset */
     {0}
diff --git a/Stackless/pickling/prickelpit.c b/Stackless/pickling/prickelpit.c
index ff3f08a42a3a92..878093625c920d 100644
--- a/Stackless/pickling/prickelpit.c
+++ b/Stackless/pickling/prickelpit.c
@@ -7,9 +7,6 @@
 #include "pickling/prickelpit.h"
 #include "module/channelobject.h"
 
-/* platform specific constants */
-#include "platf/slp_platformselect.h"
-
 /******************************************************
 
   type template and support for pickle helper types
diff --git a/Stackless/pickling/safe_pickle.c b/Stackless/pickling/safe_pickle.c
index 964d2282ff1a31..ff02112c7cbd71 100644
--- a/Stackless/pickling/safe_pickle.c
+++ b/Stackless/pickling/safe_pickle.c
@@ -1,134 +1,59 @@
 #include "Python.h"
 #ifdef STACKLESS
 
-#include "compile.h"
-
-#include "core/stackless_impl.h"
-#include "platf/slp_platformselect.h"
+#include "core/stackless_tealet.h"
 
 /* safe pickling */
 
-static int(*cPickle_save)(PyObject *, PyObject *, int) = NULL;
-
-static PyObject *
-pickle_callback(PyFrameObject *f, int exc, PyObject *retval)
+typedef struct pickle_args
 {
-    PyThreadState *ts = PyThreadState_GET();
-    PyTaskletObject *cur = ts->st.current;
-    PyCStackObject *cst;
-    PyCFrameObject *cf = (PyCFrameObject *) f;
-    intptr_t *saved_base;
-
-    /* store and update thread state */
-    ts->st.nesting_level = 1; /* always hard-switch from this one now */
-    /* swap the cstates, hold on to the return one */
-    cst = cur->cstate;
-    cur->cstate = ts->st.initial_stub;
-    Py_INCREF(cur->cstate);
-
-    /* We must base our new stack from here, because oterwise we might find
-     * ourselves in an infinite loop of stack spilling.
-     */
-    saved_base = ts->st.cstack_root;
-    ts->st.cstack_root = STACK_REFPLUS + (intptr_t *) &f;
-    Py_DECREF(retval);
-    cf->i = cPickle_save(cf->ob1, cf->ob2, cf->n);
-    ts->st.cstack_root = saved_base;
-
-    /* jump back. No decref, frame contains result. */
-    Py_DECREF(cur->cstate);
-    cur->cstate = cst;
-    ts->frame = cf->f_back;
-    slp_transfer_return(cst);
-    /* never come here */
-    return NULL;
+    PyThreadState *ts;
+    tealet_t *return_to;
+    int (*save)(PyObject *, PyObject *, int);
+    PyObject *self;
+    PyObject *args;
+    int pers_save;
+    int result;
+} pickle_args;
+
+
+static tealet_t *
+pickle_callback(tealet_t *current, void *arg)
+{
+    pickle_args *args = (pickle_args*)arg;
+    args->ts->st.nesting_level++; /* always hard-switch from this one now */
+    args->result = (*args->save)(args->self, args->args, args->pers_save);
+    args->ts->st.nesting_level--;
+    return args->return_to;
 }
 
-static int pickle_M(PyObject *self, PyObject *args, int pers_save);
-
 int
 slp_safe_pickling(int(*save)(PyObject *, PyObject *, int),
                   PyObject *self, PyObject *args, int pers_save)
 {
     PyThreadState *ts = PyThreadState_GET();
-    PyTaskletObject *cur = ts->st.current;
-    int ret = -1;
-    PyCFrameObject *cf = NULL;
-    PyCStackObject *cst;
-
-    if (ts->st.cstack_root == NULL) {
-        /* mark the stack spilling base */
-        ts->st.cstack_root = STACK_REFPLUS + (intptr_t *) &save;
-        ret = (*save)(self, args, pers_save);
-        ts->st.cstack_root = NULL;
-        return ret;
+    pickle_args *pargs = PyMem_MALLOC(sizeof(pickle_args));
+    void *ppargs;
+    int result;
+    if (!pargs) {
+        PyErr_NoMemory();
+        return -1;
     }
-
-    cPickle_save = save;
-
-    if (ts->st.main == NULL)
-        return pickle_M(self, args, pers_save);
-
-    cf = slp_cframe_new(pickle_callback, 1);
-    if (cf == NULL)
-        goto finally;
-    Py_INCREF(self);
-    cf->ob1 = self;
-    Py_INCREF(args);
-    cf->ob2 = args;
-    cf->n = pers_save;
-    ts->frame = (PyFrameObject *) cf;
-    cst = cur->cstate;
-    cur->cstate = NULL;
-    if (slp_transfer(&cur->cstate, NULL, cur) < 0)
-        return -1; /* fatal */
-    Py_XDECREF(cur->cstate);
-    cur->cstate = cst;
-    ret = cf->i;
-finally:
-    Py_XDECREF(cf);
-    return ret;
-}
-
-/* safe unpickling is not needed */
-
-
-/*
- * the following stuff is only needed in the rare case that we are
- * run without any initialisation. In this case, we don't save stack
- * but use slp_eval_frame, which initializes everything.
- */
-
-static PyObject *_self, *_args;
-static int _pers_save;
-
-static PyObject *
-pickle_runmain(PyFrameObject *f, int exc, PyObject *retval)
-{
-    PyThreadState *ts = PyThreadState_GET();
-    Py_XDECREF(retval);
-    ts->frame = f->f_back;
-    Py_DECREF(f);
-    return PyInt_FromLong(cPickle_save(_self, _args, _pers_save));
+    pargs->ts = ts;
+    pargs->return_to = tealet_current(ts->st.tealet_main);
+    pargs->save = save;
+    pargs->self = self;
+    pargs->args = args;
+    pargs->pers_save = pers_save;
+
+    ppargs = (void*)pargs;
+    result = slp_run_initial_stub(ts, pickle_callback, &ppargs);
+    if (result == 0)
+        result = pargs->result;
+    PyMem_FREE(pargs);
+    return result;
 }
 
-static int
-pickle_M(PyObject *self, PyObject *args, int pers_save)
-{
-    PyThreadState *ts = PyThreadState_GET();
-    PyCFrameObject *cf = slp_cframe_new(pickle_runmain, 0);
-    int ret;
-    intptr_t *old_root;
-
-    if (cf == NULL) return -1;
-    _self = self;
-    _args = args;
-    _pers_save = pers_save;
-    old_root = ts->st.cstack_root;
-    ts->st.cstack_root = STACK_REFPLUS + (intptr_t *) &self;
-    ret = slp_int_wrapper(slp_eval_frame((PyFrameObject *)cf));
-    ts->st.cstack_root = old_root;
-    return ret;
-}
 
-#endif
+/* safe unpickling is not needed */
+#endif
\ No newline at end of file
diff --git a/Stackless/platf/switch_amd64_unix_gas.s b/Stackless/platf/switch_amd64_unix_gas.s
deleted file mode 100644
index 6f61106572728b..00000000000000
--- a/Stackless/platf/switch_amd64_unix_gas.s
+++ /dev/null
@@ -1,56 +0,0 @@
-# NOTE: This is not yet safe to use.  Checked in for the same of reference.
-#
-# (int) slp_switch (void);
-
-       .text
-       .type   slp_switch, @function
-       # This next line is required to the C code can find and
-       # link against this function.
-       .global slp_switch
-slp_switch:
-       pushq   %rbp
-       pushq   %r15
-       pushq   %r14
-       pushq   %r13
-       pushq   %r12
-       pushq   %rbx
-
-       # Disabled for now, which should ideally give us identical
-       # behaviour to the inline C version.  Can add this when we
-       # are ready for it.
-       #subq    $8, %rsp
-       #stmxcsr (%rsp)
-
-       movq    %rsp, %rdi
-
-       call slp_save_state             # diff = slp_save_state([?]stackref)
-
-       cmp     $-1, %rax               # if (diff == -1)
-       je      .exit                   #     return -1;
-
-       cmp     $1, %rax                # if (diff ==  1)
-       je      .no_restore             #     return 0;
-
-.restore:
-       add    %rax, %rsp               # Adjust the stack pointer for the state we are restoring.
-
-       call slp_restore_state          # slp_restore_state()
-
-.no_restore:
-       xor     %rax, %rax              # Switch successful (whether we restored or not).
-
-.exit:
-       #ldmxcsr (%rsp)
-       #addq    $8, %rsp
-
-       popq    %rbx
-       popq    %r12
-       popq    %r13
-       popq    %r14
-       popq    %r15
-       # rbp gets popped by the leave statement
-
-       leave
-       ret
-.LFE11:
-       .size   slp_switch, .-slp_switch
diff --git a/Stackless/tealet/platf_slp/mkswitch_stack.py b/Stackless/tealet/platf_slp/mkswitch_stack.py
new file mode 100644
index 00000000000000..5a047ef7f2998e
--- /dev/null
+++ b/Stackless/tealet/platf_slp/mkswitch_stack.py
@@ -0,0 +1,71 @@
+"""
+  mkswitch_stack.py
+
+  Purpose:
+  Generate an include file from the platform dependant
+  include files mentioned in slp_platformselect.h .
+
+  The existing slp_switch implementations are calling
+  the macros slp_save_state and slp_restore_state.
+  Now I want to support real stack switching, that is,
+  the stack is not modified in place, but we jump to
+  a different stack, without copying anything.
+  This costs a lot of memory and should be used for
+  a few high-speed tasklets, only.
+
+  In order to keep things simple, I'm not special-casing
+  the support macroes, but use a different macro set.
+  The machine code is the same, therefore the implementation
+  can be generated from the existing include files.
+
+  We generate a new include file called slp_switch_stack.h .
+"""
+
+def parse_platformselect():
+    fin_name = "slp_platformselect.h"
+    fin = file(fin_name)
+    fout_name = "slp_switch_stack.h"
+    fout = file(fout_name, "w")
+    import sys
+    print>>fout, "/* this file is generated by mkswitch_stack.py, don't edit */"
+    print>>fout
+    for line in fin:
+        tokens = line.split()
+        if not tokens: continue
+        tok = tokens[0]
+        if tok == "#endif":
+            print>>fout, line
+            break # done
+        if tok in ("#if", "#elif"):
+            print>>fout, line
+        elif tok == "#include":
+            finc_name = tokens[1][1:-1]
+            txt = parse_switch(finc_name)
+            print>>fout, txt
+
+edits = (
+    ("slp_switch", "slp_switch_stack"),
+    ("SLP_SAVE_STATE", "SLP_STACK_BEGIN"),
+    ("SLP_RESTORE_STATE", "SLP_STACK_END"),
+)
+
+def parse_switch(fname):
+    f = file(fname)
+    res = []
+    for line in f:
+        if line.strip() == "static int":
+            res.append(line)
+            break
+    for line in f:
+        res.append(line)
+        if line.rstrip() == "}":
+            break
+    # end of procedure.
+    # now substitute
+    s = "".join(res)
+    for txt, repl in edits:
+        s = s.replace(txt, repl)
+    return s
+
+if __name__ == "__main__":
+    parse_platformselect()
\ No newline at end of file
diff --git a/Stackless/tealet/platf_slp/slp_fallback.h b/Stackless/tealet/platf_slp/slp_fallback.h
new file mode 100644
index 00000000000000..ef4687f3df025b
--- /dev/null
+++ b/Stackless/tealet/platf_slp/slp_fallback.h
@@ -0,0 +1,67 @@
+/* slp_fallback.h
+ * Implements a fallback mechanism where the stacless python switching code be used.
+ * Stackless python switching code uses global variables to communicate and thus is not
+ * thread safe. We do not attempt to provide a lock for those global variables here, it
+ * is up to the user in each case to ensure that switching only occurs on one thread at
+ * a time.
+ */
+ #include <stdint.h>
+
+
+/* rename the slp_switch function that the slp headers will define */
+#define slp_switch fallback_slp_switch
+
+/* sttic vars to pass inforamtion around.  This is what makes this non-threadsafe */
+typedef void *(*save_restore_t)(void*, void*);
+static save_restore_t fallback_save_state=NULL, fallback_restore_state=NULL;
+static void *fallback_extra=NULL;
+static void *fallback_newstack = NULL;
+
+/* call the provided save_satate method with its arguments.
+ * compute a proper stack delta and store the result for later
+ */
+#define SLP_SAVE_STATE(stackref, stsizediff) do {\
+	intptr_t stsizeb; \
+	void *newstack; \
+	stackref += STACK_MAGIC; \
+    newstack = fallback_save_state(stackref, fallback_extra); \
+	fallback_newstack = newstack; /* store this for restore_state */ \
+	if ((intptr_t)newstack & 1) \
+		return (int)newstack; \
+    /* compute the delta expected by old switching code */ \
+	stsizediff = ((intptr_t*) newstack - (intptr_t*)stackref) * sizeof(intptr_t); \
+} while (0)
+
+/* call the restore_state using the stored data */
+#define SLP_RESTORE_STATE() do { \
+	fallback_restore_state(fallback_newstack, fallback_extra); \
+} while(0)
+
+#define SLP_EVAL
+#include "slp_platformselect.h"
+
+/* This is a wrapper that takes care of setting the appropriate globals */
+#undef slp_switch
+static void *slp_switch(save_restore_t save_state,
+                        save_restore_t restore_state,
+                        void *extra)
+{
+	/* need to store the restore information on the stack */
+	void *result;
+	fallback_save_state = save_state;
+	fallback_restore_state = restore_state;
+	fallback_extra = extra;
+
+	fallback_slp_switch();
+	result = fallback_newstack;
+	
+    /* clearing them again is prudent */
+	fallback_save_state = fallback_restore_state = NULL;
+	fallback_extra = fallback_newstack = NULL;
+
+	/* successful switch was indicated by save_state returning an even result */
+	if (! ((intptr_t)result & 1))
+		result = NULL;
+	/* otherwise it is 1 or -1 */
+	return result;
+}
\ No newline at end of file
diff --git a/Stackless/platf/slp_platformselect.h b/Stackless/tealet/platf_slp/slp_platformselect.h
similarity index 96%
rename from Stackless/platf/slp_platformselect.h
rename to Stackless/tealet/platf_slp/slp_platformselect.h
index 59ad0ef371404e..90b46370c6e463 100644
--- a/Stackless/platf/slp_platformselect.h
+++ b/Stackless/tealet/platf_slp/slp_platformselect.h
@@ -2,9 +2,9 @@
  * Platform Selection for Stackless Python
  */
 
-#if   defined(MS_WIN32) && !defined(MS_WIN64) && defined(_M_IX86)
+#if   defined(_M_IX86)
 #include "switch_x86_msvc.h" /* MS Visual Studio on X86 */
-#elif defined(MS_WIN64) && defined(_M_X64)
+#elif defined(_M_X64)
 #include "switch_x64_msvc.h" /* MS Visual Studio on X64 */
 #elif defined(__GNUC__) && defined(__i386__)
 #include "switch_x86_unix.h" /* gcc on X86 */
@@ -28,6 +28,8 @@
 #include "switch_mips_unix.h" /* MIPS */
 #elif defined(SN_TARGET_PS3)
 #include "switch_ps3_SNTools.h" /* Sony PS3 */
+#else
+#error "platform unsupported by stackless python"
 #endif
 
 /* default definitions if not defined in above files */
diff --git a/Stackless/tealet/platf_slp/slp_switch_stack.h b/Stackless/tealet/platf_slp/slp_switch_stack.h
new file mode 100644
index 00000000000000..4eb03f379a6f2f
--- /dev/null
+++ b/Stackless/tealet/platf_slp/slp_switch_stack.h
@@ -0,0 +1,279 @@
+/* this file is generated by mkswitch_stack.py, don't edit */
+
+#if   defined(MS_WIN32) && !defined(MS_WIN64) && defined(_M_IX86)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+    __asm mov stackref, esp;
+    /* modify EBX, ESI and EDI in order to get them preserved */
+    __asm mov ebx, ebx;
+    __asm xchg esi, edi;
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm {
+        mov     eax, stsizediff
+        add     esp, eax
+        add     ebp, eax
+        }
+        SLP_STACK_END();
+        return 0;
+    }
+#pragma warning(default:4731)
+}
+
+#elif defined(MS_WIN64) && defined(_M_X64)
+
+
+#elif defined(__GNUC__) && defined(__i386__)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+#if STACKLESS_FRHACK
+    __asm__ volatile ("" : : : "esi", "edi");
+#else
+    __asm__ volatile ("" : : : "ebx", "esi", "edi");
+#endif
+    __asm__ ("movl %%esp, %0" : "=g" (stackref));
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm__ volatile (
+            "addl %0, %%esp\n"
+            "addl %0, %%ebp\n"
+            :
+            : "r" (stsizediff)
+            );
+        SLP_STACK_END();
+        return 0;
+    }
+#if STACKLESS_FRHACK
+    __asm__ volatile ("" : : : "esi", "edi");
+#else
+    __asm__ volatile ("" : : : "ebx", "esi", "edi");
+#endif
+}
+
+#elif defined(__GNUC__) && defined(__amd64__)
+
+static int
+slp_switch_stack(void)
+{
+    register long *stackref, stsizediff;
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+    __asm__ ("movq %%rsp, %0" : "=g" (stackref));
+    {
+    SLP_STACK_BEGIN(stackref, stsizediff);
+    __asm__ volatile (
+        "addq %0, %%rsp\n"
+        "addq %0, %%rbp\n"
+        :
+        : "r" (stsizediff)
+        );
+    SLP_STACK_END();
+    return 0;
+    }
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+}
+
+#elif defined(__GNUC__) && defined(__PPC__) && defined(__linux__)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+    __asm__ ("mr %0, 1" : "=g" (stackref) : );
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm__ volatile (
+            "mr 11, %0\n"
+            "add 1, 1, 11\n"
+            "add 30, 30, 11\n"
+            : /* no outputs */
+            : "g" (stsizediff)
+            : "11"
+            );
+        SLP_STACK_END();
+        return 0;
+    }
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+}
+
+#elif defined(__GNUC__) && defined(__ppc__) && defined(__APPLE__)
+
+static int
+slp_switch_stack(void)
+{
+    static int x = 0;
+    register intptr_t *stackref;
+    register int stsizediff;
+    __asm__ volatile (
+        "; asm block 1\n"
+        : /* no outputs */
+        : "r" (x)
+        : REGS_TO_SAVE
+    );
+    __asm__ ("; asm block 2\n\tmr %0, r1" : "=g" (stackref) : );
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm__ volatile (
+            "; asm block 3\n"
+            "\tmr r11, %0\n"
+            "\tadd r1, r1, r11\n"
+            "\tadd r30, r30, r11\n"
+            : /* no outputs */
+            : "g" (stsizediff)
+            : "r11"
+        );
+        SLP_STACK_END();
+        return 0;
+    }
+}
+
+#elif defined(__GNUC__) && defined(sparc) && defined(sun)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+
+    /* Put the stack pointer into stackref */
+
+    /* Sparc special: at first, flush register windows
+     */
+    __asm__ volatile (
+        "ta %1\n\t"
+        "mov %%sp, %0"
+        : "=r" (stackref) :  "i" (ST_FLUSH_WINDOWS));
+
+    {   /* You shalt put SLP_STACK_BEGIN into a local block */
+
+        SLP_STACK_BEGIN(stackref, stsizediff);
+
+        /* Increment stack and frame pointer by stsizediff */
+
+        /* Sparc special: at first load new return address.
+           This cannot be done later, because the stack
+           might be overwritten again just after SLP_STACK_END
+           has finished. BTW: All other registers (l0-l7 and i0-i5)
+           might be clobbered too.
+         */
+        __asm__ volatile (
+            "ld [%0+60], %%i7\n\t"
+            "add %1, %%sp, %%sp\n\t"
+            "add %1, %%fp, %%fp"
+            : : "r" (_cst->stack), "r" (stsizediff)
+            : "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+              "%i0", "%i1", "%i2", "%i3", "%i4", "%i5");
+
+        SLP_STACK_END();
+
+        /* Run far away as fast as possible, don't look back at the sins.
+         * The LORD rained down burning sulfur on Sodom and Gomorra ...
+         */
+
+        /* Sparc special: Must make it *very* clear to the CPU that
+           it shouldn't look back into the register windows
+         */
+        __asm__ volatile ( "ta %0" : : "i" (ST_CLEAN_WINDOWS));
+        return 0;
+    }
+}
+
+#elif defined(__GNUC__) && defined(__s390__) && defined(__linux__)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+    __asm__ ("lr %0, 15" : "=g" (stackref) : );
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm__ volatile (
+            "ar 15, %0"
+            : /* no outputs */
+            : "g" (stsizediff)
+            );
+        SLP_STACK_END();
+        return 0;
+    }
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+}
+
+#elif defined(__GNUC__) && defined(__s390x__) && defined(__linux__)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+    __asm__ ("lr %0, 15" : "=g" (stackref) : );
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm__ volatile (
+            "ar 15, %0"
+            : /* no outputs */
+            : "g" (stsizediff)
+            );
+        SLP_STACK_END();
+        return 0;
+    }
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+}
+
+#elif defined(__GNUC__) && defined(__arm__) && defined(__thumb__)
+
+
+#elif defined(__GNUC__) && defined(__arm32__)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+    __asm__ ("mov %0,sp" : "=g" (stackref));
+    {
+        SLP_STACK_BEGIN(stackref, stsizediff);
+        __asm__ volatile (
+            "add sp,sp,%0\n"
+            "add fp,fp,%0\n"
+            :
+            : "r" (stsizediff)
+            );
+        SLP_STACK_END();
+        return 0;
+    }
+    __asm__ volatile ("" : : : REGS_TO_SAVE);
+}
+
+#elif defined(__GNUC__) && defined(__mips__) && defined(__linux__)
+
+static int
+slp_switch_stack(void)
+{
+    register int *stackref, stsizediff;
+    /* __asm__ __volatile__ ("" : : : REGS_TO_SAVE); */
+    __asm__ ("move %0, $29" : "=r" (stackref) : );
+    {
+    SLP_STACK_BEGIN(stackref, stsizediff);
+    __asm__ __volatile__ (
+#ifdef __mips64
+        "daddu $29, %0\n"
+#else
+        "addu $29, %0\n"
+#endif
+        : /* no outputs */
+        : "r" (stsizediff)
+        );
+    SLP_STACK_END();
+    }
+    /* __asm__ __volatile__ ("" : : : REGS_TO_SAVE); */
+    return 0;
+}
+
+#endif
+
diff --git a/Stackless/platf/switch_amd64_unix.h b/Stackless/tealet/platf_slp/switch_amd64_unix.h
similarity index 100%
rename from Stackless/platf/switch_amd64_unix.h
rename to Stackless/tealet/platf_slp/switch_amd64_unix.h
diff --git a/Stackless/platf/switch_arm32_gcc.h b/Stackless/tealet/platf_slp/switch_arm32_gcc.h
similarity index 100%
rename from Stackless/platf/switch_arm32_gcc.h
rename to Stackless/tealet/platf_slp/switch_arm32_gcc.h
diff --git a/Stackless/platf/switch_arm_thumb_gas.s b/Stackless/tealet/platf_slp/switch_arm_thumb_gas.s
similarity index 100%
rename from Stackless/platf/switch_arm_thumb_gas.s
rename to Stackless/tealet/platf_slp/switch_arm_thumb_gas.s
diff --git a/Stackless/platf/switch_arm_thumb_gcc.h b/Stackless/tealet/platf_slp/switch_arm_thumb_gcc.h
similarity index 100%
rename from Stackless/platf/switch_arm_thumb_gcc.h
rename to Stackless/tealet/platf_slp/switch_arm_thumb_gcc.h
diff --git a/Stackless/platf/switch_mips_unix.h b/Stackless/tealet/platf_slp/switch_mips_unix.h
similarity index 100%
rename from Stackless/platf/switch_mips_unix.h
rename to Stackless/tealet/platf_slp/switch_mips_unix.h
diff --git a/Stackless/platf/switch_ppc_macosx.h b/Stackless/tealet/platf_slp/switch_ppc_macosx.h
similarity index 100%
rename from Stackless/platf/switch_ppc_macosx.h
rename to Stackless/tealet/platf_slp/switch_ppc_macosx.h
diff --git a/Stackless/platf/switch_ppc_unix.h b/Stackless/tealet/platf_slp/switch_ppc_unix.h
similarity index 99%
rename from Stackless/platf/switch_ppc_unix.h
rename to Stackless/tealet/platf_slp/switch_ppc_unix.h
index ccc893b2c2022b..f0bf07845f1dcf 100644
--- a/Stackless/platf/switch_ppc_unix.h
+++ b/Stackless/tealet/platf_slp/switch_ppc_unix.h
@@ -65,7 +65,7 @@ slp_switch(void)
  * further self-processing support
  */
 
-/*
+/* 
  * if you want to add self-inspection tools, place them
  * here. See the x86_msvc for the necessary defines.
  * These features are highly experimental und not
diff --git a/Stackless/platf/switch_ps3_SNTools.h b/Stackless/tealet/platf_slp/switch_ps3_SNTools.h
similarity index 100%
rename from Stackless/platf/switch_ps3_SNTools.h
rename to Stackless/tealet/platf_slp/switch_ps3_SNTools.h
diff --git a/Stackless/platf/switch_ps3_SNTools.s b/Stackless/tealet/platf_slp/switch_ps3_SNTools.s
similarity index 100%
rename from Stackless/platf/switch_ps3_SNTools.s
rename to Stackless/tealet/platf_slp/switch_ps3_SNTools.s
diff --git a/Stackless/platf/switch_s390_unix.h b/Stackless/tealet/platf_slp/switch_s390_unix.h
similarity index 100%
rename from Stackless/platf/switch_s390_unix.h
rename to Stackless/tealet/platf_slp/switch_s390_unix.h
diff --git a/Stackless/platf/switch_sparc_sun_gcc.h b/Stackless/tealet/platf_slp/switch_sparc_sun_gcc.h
similarity index 100%
rename from Stackless/platf/switch_sparc_sun_gcc.h
rename to Stackless/tealet/platf_slp/switch_sparc_sun_gcc.h
diff --git a/Stackless/platf/switch_x64_masm.asm b/Stackless/tealet/platf_slp/switch_x64_masm.asm
similarity index 100%
rename from Stackless/platf/switch_x64_masm.asm
rename to Stackless/tealet/platf_slp/switch_x64_masm.asm
diff --git a/Stackless/platf/switch_x64_msvc.h b/Stackless/tealet/platf_slp/switch_x64_msvc.h
similarity index 100%
rename from Stackless/platf/switch_x64_msvc.h
rename to Stackless/tealet/platf_slp/switch_x64_msvc.h
diff --git a/Stackless/platf/switch_x86_msvc.h b/Stackless/tealet/platf_slp/switch_x86_msvc.h
similarity index 100%
rename from Stackless/platf/switch_x86_msvc.h
rename to Stackless/tealet/platf_slp/switch_x86_msvc.h
diff --git a/Stackless/platf/switch_x86_unix.h b/Stackless/tealet/platf_slp/switch_x86_unix.h
similarity index 93%
rename from Stackless/platf/switch_x86_unix.h
rename to Stackless/tealet/platf_slp/switch_x86_unix.h
index 6668e659bb5ff3..c95362c0acbea5 100644
--- a/Stackless/platf/switch_x86_unix.h
+++ b/Stackless/tealet/platf_slp/switch_x86_unix.h
@@ -34,7 +34,7 @@ slp_switch(void)
 #if STACKLESS_FRHACK
     __asm__ volatile ("" : : : "esi", "edi");
 #else
-    __asm__ volatile ("" : : : "ebx", "esi", "edi");
+    __asm__ volatile ("" : : : "ebx", "esi", "edi", "ebp");
 #endif
     __asm__ ("movl %%esp, %0" : "=g" (stackref));
     {
@@ -51,7 +51,7 @@ slp_switch(void)
 #if STACKLESS_FRHACK
     __asm__ volatile ("" : : : "esi", "edi");
 #else
-    __asm__ volatile ("" : : : "ebx", "esi", "edi");
+    __asm__ volatile ("" : : : "ebx", "esi", "edi", "ebp");
 #endif
 }
 
diff --git a/Stackless/tealet/slp_platformselect.h b/Stackless/tealet/slp_platformselect.h
new file mode 100644
index 00000000000000..e86580628f9e7d
--- /dev/null
+++ b/Stackless/tealet/slp_platformselect.h
@@ -0,0 +1,32 @@
+
+/* define USE_SLP_FALLBACK here if you want to test the SLP_FALLBACK mechanism */
+#define ENABLE_SLP_FALLBACK
+/* #define USE_SLP_FALLBACK */
+
+#if defined USE_SLP_FALLBACK && !defined ENABLE_SLP_FALLBACK
+#define ENABLE_SLP_FALLBACK
+#endif
+
+#ifndef USE_SLP_FALLBACK
+#if   defined(_M_IX86)
+#include "switch_x86_msvc.h" /* MS Visual Studio on X86 */
+#elif defined(_M_X64)
+#include "switch_x64_msvc.h" /* MS Visual Studio on X64 */
+#elif defined(__GNUC__) && defined(__amd64__)
+#include "switch_x86_64_gcc.h" /* gcc on amd64 */
+#elif defined(__GNUC__) && defined(__i386__)
+#include "switch_x86_gcc.h" /* gcc on X86 */
+#else
+#ifdef ENABLE_SLP_FALLBACK
+#define USE_SLP_FALLBACK
+#else
+#error "Unsupported platform!"
+#endif
+#endif
+#endif
+
+#ifdef USE_SLP_FALLBACK
+/* hope this is standard C */
+#pragma message("fallback to stackless platform support. Switching is not thread-safe")
+#include "platf_slp/slp_fallback.h"
+#endif
diff --git a/Stackless/tealet/switch_x64_msvc.asm b/Stackless/tealet/switch_x64_msvc.asm
new file mode 100644
index 00000000000000..a9ebd40409703e
--- /dev/null
+++ b/Stackless/tealet/switch_x64_msvc.asm
@@ -0,0 +1,103 @@
+;
+; stack switching code for MASM on x64
+; Kristjan Valur Jonsson, apr 2011
+;
+
+include macamd64.inc
+
+pop_reg MACRO reg
+	pop reg
+ENDM
+
+load_xmm128 macro Reg, Offset
+	movdqa  Reg, Offset[rsp]
+endm
+
+.code
+
+;arguments save_state, restore_state, extra are passed in rcx, rdx, r8 respectively
+;slp_switch PROC FRAME
+NESTED_ENTRY slp_switch, _TEXT$00
+	; save all registers that the x64 ABI specifies as non-volatile.
+	; This includes some mmx registers.  May not always be necessary,
+	; unless our application is doing 3D, but better safe than sorry.
+	alloc_stack 168; 10 * 16 bytes, plus 8 bytes to make stack 16 byte aligned
+	save_xmm128 xmm15, 144
+	save_xmm128 xmm14, 128
+	save_xmm128 xmm13, 112
+	save_xmm128 xmm12, 96
+	save_xmm128 xmm11, 80
+	save_xmm128 xmm10, 64
+	save_xmm128 xmm9,  48
+	save_xmm128 xmm8,  32
+	save_xmm128 xmm7,  16
+	save_xmm128 xmm6,  0
+	
+	push_reg r15
+	push_reg r14
+	push_reg r13
+	push_reg r12
+	
+	push_reg rbp
+	push_reg rbx
+	push_reg rdi
+	push_reg rsi
+	
+	sub rsp, 20h ;allocate shadow stack space for the arguments (must be multiple of 16)
+	.allocstack 20h
+.endprolog
+
+	;save argments in nonvolatile registers
+	mov r12, rcx ;save_state
+	mov r13, rdx
+	mov r14, r8
+
+	; load stack base that we are saving minus the callee argument
+	; shadow stack.  We don't want that clobbered
+	lea rcx, [rsp+20h] 
+	mov rdx, r14
+	call r12 ;pass stackpointer, return new stack pointer in eax
+	
+	; an odd value means that we don't restore, could be
+	; an error (e.g. -1) or indication that we only want
+	; to save state (1).  return that value to the caller.
+	test rax, 1
+	jnz exit
+	
+	;actual stack switch (and re-allocating the shadow stack):
+	lea rsp, [rax-20h]
+	
+	mov rcx, rax ;pass new stack pointer
+	mov rdx, r14
+	call r13
+	;return the rax
+EXIT:
+	
+	add rsp, 20h
+	pop_reg rsi
+	pop_reg rdi
+	pop_reg rbx
+	pop_reg rbp
+	
+	pop_reg r12
+	pop_reg r13
+	pop_reg r14
+	pop_reg r15
+	
+	load_xmm128 xmm15, 144
+	load_xmm128 xmm14, 128
+	load_xmm128 xmm13, 112
+	load_xmm128 xmm12, 96
+	load_xmm128 xmm11, 80
+	load_xmm128 xmm10, 64
+	load_xmm128 xmm9,  48
+	load_xmm128 xmm8,  32
+	load_xmm128 xmm7,  16
+	load_xmm128 xmm6,  0
+	add rsp, 168
+	ret
+	
+NESTED_END slp_switch, _TEXT$00
+;slp_switch ENDP 
+	
+END
\ No newline at end of file
diff --git a/Stackless/tealet/switch_x64_msvc.h b/Stackless/tealet/switch_x64_msvc.h
new file mode 100644
index 00000000000000..1c0617121956b8
--- /dev/null
+++ b/Stackless/tealet/switch_x64_msvc.h
@@ -0,0 +1,7 @@
+/* The actual stack saving function, which just stores the stack,
+ * this declared in an .asm file
+ */
+extern void *slp_switch(void *(*save_state)(void*, void*),
+                        void *(*restore_state)(void*, void*),
+                        void *extra);
+
diff --git a/Stackless/tealet/switch_x86_64_gcc.h b/Stackless/tealet/switch_x86_64_gcc.h
new file mode 100644
index 00000000000000..c240c1c261ee9b
--- /dev/null
+++ b/Stackless/tealet/switch_x86_64_gcc.h
@@ -0,0 +1,66 @@
+
+static void *slp_switch(void *(*save_state)(void*, void*),
+                        void *(*restore_state)(void*, void*),
+                        void *extra)
+{
+  void *result;
+  __asm__ volatile (
+     "pushq %%rbp\n"
+     "pushq %%rbx\n"       /* push the registers that may contain  */
+     "pushq %%rsi\n"       /* some value that is meant to be saved */
+     "pushq %%rdi\n"
+     "pushq %%rcx\n"
+     "pushq %%rdx\n"
+     "pushq %%r8\n"
+     "pushq %%r9\n"
+     "pushq %%r10\n"
+     "pushq %%r11\n"
+     "pushq %%r12\n"
+     "pushq %%r13\n"
+     "pushq %%r14\n"
+     "pushq %%r15\n"
+
+     "movq %%rax, %%r12\n" /* save 'restore_state' for later */
+     "movq %%rsi, %%r13\n" /* save 'extra' for later         */
+
+                           /* arg 2: extra                       */
+     "movq %%rsp, %%rdi\n" /* arg 1: current (old) stack pointer */
+     "call *%%rcx\n"       /* call save_state()                  */
+
+     "testb $1, %%al\n"        /* skip the rest if the return value is odd */
+     "jnz 0f\n"
+
+     "movq %%rax, %%rsp\n"     /* change the stack pointer */
+
+     /* From now on, the stack pointer is modified, but the content of the
+        stack is not restored yet.  It contains only garbage here. */
+
+     "movq %%r13, %%rsi\n" /* arg 2: extra                       */
+     "movq %%rax, %%rdi\n" /* arg 1: current (new) stack pointer */
+     "call *%%r12\n"       /* call restore_state()               */
+
+     /* The stack's content is now restored. */
+
+     "0:\n"
+     "popq %%r15\n"
+     "popq %%r14\n"
+     "popq %%r13\n"
+     "popq %%r12\n"
+     "popq %%r11\n"
+     "popq %%r10\n"
+     "popq %%r9\n"
+     "popq %%r8\n"
+     "popq %%rdx\n"
+     "popq %%rcx\n"
+     "popq %%rdi\n"
+     "popq %%rsi\n"
+     "popq %%rbx\n"
+     "popq %%rbp\n"
+
+     : "=a"(result)              /* output variables */
+     : "a"(restore_state),       /* input variables  */
+       "c"(save_state),
+       "S"(extra)
+     );
+  return result;
+}
diff --git a/Stackless/tealet/switch_x86_gcc.h b/Stackless/tealet/switch_x86_gcc.h
new file mode 100644
index 00000000000000..8621dcc584922f
--- /dev/null
+++ b/Stackless/tealet/switch_x86_gcc.h
@@ -0,0 +1,53 @@
+
+static void *slp_switch(void *(*save_state)(void*, void*),
+                        void *(*restore_state)(void*, void*),
+                        void *extra)
+{
+  void *result;
+  __asm__ volatile (
+     "pushl %%ebp\n"
+     "pushl %%ebx\n"       /* push the registers that may contain  */
+     "pushl %%esi\n"       /* some value that is meant to be saved */
+     "pushl %%edi\n"
+     "pushl %%ecx\n"
+     "pushl %%edx\n"
+
+     "movl %%eax, %%esi\n" /* save 'restore_state' for later */
+     "movl %%edx, %%edi\n" /* save 'extra' for later         */
+
+     "movl %%esp, %%eax\n"
+
+     "pushl %%edx\n"       /* arg 2: extra                       */
+     "pushl %%eax\n"       /* arg 1: current (old) stack pointer */
+     "call *%%ecx\n"       /* call save_state()                  */
+
+     "testl $1, %%eax\n"       /* skip the rest if the return value is odd */
+     "jnz 0f\n"
+
+     "movl %%eax, %%esp\n"     /* change the stack pointer */
+
+     /* From now on, the stack pointer is modified, but the content of the
+        stack is not restored yet.  It contains only garbage here. */
+
+     "pushl %%edi\n"       /* arg 2: extra                       */
+     "pushl %%eax\n"       /* arg 1: current (new) stack pointer */
+     "call *%%esi\n"       /* call restore_state()               */
+
+     /* The stack's content is now restored. */
+
+     "0:\n"
+     "addl $8, %%esp\n"
+     "popl %%edx\n"
+     "popl %%ecx\n"
+     "popl %%edi\n"
+     "popl %%esi\n"
+     "popl %%ebx\n"
+     "popl %%ebp\n"
+
+     : "=a"(result)              /* output variables */
+     : "a"(restore_state),       /* input variables  */
+       "c"(save_state),
+       "d"(extra)
+     );
+  return result;
+}
diff --git a/Stackless/tealet/switch_x86_msvc.asm b/Stackless/tealet/switch_x86_msvc.asm
new file mode 100644
index 00000000000000..628643e3975aec
--- /dev/null
+++ b/Stackless/tealet/switch_x86_msvc.asm
@@ -0,0 +1,44 @@
+
+.386
+.model flat, c
+
+.code
+
+slp_switch_raw PROC save_state:DWORD, restore_state:DWORD, extra:DWORD
+  
+  ;save registers. EAX ECX and EDX are available for function use and thus
+  ;do not have to be stored.
+  push ebx
+  push esi
+  push edi
+  push ebp
+  
+  mov esi, restore_state ; /* save 'restore_state' for later */
+  mov edi, extra ;         /* save 'extra' for later         */
+
+  mov eax, esp
+
+  push edi ;               /* arg 2: extra                       */
+  push eax ;               /* arg 1: current (old) stack pointer */
+  mov  ecx, save_state
+  call ecx ;               /* call save_state()                  */
+
+  test eax, 1;             /* skip the restore if the return value is odd */
+  jnz exit
+
+  mov esp, eax;            /* change the stack pointer */
+
+  push edi ;               /* arg 2: extra                       */
+  push eax ;               /* arg 1: current (new) stack pointer */
+  call esi ;               /* call restore_state()               */
+
+exit:
+  add esp, 8
+  pop  ebp
+  pop  edi
+  pop  esi
+  pop  ebx
+  ret
+slp_switch_raw ENDP
+
+end
\ No newline at end of file
diff --git a/Stackless/tealet/switch_x86_msvc.h b/Stackless/tealet/switch_x86_msvc.h
new file mode 100644
index 00000000000000..bd219271f8e281
--- /dev/null
+++ b/Stackless/tealet/switch_x86_msvc.h
@@ -0,0 +1,26 @@
+/* The actual stack saving function, which just stores the stack,
+ * this declared in an .asm file
+ */
+extern void *slp_switch_raw(void *(*save_state)(void*, void*),
+                        void *(*restore_state)(void*, void*),
+                        void *extra);
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+/* Store any other runtime information on the local stack */
+#pragma optimize("", off) /* so that autos are stored on the stack */
+#pragma warning(disable:4733) /* disable warning about modifying FS[0] */
+
+static void *slp_switch(void *(*save_state)(void*, void*),
+                        void *(*restore_state)(void*, void*),
+                        void *extra)
+{
+    /* store the structured exception state for this stack */
+    DWORD seh_state = __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
+    void * result = slp_switch_raw(save_state, restore_state, extra);
+    __writefsdword(FIELD_OFFSET(NT_TIB, ExceptionList), seh_state);
+    return result;
+}
+#pragma warning(default:4733) /* disable warning about modifying FS[0] */
+#pragma optimize("", on)
diff --git a/Stackless/tealet/tealet.c b/Stackless/tealet/tealet.c
new file mode 100644
index 00000000000000..9744fa65639d47
--- /dev/null
+++ b/Stackless/tealet/tealet.c
@@ -0,0 +1,785 @@
+/********** A minimal coroutine package for C **********
+ * By Armin Rigo
+ * Documentation: see the source code of the greenlet package from
+ *
+ *     http://codespeak.net/svn/greenlet/trunk/c/_greenlet.c
+ */
+
+#include "tealet.h"
+
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+
+/************************************************************
+ * platform specific code
+ */
+
+/* The default stack direction is downwards, 0, but platforms
+ * can redefine it to upwards growing, 1.
+ * Since we support both architectures with descending and
+ * ascending stacks, we use the terms "near" and "far"
+ * to describe stack boundaries.  In a typical architecture
+ * with descending stacks, "near" corresponds to a low
+ * address and "far" to a high address.
+ */
+#define STACK_DIRECTION 0   
+
+#include "slp_platformselect.h"
+
+#if STACK_DIRECTION == 0
+#define STACK_FAR_MAIN     ((char*) -1)     /* for stack_far */
+#define STACK_LE(a, b)      ((a) <= (b))    /* to compare stack position */
+#define STACK_SUB(a, b)     ((a) - (b))     /* to subtract stack pointers */
+#else
+#define STACK_FAR_MAIN     ((char*) 1)      /* for stack_far */
+#define STACK_LE(a, b)      ((b) <= (a))    /* to compare stack position */
+#define STACK_SUB(a, b)     ((b) - (a))     /* to subtract stack pointers */
+#endif
+
+/************************************************************/
+
+/* #define DEBUG_DUMP */
+
+#ifdef DEBUG_DUMP
+#include <stdio.h>
+#endif
+
+/************************************************************
+ * Structures for maintaining copies of the C stack.
+ */
+
+/* a chunk represents a single segment of saved stack */
+typedef struct tealet_chunk_t
+{
+    struct tealet_chunk_t *next;   /* additional chunks */
+    char *stack_near;              /* near stack address */
+    size_t size;                   /* amount of data saved */
+    char data[1];                  /* the data follows here */
+} tealet_chunk_t;
+
+/* The main stack structure, contains the initial chunk and a link to further
+ * segments.  Stacks can be shared by different tealets, hence the reference
+ * count.  They can also be linked into a list of partiallty unsaved
+ * stacks, that are saved only on demand.
+ */
+typedef struct tealet_stack_t
+{
+    int refcount;                   /* controls lifetime */
+    struct tealet_stack_t **prev;   /* previous 'next' pointer */
+    struct tealet_stack_t *next;	/* next unsaved stack */
+    char *stack_far;                /* the far boundary of this stack */
+    size_t saved;                   /* total amount of memory saved in all chunks */
+    struct tealet_chunk_t chunk;    /* the initial chunk */
+} tealet_stack_t;
+
+
+/* the actual tealet structure as used internally 
+ * The main tealet will have stack_far set to the end of memory.
+ * "stack" is zero for a running tealet, otherwise it points
+ * to the saved stack, or is -1 if the sate is invalid.
+ * In addition, stack_far is set to NULL value to indicate
+ * that a tealet is exiting.
+ */
+typedef struct tealet_sub_t {
+  tealet_t base;				   /* the public part of the tealet */
+  char *stack_far;                 /* the "far" end of the stack or NULL when exiting */
+  tealet_stack_t *stack;           /* saved stack or 0 if active or -1 if invalid*/
+#ifndef debug
+  int id;                          /* number of this tealet */
+#endif
+} tealet_sub_t;
+
+/* a structure incorporating extra data */
+typedef struct tealet_nonmain_t {
+  tealet_sub_t base;
+  double _extra[1];                /* start of any extra data */
+} tealet_nonmain_t;
+
+/* The main tealet has additional fields for housekeeping */
+typedef struct tealet_main_t {
+  tealet_sub_t base;
+  void         *g_user;     /* user data pointer for main */
+  tealet_sub_t *g_current;
+  tealet_sub_t *g_target;   /* Temporary store when switching */
+  void         *g_arg;      /* argument passed around when switching */
+  tealet_alloc_t g_alloc;   /* the allocation context used */
+  tealet_stack_t *g_prev;   /* previously active unsaved stacks */
+#ifndef NDEBUG
+  int g_tealets;            /* number of active tealets excluding main */
+  int g_counter;            /* total number of tealets */
+#endif
+  double _extra[1];         /* start of any extra data */
+} tealet_main_t;
+
+#define TEALET_IS_MAIN_STACK(t)  (((tealet_sub_t *)(t))->stack_far == STACK_FAR_MAIN)
+#define TEALET_GET_MAIN(t)     ((tealet_main_t *)(((tealet_t *)(t))->main))
+
+/************************************************************/
+
+int (*_tealet_switchstack)(tealet_main_t*);
+int (*_tealet_initialstub)(tealet_main_t*, tealet_run_t run, void*);
+
+/************************************************************
+ * helpers to call the malloc functions provided by the user
+ */
+static void *tealet_int_malloc(tealet_main_t *main, size_t size)
+{
+    return main->g_alloc.malloc_p(size, main->g_alloc.context);
+}
+static void tealet_int_free(tealet_main_t *main, void *ptr)
+{
+    main->g_alloc.free_p(ptr, main->g_alloc.context);
+}
+
+/*************************************************************
+ * actual stack management routines.  Copying, growing
+ * restoring, duplicating, deleting
+ */
+static tealet_stack_t *tealet_stack_new(tealet_main_t *main,
+    char *stack_near, char *stack_far, size_t size)
+{
+    size_t tsize;
+    tealet_stack_t *s;
+    
+    tsize = offsetof(tealet_stack_t, chunk.data[0]) + size;
+    s = (tealet_stack_t*)tealet_int_malloc(main, tsize);
+    if (!s)
+        return NULL;
+    s->refcount = 1;
+    s->prev = NULL;
+    s->stack_far = stack_far;
+    s->saved = size;
+
+    s->chunk.next = NULL;
+    s->chunk.stack_near = stack_near;
+    s->chunk.size = size;
+#if STACK_DIRECTION == 0
+    memcpy(&s->chunk.data[0], stack_near, size);
+#else
+    memcpy(&s->chunk.data[0], stack_near-size, size);
+#endif
+    return s;
+}
+
+static int tealet_stack_grow(tealet_main_t *main,
+    tealet_stack_t *stack, size_t size)
+{
+    tealet_chunk_t *chunk;
+    size_t tsize, diff;
+    assert(size > stack->saved);
+
+    diff = size - stack->saved;
+    tsize = offsetof(tealet_chunk_t, data[0]) + diff;
+    chunk = (tealet_chunk_t*)tealet_int_malloc(main, tsize);
+    if (!chunk)
+        return -1;
+#if STACK_DIRECTION == 0
+    chunk->stack_near = stack->chunk.stack_near + stack->saved;
+    memcpy(&chunk->data[0], chunk->stack_near, diff);
+#else
+    chunk->stack_near = stack->chunk.stack_near - stack->saved;
+    memcpy(&chunk->data[0], chunk->stack_near - diff, diff);
+#endif
+    chunk->size = diff;
+    chunk->next = stack->chunk.next;
+    stack->chunk.next = chunk;
+    stack->saved = size;
+    return 0;
+}
+
+static void tealet_stack_restore(tealet_stack_t *stack)
+{
+    tealet_chunk_t *chunk = &stack->chunk;
+    do {
+#if STACK_DIRECTION == 0
+        memcpy(chunk->stack_near, &chunk->data[0], chunk->size);
+#else
+        memcpy(chunk->stack_near - chunk->size, &chunk->data[0], chunk->size);
+#endif
+        chunk = chunk->next;
+    } while(chunk);
+}
+
+static tealet_stack_t *tealet_stack_dup(tealet_stack_t *stack)
+{
+    stack->refcount += 1;
+    return stack;
+}
+
+static void tealet_stack_link(tealet_stack_t *stack, tealet_stack_t **head)
+{
+    assert(stack->prev == NULL);
+    assert(*head != stack);
+    if (*head)
+        assert((*head)->prev == head);
+    stack->next = *head;
+    if (stack->next)
+        stack->next->prev = &stack->next;
+    stack->prev = head;
+    *head = stack;
+}
+
+static void tealet_stack_unlink(tealet_stack_t *stack)
+{
+    tealet_stack_t *next = stack->next;
+    assert(stack->prev);
+    assert(*stack->prev == stack);
+    if (next)
+        assert(next->prev == &stack->next);
+
+    if (next)
+        next->prev = stack->prev;
+    *stack->prev = next;
+    stack->prev = NULL;
+}
+
+static void tealet_stack_decref(tealet_main_t *main, tealet_stack_t *stack)
+{
+    tealet_chunk_t *chunk;
+    if (stack == NULL || --stack->refcount > 0)
+        return;
+    if (stack->prev)
+        tealet_stack_unlink(stack);
+ 
+    chunk = stack->chunk.next;
+    tealet_int_free(main, (void*)stack);
+    while(chunk) {
+        tealet_chunk_t *next = chunk->next;
+        tealet_int_free(main, (void*)chunk);
+        chunk = next;
+    }
+}
+
+static void tealet_stack_defunct(tealet_main_t *main, tealet_stack_t *stack)
+{
+    /* stack couldn't be grown.  Release any extra chunks and mark stack as defunct */
+    tealet_chunk_t *chunk;
+    chunk = stack->chunk.next;
+    stack->chunk.next = NULL;
+    stack->saved = (size_t)-1;
+    while(chunk) {
+        tealet_chunk_t *next = chunk->next;
+        tealet_int_free(main, (void*)chunk);
+        chunk = next;
+    }
+}
+
+
+/***************************************************************
+ * utility functions for allocating and growing stacks
+ */
+
+/* save a new stack, at least up to "saveto" */
+static tealet_stack_t *tealet_stack_saveto(tealet_main_t *main,
+    char *stack_near, char *stack_far, char *saveto, int *full)
+{
+    ptrdiff_t size;
+    if (STACK_LE(stack_far, saveto)) {
+        saveto = stack_far;
+        *full = 1;
+    } else
+        *full = 0;
+    assert(saveto != STACK_FAR_MAIN); /* can't save all of memory */
+    size = STACK_SUB(saveto, stack_near);
+    if (size < 0)
+        size = 0;
+    return tealet_stack_new(main, (char*) stack_near, stack_far, size);
+}
+
+static int tealet_stack_growto(tealet_main_t *main, tealet_stack_t *stack, char* saveto,
+    int *full, int fail_ok)
+{
+    /* Save more of g's stack into the heap -- at least up to 'saveto'
+
+       g->stack_stop |________|
+                     |        |
+                     |    __ stop       .........
+                     |        |    ==>  :       :
+                     |________|         :_______:
+                     |        |         |       |
+                     |        |         |       |
+      g->stack_start |        |         |_______| g->stack_copy
+
+     */
+    ptrdiff_t size, saved=(ptrdiff_t)stack->saved;
+    int fail;
+
+    /* We shouldn't be completely saved already */
+    if (stack->stack_far != STACK_FAR_MAIN)
+        assert(STACK_SUB(stack->stack_far, stack->chunk.stack_near) > saved);
+ 
+    /* truncate the "stop" */
+    if (STACK_LE(stack->stack_far, saveto)) {
+        saveto = stack->stack_far;
+        *full = 1;
+    } else
+        *full = 0;
+    
+    /* total saved size expected after this */
+    assert(saveto != STACK_FAR_MAIN); /* can't save them all */
+    size = STACK_SUB(saveto, stack->chunk.stack_near);
+    if (size <= saved)
+        return 0; /* nothing to do */
+    
+    fail = tealet_stack_grow(main, stack, size);
+    if (fail == 0)
+        return 0;
+
+    if (fail_ok)
+        return fail; /* caller can deal with failures */
+    /* we cannot fail.  Mark this stack as defunct and continue */
+    tealet_stack_defunct(main, stack);
+    *full = 1;
+    return 0;
+}
+
+/* Grow a list og stacks to a certain limit.  Unlink those that
+ * become fully saved.
+ */
+static int tealet_stack_grow_list(tealet_main_t *main, tealet_stack_t *list, 
+    char *saveto, tealet_stack_t *target, int fail_ok)
+{
+    while (list) {
+        int fail;
+        int full;
+        if (list == target) {
+            /* this is the stack we are switching to.  We should stop here 
+             * since previous stacks are already fully saved wrt. this.
+             * also, if this stack is not shared, it need not be saved
+             */
+            if (list->refcount > 1) {
+                /* saving because the target stack is shared.  If failure cannot
+                 * be handled, the target will be marked invalid on error. But
+                 * the caller of this function will have already checked that
+                 * and will complete the switch despite such a flag.  Only
+                 * subsequent uses of this stack will fail.
+                 */
+                fail = tealet_stack_growto(main, list, saveto, &full, fail_ok);
+                if (fail)
+                    return fail;
+                if (fail_ok)
+                    assert(full); /* we saved it entirely */
+            }
+            tealet_stack_unlink(list);
+            return 0;
+        }
+                
+        fail = tealet_stack_growto(main, list, saveto, &full, fail_ok);
+        if (fail)
+            return fail;
+        if (full)
+            tealet_stack_unlink(list);
+        list = list->next;
+    }
+    return 0;
+}
+
+/*********************************************************************
+ * the save and restore callbacks.  These implement all the stack
+ * save and restore logic using previously defined functions
+ */
+
+/* main->g_target contains the tealet we are switching to:
+ * target->stack_far is the limit to which we must save the old stack
+ * target->stack can be NULL, indicating that the target stack
+ * needs not be restored.
+ */
+static void *tealet_save_state(void *old_stack_pointer, void *main)
+{
+    /* must free all the C stack up to target->stack_stop */
+    tealet_main_t *g_main = (tealet_main_t *)main;
+    tealet_sub_t *g_target = g_main->g_target;
+    tealet_sub_t *g_current = g_main->g_current;
+    char* target_stop = g_target->stack_far;
+    int exiting, fail, fail_ok;
+    assert(target_stop != NULL); /* target is't exiting */
+    assert(g_current != g_target);
+    
+    exiting = g_current->stack_far == NULL;
+    fail_ok = !exiting;
+
+    /* save and unlink older stacks on demand */
+    /* when coming from main, there should be no list of unsaved stacks */
+    if (TEALET_IS_MAIN_STACK(g_main->g_current)) {
+        assert(!exiting);
+        assert(g_main->g_prev == NULL);
+    }
+    fail = tealet_stack_grow_list(g_main, g_main->g_prev, target_stop, g_target->stack, fail_ok);
+    if (fail)
+        return (void*) -1;
+    /* when returning to main, there should now be no list of unsaved stacks */
+    if (TEALET_IS_MAIN_STACK(g_main->g_target))
+        assert(g_main->g_prev == NULL);
+    
+    if (exiting) {
+        /* tealet is exiting. We don't save its stack. */
+        assert(!TEALET_IS_MAIN_STACK(g_current));
+        if (g_current->stack == NULL) {
+            /* auto-delete the tealet */
+#ifndef NDEBUG
+            g_main->g_tealets--;
+#endif
+            tealet_int_free(g_main, g_current);
+        } else {
+            /* -1 means do-not-delete */
+            assert(g_current->stack == (tealet_stack_t*)-1);
+            g_current->stack = NULL;
+        }
+    } else {
+        /* save the initial stack chunk */
+        int full;
+        tealet_stack_t *stack = tealet_stack_saveto(g_main, (char*) old_stack_pointer,
+            g_current->stack_far, target_stop, &full);
+        if (!stack) {
+            if (fail_ok)
+                return (void*) -1;
+            assert(!TEALET_IS_MAIN_STACK(g_current));
+            g_current->stack = (tealet_stack_t *)-1; /* signal invalid stack */
+        } else {
+            g_current->stack = stack;
+            /* if it is partially saved, link it in to previous stacks */
+            if (TEALET_IS_MAIN_STACK(g_current))
+                assert(!full); /* always link in the main tealet's stack */
+            if (!full)
+                tealet_stack_link(stack, &g_main->g_prev);
+        }
+    }
+
+    if (g_target->stack == NULL)
+        return (void *) 1; /* don't restore */
+
+    /* return the stack pointer, it was saved here */
+    return g_target->stack->chunk.stack_near;
+}
+
+static void *tealet_restore_state(void *new_stack_pointer, void *main)
+{
+    tealet_main_t *g_main = (tealet_main_t *)main;
+    tealet_sub_t *g = g_main->g_target;
+
+    /* Restore the heap copy back into the C stack */
+    assert(g->stack != NULL);
+    tealet_stack_restore(g->stack);
+    tealet_stack_decref(g_main, g->stack);
+    g->stack = NULL;
+    return NULL;
+}
+
+static int tealet_switchstack(tealet_main_t *g_main)
+{
+    /* note: we can't pass g_target simply as an argument here, because
+     of the mix between different call stacks: after slp_switch() it
+     might end up with a different value.  But g_main is safe, because
+     it should have always the same value before and after the switch. */
+    void *res;
+    assert(g_main->g_target);
+    assert(g_main->g_target != g_main->g_current);
+    /* if the target saved stack is invalid (due to a failure to save it
+    * during the exit of another tealet), we detect this here and
+    * report an error
+    * return value is:
+    *  0 = successful switch
+    *  1 = successful save only
+    * -1 = error, couldn't save state
+    * -2 = error, target tealet corrupt
+    */
+    if (g_main->g_target->stack == (tealet_stack_t*)-1)
+        return -2;
+    {
+        /* make sure that optimizers, e.g. gcc -O2, won't assume that
+         * g_main->g_target stays unchanged across the switch and optimize it
+         * into a register
+         */
+        tealet_sub_t * volatile *ptarget = &g_main->g_target;
+        res = slp_switch(tealet_save_state, tealet_restore_state, g_main);
+        g_main->g_target = *ptarget;
+    }
+    if ((int)res >= 0)
+        g_main->g_current = g_main->g_target;
+    g_main->g_target = NULL;
+    return (int)res;
+}
+
+/* We are initializing and switching to a new stub,
+ * in order to immediately start a new tealet's execution.
+ * stack_far is the far end of this stack and must be
+ * far enough that local variables in this function get saved.
+ * A stack variable in the calling function is sufficient.
+ */
+static int tealet_initialstub(tealet_main_t *g_main, tealet_run_t run, void *stack_far)
+{
+    int result;
+    tealet_sub_t *g = g_main->g_current;
+    tealet_sub_t *g_target = g_main->g_target;
+    assert(g_target->stack == NULL); /* it is fresh */
+    
+    assert(run);
+    g_target->stack_far = (char *)stack_far;
+    result = _tealet_switchstack(g_main);
+    if (result < 0) {
+        /* couldn't allocate stack */
+        g_main->g_current = g;
+        return result;
+    }
+    if (result == 1) {
+        /* We successfully saved the source state (our caller) and initialized
+         * the current target without restoring state. We are the new tealet.
+         */
+        g = g_main->g_current;
+        assert(g == g_target);
+        assert(g->stack == NULL);     /* running */      
+    
+        #ifdef DEBUG_DUMP
+        printf("starting %p\n", g);
+        #endif
+        g_target = (tealet_sub_t *)(run((tealet_t *)g, g_main->g_arg));
+        #ifdef DEBUG_DUMP
+        printf("ending %p -> %p\n", g, g_target);
+        #endif
+        if (tealet_exit((tealet_t*)g_target, NULL, TEALET_EXIT_DEFAULT))
+            tealet_exit((tealet_t*)g_main, NULL, TEALET_EXIT_DEFAULT); /* failsafe */
+        assert(!"This point should not be reached");
+    } else {
+        /* this is a switch back into the calling tealet */
+        assert(result == 0);
+    }
+    return 0;
+}
+
+static tealet_sub_t *tealet_alloc(tealet_main_t *g_main, tealet_alloc_t *alloc, size_t extrasize)
+{
+    tealet_sub_t *g;
+    size_t basesize = g_main == NULL ? offsetof(tealet_main_t, _extra) : offsetof(tealet_nonmain_t, _extra);
+    size_t size = basesize + extrasize;
+    if (g_main != NULL)
+        alloc = &g_main->g_alloc;
+    g = (tealet_sub_t*) alloc->malloc_p(size, alloc->context);
+    if (g == NULL)
+        return NULL;
+    if (g_main == NULL)
+        g_main = (tealet_main_t *)g;
+    g->base.main = (tealet_t *)g_main;
+    if (extrasize)
+        g->base.extra = (void*)((char*)g + basesize);
+    else
+        g->base.extra = NULL;
+    g->stack = NULL;
+    g->stack_far = NULL;
+#ifndef NDEBUG
+    g->id = g_main->g_counter++;
+#endif
+    return g;
+}
+
+
+/************************************************************/
+
+tealet_t *tealet_initialize(tealet_alloc_t *alloc, size_t extrasize)
+{
+    tealet_sub_t *g;
+    tealet_main_t *g_main;
+    g = tealet_alloc(NULL, alloc, extrasize);
+    if (g == NULL)
+        return NULL;
+    g_main = (tealet_main_t *)g;
+    g->stack = NULL;
+    g->stack_far = STACK_FAR_MAIN;
+    g_main->g_user = NULL;
+    g_main->g_current = g;
+    g_main->g_target = NULL;
+    g_main->g_arg = NULL;
+    g_main->g_alloc = *alloc;
+    g_main->g_prev =  NULL;
+#ifndef NDEBUG
+    g_main->g_tealets = 0;
+    g_main->g_counter = 0;
+#endif
+    assert(TEALET_IS_MAIN_STACK(g_main));
+    /* set up the following field with an indirection, which is needed
+     to prevent any inlining */
+    _tealet_initialstub = tealet_initialstub;
+    _tealet_switchstack = tealet_switchstack;
+    return (tealet_t *)g_main;
+}
+
+void tealet_finalize(tealet_t *tealet)
+{
+    tealet_main_t *g_main = TEALET_GET_MAIN(tealet);
+    assert(TEALET_IS_MAIN_STACK(g_main));
+    assert(g_main->g_current == (tealet_sub_t *)g_main);
+    tealet_int_free(g_main, g_main);
+}
+
+void *tealet_malloc(tealet_t *tealet, size_t s)
+{
+    tealet_main_t *g_main = TEALET_GET_MAIN(tealet);
+    return tealet_int_malloc(g_main, s);
+}
+
+void tealet_free(tealet_t *tealet, void *p)
+{
+    tealet_main_t *g_main = TEALET_GET_MAIN(tealet);
+    tealet_int_free(g_main, p);
+}
+
+tealet_t *tealet_new(tealet_t *tealet, tealet_run_t run, void **parg, size_t extrasize)
+{
+    tealet_sub_t *result; /* store this until we return */
+    int fail;
+    tealet_main_t *g_main = TEALET_GET_MAIN(tealet);
+    assert(TEALET_IS_MAIN_STACK(g_main));
+    assert(!g_main->g_target);
+    result = tealet_alloc(g_main, NULL, extrasize);
+    if (result == NULL)
+        return NULL; /* Could not allocate */
+    g_main->g_target = result;
+    g_main->g_arg = parg ? *parg : NULL;
+#ifndef NDEBUG
+    g_main->g_tealets ++;
+#endif
+    fail = _tealet_initialstub(g_main, run, (void*)&result);
+    if (fail) {
+        /* could not save stack */
+        tealet_int_free(g_main, result);
+        g_main->g_target = NULL;
+#ifndef NDEBUG
+        g_main->g_tealets --;
+#endif
+        return NULL;
+    }
+    if (parg)
+        *parg = g_main->g_arg;
+    return (tealet_t*)result;
+}
+
+int tealet_switch(tealet_t *stub, void **parg)
+{
+    tealet_sub_t *g_target = (tealet_sub_t *)stub;
+    tealet_main_t *g_main = TEALET_GET_MAIN(g_target);
+    int result;
+    if (g_target == g_main->g_current)
+        return 0; /* switch to self */
+#ifdef DEBUG_DUMP
+    printf("switch %p -> %p\n", g_main->g_current, g_target);
+#endif
+    g_main->g_target = g_target;
+    g_main->g_arg = parg ? *parg : NULL;
+    result = _tealet_switchstack(g_main);
+    if (parg)
+        *parg = g_main->g_arg;
+#ifdef DEBUG_DUMP
+    printf("done switch, res=%d, now in %p\n", result, g_main->g_current);
+#endif
+    return result;
+}
+ 
+int tealet_exit(tealet_t *target, void *arg, int flags)
+{
+    tealet_sub_t *g_target = (tealet_sub_t *)target;
+    tealet_main_t *g_main = TEALET_GET_MAIN(g_target);
+    tealet_sub_t *g_current = g_main->g_current;
+    char *stack_far = g_target->stack_far;
+    int result;
+    assert(g_current != (tealet_sub_t*)g_main); /* mustn't exit main */
+    if (g_target == g_current)
+        return -2; /* invalid tealet */
+
+    g_current->stack_far = NULL; /* signal exit */
+    assert (g_current->stack == NULL);
+    if (flags & TEALET_EXIT_NODELETE)
+        g_current->stack = (tealet_stack_t*) -1; /* signal do-not-delete */
+    g_main->g_target = g_target;
+    g_main->g_arg = arg;
+    result = _tealet_switchstack(g_main);
+    assert(result < 0); /* only return here if there was failure */
+    g_target->stack_far = stack_far;
+    g_current->stack = NULL;
+    return result;
+}
+
+tealet_t *tealet_duplicate(tealet_t *tealet, size_t extrasize)
+{
+    tealet_sub_t *g_tealet = (tealet_sub_t *)tealet;
+    tealet_main_t *g_main = TEALET_GET_MAIN(g_tealet);
+    tealet_sub_t *g_copy;
+    /* can't dup the current or the main tealet */
+    assert(g_tealet != g_main->g_current && g_tealet != (tealet_sub_t*)g_main);
+    g_copy = tealet_alloc(g_main, NULL, extrasize);
+    if (g_copy == NULL)
+        return NULL;
+#ifndef NDEBUG
+    g_main->g_tealets++;
+#endif
+    /* copy the relevant bits.  extra data is not copied since we don't
+     * know how large it was in the source
+     */
+    g_copy->stack_far = g_tealet->stack_far;
+    g_copy->stack = tealet_stack_dup(g_tealet->stack);
+    return (tealet_t*)g_copy;
+}
+
+void tealet_delete(tealet_t *target)
+{
+    tealet_sub_t *g_target = (tealet_sub_t *)target;
+    tealet_main_t *g_main = TEALET_GET_MAIN(g_target);
+    assert(!TEALET_IS_MAIN(target));
+    tealet_stack_decref(g_main, g_target->stack);
+    tealet_int_free(g_main, g_target);
+#ifndef NDEBUG
+    g_main->g_tealets--;
+#endif
+}
+
+tealet_t *tealet_current(tealet_t *tealet)
+{
+    tealet_main_t *g_main = TEALET_GET_MAIN(tealet);
+    return (tealet_t *)g_main->g_current;
+}
+
+void **tealet_main_userpointer(tealet_t *tealet)
+{
+   tealet_main_t *g_main = TEALET_GET_MAIN(tealet);
+   return &g_main->g_user;
+}
+
+int tealet_status(tealet_t *_tealet)
+{
+    tealet_sub_t *tealet = (tealet_sub_t *)_tealet;
+    if (tealet->stack_far == NULL)
+        return TEALET_STATUS_EXITED;
+    if (tealet->stack == (tealet_stack_t*)-1)
+        return TEALET_STATUS_DEFUNCT;
+    return TEALET_STATUS_ACTIVE;
+}
+
+#ifndef NDEBUG
+int tealet_get_count(tealet_t *tealet)
+{
+    return TEALET_GET_MAIN(tealet)->g_tealets;
+}
+#endif
+
+ptrdiff_t tealet_stack_diff(void *a, void *b)
+{
+    return STACK_SUB((ptrdiff_t)a, (ptrdiff_t)(b));
+}
+
+void *tealet_get_far(tealet_t *_tealet)
+{
+    tealet_sub_t *tealet = (tealet_sub_t *)_tealet;
+    return tealet->stack_far;
+}
+
+void *tealet_new_far(tealet_t *d1, tealet_run_t d2, void **d3, size_t d4)
+{
+    tealet_sub_t *result;
+    void *r;
+    (void)d1;
+    (void)d2;
+    (void)d3;
+    (void)d4;
+    /* avoid compiler warnings about returning tmp addr */
+    r = (void*)&result;
+    return r;
+}
diff --git a/Stackless/tealet/tealet.h b/Stackless/tealet/tealet.h
new file mode 100644
index 00000000000000..beeebcfec3d411
--- /dev/null
+++ b/Stackless/tealet/tealet.h
@@ -0,0 +1,227 @@
+/********** A minimal coroutine package for C **********/
+#ifndef _TEALET_H_
+#define _TEALET_H_
+
+#include <stddef.h>
+
+#ifdef WIN32
+#if defined TEALET_EXPORTS
+#define TEALET_API __declspec(dllexport)
+#elif defined TEALET_IMPORTS
+#define TEALET_API __declspec(dllimport)
+#else
+#define TEALET_API
+#endif
+#else /* win32 */
+#define TEALET_API
+#endif
+
+
+/* A structure to define the memory allocation api used.
+ * the functions have C89 semantics and take an additional "context"
+ * pointer that they can use as they please
+ */
+typedef void*(*tealet_malloc_t)(size_t size, void *context);
+typedef void*(*tealet_free_t)(void *ptr, void *context);
+typedef struct tealet_alloc_t {
+  tealet_malloc_t malloc_p;
+  tealet_free_t free_p;
+  void *context;
+} tealet_alloc_t;
+
+/* use the following macro to initialize a tealet_alloc_t
+ * structure with stdlib malloc functions, for convenience, e.g.:
+ * tealet_alloc_t stdalloc = TEALET_MALLOC;
+ */
+#define TEALET_MALLOC {\
+    (tealet_malloc_t)&malloc, \
+    (tealet_free_t)&free, \
+    0 \
+}
+
+
+/* The user-visible tealet structure.  If an "extrasize" is provided when
+ * the tealet is created, "extra" points to a block of that size, otherwise
+ * it is initialized to NULL
+ */
+typedef struct tealet_t {
+  struct tealet_t *main;   /* pointer to the main tealet */
+  void *extra;
+  /* private fields follow */
+} tealet_t;
+
+/* The "run" function of a tealet.  It is called with the
+ * current tealet and the argument provided to its start function 
+ */
+typedef tealet_t *(*tealet_run_t)(tealet_t *current, void *arg);
+
+
+/* error codes.  API functions that return int return a negative value
+ * to signal an error.
+ * Those that return tealet_t pointers return NULL to signal a memory
+ * error.
+ */
+#define TEALET_ERR_MEM -1       /* memory allocation failed */
+#define TEALET_ERR_DEFUNCT -2   /* the target tealet is corrupt */
+
+
+/* Initialize and return the main tealet.  The main tealet contains the whole
+ * "normal" execution of the program; it starts when the program starts and
+ * ends when the program ends.  This function and tealet_finalize() should
+ * be called together from the same (main) function which calls the rest of
+ * the program.  It is fine to nest several uses of initialize/finalize,
+ * or to call them in multiple threads in case of multithreaded programs,
+ * as long as you don't try to switch between tealets created with a
+ * different main tealet.
+ */
+TEALET_API
+tealet_t *tealet_initialize(tealet_alloc_t *alloc, size_t extrasize);
+
+/* Tear down the main tealet.  Call e.g. after a thread finishes (including
+ * all its tealets).
+ */
+TEALET_API
+void tealet_finalize(tealet_t *tealet);
+
+/* access to the tealet's allocator.  This can be useful to use
+ * e.g. when passing data between tealets but such data cannot
+ * reside on the stack (except during the initial call to tealet_new)
+ */
+TEALET_API
+void *tealet_malloc(tealet_t *tealet, size_t s);
+TEALET_API
+void tealet_free(tealet_t *tealet, void *p);
+
+/* Allocate a new tealet 'g', and call 'run(g, *arg)' in it.
+ * The return value of run() must be the next tealet in which to continue
+ * execution, which must be a different one, like for example the main tealet.
+ * When 'run(g)' returns, the tealet 'g' is freed.
+ * The return value is the new tealet, or NULL if memory allocation failed.
+ * Note that this tealet may have been alread freed should run(g) have
+ * returned by the time this function returns.
+ * On return, *arg contains the arg value passed in to the switch
+ * causing this return.
+ * 'arg' can be NULL, in which case NULL is passed to run and no result
+ * argument is passed.
+ * If 'extrasize' is non-zero, extra data will be allocated and the tealet's
+ * 'extra' member points to it, otherwise it is set to NULL
+ */
+TEALET_API
+tealet_t *tealet_new(tealet_t *tealet, tealet_run_t run, void **parg, size_t extrasize);
+
+/* Switch to another tealet.  Execution continues there.  The tealet
+ * passed in must not have been freed yet and must descend from
+ * the same main tealet as the current one.  In multithreaded applications,
+ * it must also belong to the current thread (otherwise, segfaults).
+ * if 'arg' is non-NULL, the argument passed in *arg will be provided
+ * to the other tealet when it returns from its tealet_new() or 
+ * tealet_switch().
+ * On return, *arg contains whatever *arg was
+ * provided when switching back here.
+ * Take care to not have *arg point to stack allocated data because
+ * such data may be overwritten when the context switches.
+ */
+TEALET_API
+int tealet_switch(tealet_t *target, void **parg);
+
+/* Exit the current tealet.  Similar to tealet_switch except that it only
+ * ever returns if the target tealet is defunct.
+ * It also allows passing of an *arg to the target tealet, plus allows
+ * control over whether the tealet is automatically deleted or not.
+ * Returning with 'p' from the tealet's run funciton is equivalent to calling
+ * tealet_exit(p, NULL, 1).
+ * This function can be used as an emergency measure to return to the
+ * main tealet if tealet_switch() fails due to inability to save the stack.
+ * Note that exiting to the main tealet is always guaranteed to work.
+ */
+#define TEALET_EXIT_DEFAULT 0
+#define TEALET_EXIT_NODELETE 1
+TEALET_API
+int tealet_exit(tealet_t *target, void *arg, int flags);
+
+/* Duplicate a tealet. The active tealet is duplicated
+ * along with its stack contents.
+ * This can be used, for example, to create "stubs" that can be duplicated
+ * and re-used to run with different arguments.
+ * Use this with care, because initially the duplicate will share the same
+ * stack data as the original.  This includes any local variables, even the
+ * "current" argument passed to the original "run" function which may
+ * be obsolete by the time the duplicate is run.  Use the argument passing
+ * mechanism to provide the copy with fresh data.
+ */
+TEALET_API
+tealet_t *tealet_duplicate(tealet_t *tealet, size_t extrasize);
+
+/* Deallocate a tealet.  Use this to delete a tealet that has exited
+ * with tealet_exit() with 'TEALET_EXIT_NODELETE', or defunct tealets.
+ * Active tealet can also be
+ * deleted, such as stubs that are no longer in use, but take care
+ * because any local resources in such tealets won't be freed.
+ */
+TEALET_API
+void tealet_delete(tealet_t *target);
+
+/* Return the current tealet, i.e. the one in which the caller of this
+ * function currently is.  "tealet" can be any tealet derived from the
+ * main tealet.
+ */
+TEALET_API
+tealet_t *tealet_current(tealet_t *tealet);
+
+/* Get the address of a the tealet's main user pointer, a single
+ * void pointer associated with the main tealet.  Use this to
+ * associate a (void*)value with the main tealet.
+ */
+TEALET_API
+void **tealet_main_userpointer(tealet_t *tealet);
+
+/* functions for stack arithmetic.  Useful when deciding
+ * if you want to start a newa tealet, or when doing stack
+ * spilling
+ */
+
+/* subtract two stack positions, taking into account if the
+ * local stack grows up or down in memory.
+ * The result is positive if 'b' is 'deeper' on the stack
+ * than 'a'
+ */
+TEALET_API
+ptrdiff_t tealet_stack_diff(void *a, void *b);
+
+/* Get a tealet's "far" position on the stack.  This is an
+ * indicator of its creation position on the stack.  The main
+ * tealet extends until the beginning of stack
+ */
+TEALET_API
+void *tealet_get_far(tealet_t *_tealet);
+
+/* this is used to get the "far address _if_ a tealet were initialized here
+ * The arguments must match the real tealet_new() but are dummies.
+ */
+TEALET_API
+void *tealet_new_far(tealet_t *dummy1, tealet_run_t dummy2, void **dummy3, size_t dummy4);
+
+/* get a tealet's status */
+#define TEALET_STATUS_ACTIVE 0
+#define TEALET_STATUS_EXITED 1
+#define TEALET_STATUS_DEFUNCT -2
+TEALET_API
+int tealet_status(tealet_t *tealet);
+
+#ifndef NDEBUG
+TEALET_API
+int tealet_get_count(tealet_t *t);
+#endif
+
+/* Convenience macros */
+#define TEALET_MAIN(t) ((t)->main)
+#define TEALET_IS_MAIN(t)  ((t) == TEALET_MAIN(t))
+#define TEALET_CURRENT_IS_MAIN(t) (tealet_current(t) == TEALET_MAIN(t))
+
+/* see if two tealets share the same MAIN, and can therefore be switched between */
+#define TEALET_RELATED(t1, t2) (TEALET_MAIN(t1) == TEALET_MAIN(t2))
+
+/* convenience access to a typecast extra pointer */
+#define TEALET_EXTRA(t, tp) ((tp*)((t)->extra))
+
+#endif /* _TEALET_H_ */
diff --git a/Stackless/tealet/tealet.sln b/Stackless/tealet/tealet.sln
new file mode 100644
index 00000000000000..7958176dfa8edd
--- /dev/null
+++ b/Stackless/tealet/tealet.sln
@@ -0,0 +1,36 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tealet", "tealet.vcxproj", "{4D8AC602-C828-4EDC-B65A-9A439810F157}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{E03E9A66-978B-43DE-82D6-FE0F6367368F}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|Win32.Build.0 = Debug|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|x64.ActiveCfg = Debug|x64
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|x64.Build.0 = Debug|x64
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|Win32.ActiveCfg = Release|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|Win32.Build.0 = Release|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|x64.ActiveCfg = Release|x64
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|x64.Build.0 = Release|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|Win32.Build.0 = Debug|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|x64.ActiveCfg = Debug|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|x64.Build.0 = Debug|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|Win32.ActiveCfg = Release|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|Win32.Build.0 = Release|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|x64.ActiveCfg = Release|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Stackless/tealet/tealet.vcproj b/Stackless/tealet/tealet.vcproj
new file mode 100644
index 00000000000000..c2dca5bb195ba2
--- /dev/null
+++ b/Stackless/tealet/tealet.vcproj
@@ -0,0 +1,454 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="tealet"
+	ProjectGUID="{4D8AC602-C828-4EDC-B65A-9A439810F157}"
+	RootNamespace="tealet"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				IgnoreAllDefaultLibraries="false"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\tealet.c"
+				>
+			</File>
+			<File
+				RelativePath=".\tealet.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="platform"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\slp_platformselect.h"
+				>
+			</File>
+			<File
+				RelativePath=".\switch_x64_msvc.asm"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Assembling"
+						CommandLine="ml64 /nologo /c /Zi /Fo &quot;$(IntDir)\$(InputName) .obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\$(InputName) .obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Assembling"
+						CommandLine="ml64 /nologo /c /Zi /Fo &quot;$(IntDir)\$(InputName) .obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\$(InputName) .obj"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\switch_x64_msvc.h"
+				>
+			</File>
+			<File
+				RelativePath=".\switch_x86_msvc.asm"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Assembling"
+						CommandLine="ml -c -Zi &quot;-Fl$(IntDir)\$(InputName).lst&quot; &quot;-Fo$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\$(InputName).obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="ml -c -Zi &quot;-Fl$(IntDir)\$(InputName).lst&quot; &quot;-Fo$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\$(InputName).obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Assembling"
+						CommandLine="ml -c -Zi &quot;-Fl$(IntDir)\$(InputName).lst&quot; &quot;-Fo$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\$(InputName).obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\switch_x86_msvc.h"
+				>
+			</File>
+			<Filter
+				Name="other platforms"
+				>
+				<File
+					RelativePath=".\switch_x86_64_gcc.h"
+					>
+				</File>
+				<File
+					RelativePath=".\switch_x86_gcc.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/Stackless/tealet/tealet.vcxproj b/Stackless/tealet/tealet.vcxproj
new file mode 100644
index 00000000000000..9be8abf16525d3
--- /dev/null
+++ b/Stackless/tealet/tealet.vcxproj
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{4D8AC602-C828-4EDC-B65A-9A439810F157}</ProjectGuid>
+    <RootNamespace>tealet</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TEALET_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="tealet.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="platf_slp\slp_fallback.h" />
+    <ClInclude Include="tealet.h" />
+    <ClInclude Include="slp_platformselect.h" />
+    <ClInclude Include="switch_x64_msvc.h" />
+    <ClInclude Include="switch_x86_msvc.h" />
+    <ClInclude Include="switch_x86_64_gcc.h" />
+    <ClInclude Include="switch_x86_gcc.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="switch_x64_msvc.asm">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Assembling</Message>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64 /nologo /c /Zi /Fo "$(IntDir)%(Filename) .obj" "%(FullPath)"
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename) .obj;%(Outputs)</Outputs>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Assembling</Message>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64 /nologo /c /Zi /Fo "$(IntDir)%(Filename) .obj" "%(FullPath)"
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename) .obj;%(Outputs)</Outputs>
+    </CustomBuild>
+    <CustomBuild Include="switch_x86_msvc.asm">
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Assembling</Message>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml -c -Zi "-Fl$(IntDir)%(Filename).lst" "-Fo$(IntDir)%(Filename).obj" "%(FullPath)"
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml -c -Zi "-Fl$(IntDir)%(Filename).lst" "-Fo$(IntDir)%(Filename).obj" "%(FullPath)"
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Assembling</Message>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml -c -Zi "-Fl$(IntDir)%(Filename).lst" "-Fo$(IntDir)%(Filename).obj" "%(FullPath)"
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Stackless/tealet/tealetvs2008.sln b/Stackless/tealet/tealetvs2008.sln
new file mode 100644
index 00000000000000..eb422edf285782
--- /dev/null
+++ b/Stackless/tealet/tealetvs2008.sln
@@ -0,0 +1,39 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tealet", "tealet.vcproj", "{4D8AC602-C828-4EDC-B65A-9A439810F157}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{E03E9A66-978B-43DE-82D6-FE0F6367368F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{4D8AC602-C828-4EDC-B65A-9A439810F157} = {4D8AC602-C828-4EDC-B65A-9A439810F157}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|Win32.Build.0 = Debug|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|x64.ActiveCfg = Debug|x64
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Debug|x64.Build.0 = Debug|x64
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|Win32.ActiveCfg = Release|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|Win32.Build.0 = Release|Win32
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|x64.ActiveCfg = Release|x64
+		{4D8AC602-C828-4EDC-B65A-9A439810F157}.Release|x64.Build.0 = Release|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|Win32.Build.0 = Debug|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|x64.ActiveCfg = Debug|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Debug|x64.Build.0 = Debug|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|Win32.ActiveCfg = Release|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|Win32.Build.0 = Release|Win32
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|x64.ActiveCfg = Release|x64
+		{E03E9A66-978B-43DE-82D6-FE0F6367368F}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Stackless/tealet/test.vcproj b/Stackless/tealet/test.vcproj
new file mode 100644
index 00000000000000..3cf8e75d77f51c
--- /dev/null
+++ b/Stackless/tealet/test.vcproj
@@ -0,0 +1,358 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="test"
+	ProjectGUID="{E03E9A66-978B-43DE-82D6-FE0F6367368F}"
+	RootNamespace="test"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+		<DefaultToolFile
+			FileName="masm.rules"
+		/>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="MASM"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;TEALET_IMPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="MASM"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;TEALET_IMPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="MASM"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="MASM"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\tests.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/Stackless/tealet/test.vcxproj b/Stackless/tealet/test.vcxproj
new file mode 100644
index 00000000000000..95aedadedaa844
--- /dev/null
+++ b/Stackless/tealet/test.vcxproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{E03E9A66-978B-43DE-82D6-FE0F6367368F}</ProjectGuid>
+    <RootNamespace>test</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;TEALET_IMPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;TEALET_IMPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="tests.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="tealet.vcxproj">
+      <Project>{4d8ac602-c828-4edc-b65a-9a439810f157}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Stackless/tealet/tests.c b/Stackless/tealet/tests.c
new file mode 100644
index 00000000000000..ff9c51774e8160
--- /dev/null
+++ b/Stackless/tealet/tests.c
@@ -0,0 +1,621 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "tealet.h"
+
+static int status = 0;
+static tealet_t *g_main = NULL;
+static tealet_t *the_stub = NULL;
+static int newmode = 0;
+
+
+static tealet_alloc_t talloc = TEALET_MALLOC;
+void init_test() {
+    assert(g_main == NULL);
+    g_main = tealet_initialize(&talloc);
+    assert(tealet_current(g_main) == g_main);
+    status = 0;
+}
+void fini_test() {
+    assert(g_main != NULL);
+    assert(tealet_current(g_main) == g_main);
+    if (the_stub)
+        tealet_delete(the_stub);
+    the_stub = NULL;
+#ifndef NDEBUG
+    assert(tealet_get_count(g_main) == 0);
+#endif
+    tealet_finalize(g_main);
+    g_main = NULL;
+}
+
+/****************************************************************
+ *Implement copyable stubs by using a trampoline
+ */
+struct mystub_arg
+{
+    tealet_t *current;
+    tealet_run_t run;
+    void *runarg;
+};
+static tealet_t *mystub_main(tealet_t *current, void *arg)
+{
+    void *myarg = 0;
+    /* the caller is in arg, return right back to him */
+    tealet_switch((tealet_t*)arg, &myarg);
+    /* now we are back, myarg should contain the arg to the run function.
+     * We were possibly duplicated, so can't trust the original function args.
+     */
+    {
+        struct mystub_arg sarg = *(struct mystub_arg*)myarg;
+        tealet_free(sarg.current, myarg);
+        return (sarg.run)(sarg.current, sarg.runarg);
+    }
+}
+
+/* create a stub and return it */
+tealet_t *mystub_new(tealet_t *t) {
+    void *arg = (void*)tealet_current(t);
+    return tealet_new(t, mystub_main, &arg);
+}
+
+/* run a stub */
+int mystub_run(tealet_t *stub, tealet_run_t run, void **parg)
+{
+    int result;
+    void *myarg;
+    /* we cannot pass arguments to a different tealet on the stack */
+    struct mystub_arg *psarg = (struct mystub_arg*)tealet_malloc(stub, sizeof(struct mystub_arg));
+    if (!psarg)
+        return TEALET_ERR_MEM;
+    psarg->current = stub;
+    psarg->run = run;
+    psarg->runarg = parg ? *parg : NULL;
+    myarg = (void*)psarg;
+    result = tealet_switch(stub, &myarg);
+    if (result) {
+        /* failure */
+        tealet_free(stub, psarg);
+        return result;
+    }
+    /* pass back the arg value from the switch */
+    if (parg)
+        *parg = myarg;
+    return 0;
+}
+
+
+
+/**************************************/
+
+/* create a tealet or stub low on the stack */
+static tealet_t * tealet_new_descend(tealet_t *t, int level, tealet_run_t run, void **parg)
+{
+    int boo[10];
+    boo[9] = 0;
+    if (level > 0)
+        return tealet_new_descend(t, level-1, run, parg);
+    if (run)
+        return tealet_new(t, run, parg);
+    else
+        return mystub_new(t);
+}
+
+/***************************************
+ * methods for creating tealets in different ways
+ */
+
+static tealet_t * tealet_new_rnd(tealet_t* t, tealet_run_t run, void **parg)
+{
+       return tealet_new_descend(t, rand() % 20, run, parg);
+}
+
+static tealet_t * stub_new(tealet_t *t, tealet_run_t run, void **parg)
+{
+    tealet_t *stub = tealet_new_descend(t, rand() % 20, NULL, NULL);
+    int res;
+    if (stub == NULL)
+        return NULL;
+    if (run)
+        res = mystub_run(stub, run, parg);
+    else
+        res = 0;
+    if (res) {
+        tealet_delete(stub);
+        assert(res == TEALET_ERR_MEM);
+        return NULL;
+    }
+    return stub;
+}
+
+static tealet_t * stub_new2(tealet_t *t, tealet_run_t run, void **parg)
+{
+    tealet_t *dup, *stub;
+    int res;
+    stub = tealet_new_descend(t, rand() % 20, NULL, NULL);
+    if (stub == NULL)
+        return NULL;
+    dup = tealet_duplicate(stub);
+    if (stub == NULL) {
+        tealet_delete(stub);
+        return NULL;
+    }
+    if (run)
+        res = mystub_run(dup, run, parg);
+    else
+        res = 0;
+    tealet_delete(stub);
+    if (res) {
+        tealet_delete(dup);
+        assert(res == TEALET_ERR_MEM);
+        return NULL;
+    }
+    return dup;
+}
+
+static tealet_t * stub_new3(tealet_t *t, tealet_run_t run, void **parg)
+{
+    tealet_t *dup;
+    int res;
+    if ((rand()%10) == 0)
+        if (the_stub != NULL) {
+            tealet_delete(the_stub);
+            the_stub = NULL;
+        }
+    if (the_stub == NULL)
+        the_stub = tealet_new_descend(t, rand() % 20, NULL, NULL);
+    if (the_stub == NULL)
+        return NULL;
+    dup = tealet_duplicate(the_stub);
+    if (dup == NULL)
+        return NULL;
+    if (run) {
+        res = mystub_run(dup, run, parg);
+        if (res) {
+            tealet_delete(dup);
+            assert(res == TEALET_ERR_MEM);
+            return NULL;
+        }
+    }
+    return dup;
+}
+    
+
+typedef tealet_t* (*t_new)(tealet_t *, tealet_run_t, void**);
+static t_new newarray[] = {tealet_new_rnd, stub_new, stub_new2, stub_new3};
+
+static t_new get_new(){
+    if (newmode >= 0)
+        return newarray[newmode];
+    return newarray[rand() % (sizeof(newarray)/sizeof(*newarray))];
+}
+#define tealet_new get_new()
+
+/************************************************************/
+
+void test_main_current(void)
+{
+  init_test();
+  fini_test();
+}
+
+/************************************************************/
+
+tealet_t *test_simple_run(tealet_t *t1, void *arg)
+{
+  assert(t1 != g_main);
+  status = 1;
+  return g_main;
+}
+
+void test_simple(void)
+{
+  init_test();
+  tealet_new(g_main, test_simple_run, NULL);
+  assert(status == 1);
+  fini_test();
+}
+
+/*************************************************************/
+
+tealet_t *test_status_run(tealet_t *t1, void *arg)
+{
+  assert(t1 == tealet_current(t1));
+  assert(!TEALET_IS_MAIN(t1));
+  assert(tealet_status(t1) == TEALET_STATUS_ACTIVE);
+  return g_main;
+}
+
+void test_status(void)
+{
+  tealet_t *stub1;
+  init_test();
+
+  assert(tealet_status(g_main) == TEALET_STATUS_ACTIVE);
+  assert(TEALET_IS_MAIN(g_main));
+
+  stub1 = tealet_new(g_main, NULL, NULL);
+  assert(tealet_status(stub1) == TEALET_STATUS_ACTIVE);
+  assert(!TEALET_IS_MAIN(stub1));
+  mystub_run(stub1, test_status_run, NULL);
+
+  fini_test();
+}
+
+
+/*************************************************************/
+tealet_t *test_exit_run(tealet_t *t1, void *arg)
+{
+  int result;
+  assert(t1 != g_main);
+  status += 1;
+  result = tealet_exit(g_main, NULL, (int)arg);
+  assert(0);
+  return (tealet_t*)-1;
+}
+
+void test_exit(void)
+{
+  tealet_t *stub1, *stub2;
+  int result;
+  void *arg;
+  init_test();
+  stub1 = tealet_new(g_main, NULL, NULL);
+  stub2 = tealet_duplicate(stub1);
+  arg = (void*)TEALET_EXIT_NODELETE;
+  result = mystub_run(stub1, test_exit_run, &arg);
+  assert(result == 0);
+  assert(status == 1);
+  assert(tealet_status(stub1) == TEALET_STATUS_EXITED);
+  tealet_delete(stub1);
+  arg = (void*)TEALET_EXIT_DEFAULT;
+  result = mystub_run(stub2, test_exit_run, &arg);
+  assert(status == 2);
+  fini_test();
+}
+
+
+/************************************************************/
+
+static tealet_t *glob_t1;
+static tealet_t *glob_t2;
+
+tealet_t *test_switch_2(tealet_t *t2, void *arg)
+{
+  assert(t2 != g_main);
+  assert(t2 != glob_t1);
+  glob_t2 = t2;
+  assert(status == 1);
+  status = 2;
+  assert(tealet_current(g_main) == t2);
+  tealet_switch(glob_t1, NULL);
+  assert(status == 3);
+  status = 4;
+  assert(tealet_current(g_main) == t2);
+  tealet_switch(glob_t1, NULL);
+  assert(status == 5);
+  status = 6;
+  assert(t2 == glob_t2);
+  assert(tealet_current(g_main) == t2);
+  tealet_switch(t2, NULL);
+  assert(status == 6);
+  status = 7;
+  assert(tealet_current(g_main) == t2);
+  return g_main;
+}
+
+tealet_t *test_switch_1(tealet_t *t1, void *arg)
+{
+  assert(t1 != g_main);
+  glob_t1 = t1;
+  assert(status == 0);
+  status = 1;
+  assert(tealet_current(g_main) == t1);
+  tealet_new(g_main, test_switch_2, NULL);
+  assert(status == 2);
+  status = 3;
+  assert(tealet_current(g_main) == t1);
+  tealet_switch(glob_t2, NULL);
+  assert(status == 4);
+  status = 5;
+  assert(tealet_current(g_main) == t1);
+  return glob_t2;
+}
+
+void test_switch(void)
+{
+  init_test();
+  tealet_new(g_main, test_switch_1, NULL);
+  assert(status == 7);
+  fini_test();
+}
+
+/************************************************************/
+
+/* 1 is high on the stack.  We then create 2 lower on the stack */
+/* the execution is : m 1 m 2 1 m 2 m */
+tealet_t *test_switch_new_1(tealet_t *t1, void *arg)
+{
+    tealet_t *caller = (tealet_t*)arg;
+    tealet_t *stub;
+    /* switch back to the creator */
+    tealet_switch(caller, NULL);
+    /* now we want to trample the stack */
+    stub = tealet_new_descend(t1, 50, NULL, NULL);
+    tealet_delete(stub);
+    /* and back to main */
+    return g_main;
+}
+
+tealet_t *test_switch_new_2(tealet_t *t2, void *arg) {
+    tealet_t *target = (tealet_t*)arg;
+    /* switch to tealet 1 to trample the stack*/
+    target->data = (void*)t2;
+    tealet_switch(target, NULL);
+   
+    /* and then return to main */
+    return g_main;
+}
+    
+void test_switch_new(void)
+{
+  tealet_t *tealet1, *tealet2;
+  void *arg;
+  init_test();
+  arg = (void *)tealet_current(g_main);
+  tealet1 = tealet_new(g_main, test_switch_new_1, &arg);
+  /* the tealet is now running */
+  arg = (void*)tealet1;
+  tealet2 = tealet_new_descend(g_main, 4, test_switch_new_2, &arg);
+  assert(tealet_status(tealet2) == TEALET_STATUS_ACTIVE);
+  tealet_switch(tealet2, NULL);
+  /* tealet should be dead now */
+  fini_test();
+}
+
+/************************************************************/
+
+/* test argument passing with switch and exit */
+tealet_t *test_arg_1(tealet_t *t1, void *arg)
+{
+  void *myarg;
+  tealet_t *peer = (tealet_t*)arg;
+  myarg = (void*)1;
+  tealet_switch(peer, &myarg);
+  assert(myarg == (void*)2);
+  myarg = (void*)3;
+  tealet_exit(peer, myarg, TEALET_EXIT_DEFAULT);
+  return NULL;
+}
+
+void test_arg(void)
+{
+  void *myarg;
+  tealet_t *t1;
+  init_test();
+  myarg = (void*)g_main;
+  t1 = tealet_new(g_main, test_arg_1, &myarg);
+  assert(myarg == (void*)1);
+  myarg = (void*)2;
+  tealet_switch(t1, &myarg);
+  assert(myarg == (void*)3);
+  fini_test();
+}
+
+/************************************************************/
+
+#define ARRAYSIZE  127
+#define MAX_STATUS 50000
+
+static tealet_t *tealetarray[ARRAYSIZE] = {NULL};
+static int got_index;
+
+tealet_t *random_new_tealet(tealet_t*, void *arg);
+
+static void random_run(int index)
+{
+  int i, prevstatus;
+  void *arg;
+  tealet_t *cur = tealet_current(g_main);
+  assert(tealetarray[index] == cur);
+  do
+    {
+      i = rand() % (ARRAYSIZE + 1);
+      status += 1;
+      if (i == ARRAYSIZE)
+        break;
+      prevstatus = status;
+      got_index = i;
+      if (tealetarray[i] == NULL)
+        {
+          if (status >= MAX_STATUS)
+            break;
+          arg = (void*)i;
+          tealet_new(g_main, random_new_tealet, &arg);
+        }
+      else
+        {
+          tealet_switch(tealetarray[i], NULL);
+        }
+      assert(status >= prevstatus);
+      assert(tealet_current(g_main) == cur);
+      assert(tealetarray[index] == cur);
+      assert(got_index == index);
+    }
+  while (status < MAX_STATUS);
+}
+
+tealet_t *random_new_tealet(tealet_t* cur, void *arg)
+{
+  int i = got_index;
+  assert(tealet_current(g_main) == cur);
+  assert(i == (int)(arg));
+  assert(i > 0 && i < ARRAYSIZE);
+  assert(tealetarray[i] == NULL);
+  tealetarray[i] = cur;
+  random_run(i);
+  tealetarray[i] = NULL;
+
+  i = rand() % ARRAYSIZE;
+  if (tealetarray[i] == NULL)
+    {
+      assert(tealetarray[0] != NULL);
+      i = 0;
+    }
+  got_index = i;
+  return tealetarray[i];
+}
+
+void test_random(void)
+{
+  int i;
+  init_test();
+  for( i=0; i<ARRAYSIZE; i++)
+      tealetarray[i] = NULL;
+  tealetarray[0] = g_main;
+  status = 0;
+  while (status < MAX_STATUS)
+    random_run(0);
+
+  assert(g_main == tealetarray[0]);
+  for (i=1; i<ARRAYSIZE; i++)
+    while (tealetarray[i] != NULL)
+      random_run(0);
+
+  fini_test();
+}
+
+
+
+/************************************************************/
+
+/* Another random switching test.  Tealets find a random target
+ * tealet to switch to and do that.  While the test is running, they
+ * generate new tealets to fill the array.  Each tealet runs x times
+ * and then exits.  The switching happens at a random depth.
+ */
+#define N_RUNS 10
+#define MAX_DESCEND 20
+
+void random2_run(int index);
+tealet_t *random2_tealet(tealet_t* cur, void *arg)
+{
+  int index = (int)arg;
+  assert(tealet_current(g_main) == cur);
+  assert(index > 0 && index < ARRAYSIZE);
+  assert(tealetarray[index] == NULL);
+  tealetarray[index] = cur;
+  random2_run(index);
+  tealetarray[index] = NULL;
+  return tealetarray[0]; /* switch to main */
+}
+void random2_new(int index) {
+    void *arg = (void*)index;
+    tealet_new(g_main, random2_tealet, &arg);
+}
+
+int random2_descend(int index, int level) {
+    int target;
+    if (level > 0)
+        return random2_descend(index, level-1);
+  
+    /* find target */
+    target = rand() % ARRAYSIZE;
+    if (status<MAX_STATUS) {
+        status += 1;
+        while(target == index)
+            target = rand() % ARRAYSIZE;
+        if (tealetarray[target] == NULL)
+            random2_new(target);
+        else
+            tealet_switch(tealetarray[target], NULL);
+        return 1;
+    } else {
+        /* find a telet */
+        int j;
+        for (j=0; j<ARRAYSIZE; j++) {
+            int k = (j + target) % ARRAYSIZE;
+            if (k != index && tealetarray[k]) {
+                status += 1;
+                tealet_switch(tealetarray[k], NULL);
+                return 1;
+            }
+        }
+        return 0;
+    }
+}
+            
+
+void random2_run(int index)
+{
+    int i;
+    assert(tealetarray[index] == NULL || tealetarray[index] == tealet_current(g_main));
+    tealetarray[index] = tealet_current(g_main);
+    for (i=0; i<N_RUNS; i++)
+        if (random2_descend(index, rand() % (MAX_DESCEND+1)) == 0)
+            break;
+    tealetarray[index] = NULL;
+}
+
+
+void test_random2(void)
+{
+    int i;
+    init_test();
+    for( i=0; i<ARRAYSIZE; i++)
+        tealetarray[i] = NULL;
+    tealetarray[0] = g_main;
+ 
+    while (status < MAX_STATUS)
+        random2_run(0);
+
+    /* drain the system */
+    tealetarray[0] = tealet_current(g_main);
+    for(;;) {
+        for(i=1; i<ARRAYSIZE; i++)
+            if (tealetarray[i]) {
+                status++;
+                tealet_switch(tealetarray[i], NULL);
+                break;
+            }
+        if (i == ARRAYSIZE)
+            break;
+    }
+    tealetarray[0] = NULL;
+    fini_test();
+}
+static void (*test_list[])(void) = {
+  test_main_current,
+  test_simple,
+  test_status,
+  test_exit,
+  test_switch,
+  test_switch_new,
+  test_arg,
+  test_random,
+  test_random2,
+  NULL
+};
+
+
+void runmode(int mode)
+{
+    int i;
+    newmode = mode;
+    printf("+++ Running tests with newmode = %d\n", newmode);
+    for (i = 0; test_list[i] != NULL; i++)
+    {
+        printf("+++ Running test %d... +++\n", i);
+        test_list[i]();
+    }
+    printf("+++ All ok. +++\n");
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+    for (i = 0; i<3; i++)
+        runmode(i);
+    runmode(-1);
+    return 0;
+}
diff --git a/Stackless/unittests/test_miscell.py b/Stackless/unittests/test_miscell.py
index 57d05420715287..91c34410fa4088 100644
--- a/Stackless/unittests/test_miscell.py
+++ b/Stackless/unittests/test_miscell.py
@@ -559,7 +559,6 @@ def testAtomicNopCtxt(self):
         finally:
             stackless.getcurrent().set_atomic(old)
 
-
 class TestSchedule(AsTaskletTestCase):
     def setUp(self):
         super(TestSchedule, self).setUp()
@@ -584,6 +583,44 @@ def foo(previous):
         stackless.schedule_remove()
         self.assertEqual(self.events, ["foo"])
 
+class TestUncollectables(StacklessTestCase):
+    def _testNone(self):
+        self.assertEqual(stackless.uncollectables, [])
+
+    def testOne(self):
+        before = set(stackless.uncollectables)
+        c = stackless.channel()
+        def func1():
+            stackless.test_cstate(func2) # force hard switch
+        def func2():
+            c.receive()
+        t = stackless.tasklet(func1)()
+        stackless.run()
+        after = set(stackless.uncollectables)
+        self.assertEqual(after-before, set([t]))
+        c.send(None)
+        stackless.run()
+        after = set(stackless.uncollectables)
+        self.assertEqual(after, before)
+
+    def testTwo(self):
+        before = set(stackless.uncollectables)
+        c = stackless.channel()
+        def func1():
+            stackless.test_cstate(func2) # force hard switch
+        def func2():
+            c.receive()
+        t1 = stackless.tasklet(func1)()
+        t2 = stackless.tasklet(func1)()
+        stackless.run()
+        after = set(stackless.uncollectables)
+        self.assertEqual(after - before, set([t1, t2]))
+        c.send(None)
+        c.send(None)
+        stackless.run()
+        after = set(stackless.uncollectables)
+        self.assertEqual(after, before)
+
 
 #///////////////////////////////////////////////////////////////////////////////