Added unmodified Python-2.7.5 sources

Change-Id: I230169787cb61d59d4b31f81bcdf98b57454c70b
diff --git a/Python-2.7.5/Objects/abstract.c b/Python-2.7.5/Objects/abstract.c
new file mode 100644
index 0000000..3c88711
--- /dev/null
+++ b/Python-2.7.5/Objects/abstract.c
@@ -0,0 +1,3113 @@
+/* Abstract Object Interface (many thanks to Jim Fulton) */
+
+#include "Python.h"
+#include <ctype.h>
+#include "structmember.h" /* we need the offsetof() macro from there */
+#include "longintrepr.h"
+
+#define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \
+                Py_TPFLAGS_CHECKTYPES)
+
+
+/* Shorthands to return certain errors */
+
+static PyObject *
+type_error(const char *msg, PyObject *obj)
+{
+    PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name);
+    return NULL;
+}
+
+static PyObject *
+null_error(void)
+{
+    if (!PyErr_Occurred())
+        PyErr_SetString(PyExc_SystemError,
+                        "null argument to internal routine");
+    return NULL;
+}
+
+/* Operations on any object */
+
+int
+PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
+{
+    int r;
+
+    if (o1 == NULL || o2 == NULL) {
+        null_error();
+        return -1;
+    }
+    r = PyObject_Compare(o1, o2);
+    if (PyErr_Occurred())
+        return -1;
+    *result = r;
+    return 0;
+}
+
+PyObject *
+PyObject_Type(PyObject *o)
+{
+    PyObject *v;
+
+    if (o == NULL)
+        return null_error();
+    v = (PyObject *)o->ob_type;
+    Py_INCREF(v);
+    return v;
+}
+
+Py_ssize_t
+PyObject_Size(PyObject *o)
+{
+    PySequenceMethods *m;
+
+    if (o == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = o->ob_type->tp_as_sequence;
+    if (m && m->sq_length)
+        return m->sq_length(o);
+
+    return PyMapping_Size(o);
+}
+
+#undef PyObject_Length
+Py_ssize_t
+PyObject_Length(PyObject *o)
+{
+    return PyObject_Size(o);
+}
+#define PyObject_Length PyObject_Size
+
+
+/* The length hint function returns a non-negative value from o.__len__()
+   or o.__length_hint__().  If those methods aren't found or return a negative
+   value, then the defaultvalue is returned.  If one of the calls fails,
+   this function returns -1.
+*/
+
+Py_ssize_t
+_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
+{
+    static PyObject *hintstrobj = NULL;
+    PyObject *ro, *hintmeth;
+    Py_ssize_t rv;
+
+    /* try o.__len__() */
+    rv = PyObject_Size(o);
+    if (rv >= 0)
+        return rv;
+    if (PyErr_Occurred()) {
+        if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
+            !PyErr_ExceptionMatches(PyExc_AttributeError))
+                return -1;
+        PyErr_Clear();
+    }
+
+    if (PyInstance_Check(o))
+        return defaultvalue;
+    /* try o.__length_hint__() */
+    hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj);
+    if (hintmeth == NULL) {
+        if (PyErr_Occurred())
+            return -1;
+        else
+            return defaultvalue;
+    }
+    ro = PyObject_CallFunctionObjArgs(hintmeth, NULL);
+    Py_DECREF(hintmeth);
+    if (ro == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
+            !PyErr_ExceptionMatches(PyExc_AttributeError))
+            return -1;
+        PyErr_Clear();
+        return defaultvalue;
+    }
+    rv = PyNumber_Check(ro) ? PyInt_AsSsize_t(ro) : defaultvalue;
+    Py_DECREF(ro);
+    return rv;
+}
+
+PyObject *
+PyObject_GetItem(PyObject *o, PyObject *key)
+{
+    PyMappingMethods *m;
+
+    if (o == NULL || key == NULL)
+        return null_error();
+
+    m = o->ob_type->tp_as_mapping;
+    if (m && m->mp_subscript)
+        return m->mp_subscript(o, key);
+
+    if (o->ob_type->tp_as_sequence) {
+        if (PyIndex_Check(key)) {
+            Py_ssize_t key_value;
+            key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+            if (key_value == -1 && PyErr_Occurred())
+                return NULL;
+            return PySequence_GetItem(o, key_value);
+        }
+        else if (o->ob_type->tp_as_sequence->sq_item)
+            return type_error("sequence index must "
+                              "be integer, not '%.200s'", key);
+    }
+
+    return type_error("'%.200s' object has no attribute '__getitem__'", o);
+}
+
+int
+PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
+{
+    PyMappingMethods *m;
+
+    if (o == NULL || key == NULL || value == NULL) {
+        null_error();
+        return -1;
+    }
+    m = o->ob_type->tp_as_mapping;
+    if (m && m->mp_ass_subscript)
+        return m->mp_ass_subscript(o, key, value);
+
+    if (o->ob_type->tp_as_sequence) {
+        if (PyIndex_Check(key)) {
+            Py_ssize_t key_value;
+            key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+            if (key_value == -1 && PyErr_Occurred())
+                return -1;
+            return PySequence_SetItem(o, key_value, value);
+        }
+        else if (o->ob_type->tp_as_sequence->sq_ass_item) {
+            type_error("sequence index must be "
+                       "integer, not '%.200s'", key);
+            return -1;
+        }
+    }
+
+    type_error("'%.200s' object does not support item assignment", o);
+    return -1;
+}
+
+int
+PyObject_DelItem(PyObject *o, PyObject *key)
+{
+    PyMappingMethods *m;
+
+    if (o == NULL || key == NULL) {
+        null_error();
+        return -1;
+    }
+    m = o->ob_type->tp_as_mapping;
+    if (m && m->mp_ass_subscript)
+        return m->mp_ass_subscript(o, key, (PyObject*)NULL);
+
+    if (o->ob_type->tp_as_sequence) {
+        if (PyIndex_Check(key)) {
+            Py_ssize_t key_value;
+            key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+            if (key_value == -1 && PyErr_Occurred())
+                return -1;
+            return PySequence_DelItem(o, key_value);
+        }
+        else if (o->ob_type->tp_as_sequence->sq_ass_item) {
+            type_error("sequence index must be "
+                       "integer, not '%.200s'", key);
+            return -1;
+        }
+    }
+
+    type_error("'%.200s' object does not support item deletion", o);
+    return -1;
+}
+
+int
+PyObject_DelItemString(PyObject *o, char *key)
+{
+    PyObject *okey;
+    int ret;
+
+    if (o == NULL || key == NULL) {
+        null_error();
+        return -1;
+    }
+    okey = PyString_FromString(key);
+    if (okey == NULL)
+        return -1;
+    ret = PyObject_DelItem(o, okey);
+    Py_DECREF(okey);
+    return ret;
+}
+
+int
+PyObject_AsCharBuffer(PyObject *obj,
+                          const char **buffer,
+                          Py_ssize_t *buffer_len)
+{
+    PyBufferProcs *pb;
+    char *pp;
+    Py_ssize_t len;
+
+    if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+        null_error();
+        return -1;
+    }
+    pb = obj->ob_type->tp_as_buffer;
+    if (pb == NULL ||
+         pb->bf_getcharbuffer == NULL ||
+         pb->bf_getsegcount == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected a character buffer object");
+        return -1;
+    }
+    if ((*pb->bf_getsegcount)(obj,NULL) != 1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected a single-segment buffer object");
+        return -1;
+    }
+    len = (*pb->bf_getcharbuffer)(obj, 0, &pp);
+    if (len < 0)
+        return -1;
+    *buffer = pp;
+    *buffer_len = len;
+    return 0;
+}
+
+int
+PyObject_CheckReadBuffer(PyObject *obj)
+{
+    PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
+
+    if (pb == NULL ||
+        pb->bf_getreadbuffer == NULL ||
+        pb->bf_getsegcount == NULL ||
+        (*pb->bf_getsegcount)(obj, NULL) != 1)
+        return 0;
+    return 1;
+}
+
+int PyObject_AsReadBuffer(PyObject *obj,
+                          const void **buffer,
+                          Py_ssize_t *buffer_len)
+{
+    PyBufferProcs *pb;
+    void *pp;
+    Py_ssize_t len;
+
+    if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+        null_error();
+        return -1;
+    }
+    pb = obj->ob_type->tp_as_buffer;
+    if (pb == NULL ||
+         pb->bf_getreadbuffer == NULL ||
+         pb->bf_getsegcount == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected a readable buffer object");
+        return -1;
+    }
+    if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected a single-segment buffer object");
+        return -1;
+    }
+    len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
+    if (len < 0)
+        return -1;
+    *buffer = pp;
+    *buffer_len = len;
+    return 0;
+}
+
+int PyObject_AsWriteBuffer(PyObject *obj,
+                           void **buffer,
+                           Py_ssize_t *buffer_len)
+{
+    PyBufferProcs *pb;
+    void*pp;
+    Py_ssize_t len;
+
+    if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+        null_error();
+        return -1;
+    }
+    pb = obj->ob_type->tp_as_buffer;
+    if (pb == NULL ||
+         pb->bf_getwritebuffer == NULL ||
+         pb->bf_getsegcount == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected a writeable buffer object");
+        return -1;
+    }
+    if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected a single-segment buffer object");
+        return -1;
+    }
+    len = (*pb->bf_getwritebuffer)(obj,0,&pp);
+    if (len < 0)
+        return -1;
+    *buffer = pp;
+    *buffer_len = len;
+    return 0;
+}
+
+/* Buffer C-API for Python 3.0 */
+
+int
+PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
+{
+    if (!PyObject_CheckBuffer(obj)) {
+        PyErr_Format(PyExc_TypeError,
+                     "'%100s' does not have the buffer interface",
+                     Py_TYPE(obj)->tp_name);
+        return -1;
+    }
+    return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
+}
+
+static int
+_IsFortranContiguous(Py_buffer *view)
+{
+    Py_ssize_t sd, dim;
+    int i;
+
+    if (view->ndim == 0) return 1;
+    if (view->strides == NULL) return (view->ndim == 1);
+
+    sd = view->itemsize;
+    if (view->ndim == 1) return (view->shape[0] == 1 ||
+                               sd == view->strides[0]);
+    for (i=0; i<view->ndim; i++) {
+        dim = view->shape[i];
+        if (dim == 0) return 1;
+        if (view->strides[i] != sd) return 0;
+        sd *= dim;
+    }
+    return 1;
+}
+
+static int
+_IsCContiguous(Py_buffer *view)
+{
+    Py_ssize_t sd, dim;
+    int i;
+
+    if (view->ndim == 0) return 1;
+    if (view->strides == NULL) return 1;
+
+    sd = view->itemsize;
+    if (view->ndim == 1) return (view->shape[0] == 1 ||
+                               sd == view->strides[0]);
+    for (i=view->ndim-1; i>=0; i--) {
+        dim = view->shape[i];
+        if (dim == 0) return 1;
+        if (view->strides[i] != sd) return 0;
+        sd *= dim;
+    }
+    return 1;
+}
+
+int
+PyBuffer_IsContiguous(Py_buffer *view, char fort)
+{
+
+    if (view->suboffsets != NULL) return 0;
+
+    if (fort == 'C')
+        return _IsCContiguous(view);
+    else if (fort == 'F')
+        return _IsFortranContiguous(view);
+    else if (fort == 'A')
+        return (_IsCContiguous(view) || _IsFortranContiguous(view));
+    return 0;
+}
+
+
+void*
+PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
+{
+    char* pointer;
+    int i;
+    pointer = (char *)view->buf;
+    for (i = 0; i < view->ndim; i++) {
+        pointer += view->strides[i]*indices[i];
+        if ((view->suboffsets != NULL) && (view->suboffsets[i] >= 0)) {
+            pointer = *((char**)pointer) + view->suboffsets[i];
+        }
+    }
+    return (void*)pointer;
+}
+
+
+void
+_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
+{
+    int k;
+
+    for (k=0; k<nd; k++) {
+        if (index[k] < shape[k]-1) {
+            index[k]++;
+            break;
+        }
+        else {
+            index[k] = 0;
+        }
+    }
+}
+
+void
+_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
+{
+    int k;
+
+    for (k=nd-1; k>=0; k--) {
+        if (index[k] < shape[k]-1) {
+            index[k]++;
+            break;
+        }
+        else {
+            index[k] = 0;
+        }
+    }
+}
+
+  /* view is not checked for consistency in either of these.  It is
+     assumed that the size of the buffer is view->len in
+     view->len / view->itemsize elements.
+  */
+
+int
+PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
+{
+    int k;
+    void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
+    Py_ssize_t *indices, elements;
+    char *dest, *ptr;
+
+    if (len > view->len) {
+        len = view->len;
+    }
+
+    if (PyBuffer_IsContiguous(view, fort)) {
+        /* simplest copy is all that is needed */
+        memcpy(buf, view->buf, len);
+        return 0;
+    }
+
+    /* Otherwise a more elaborate scheme is needed */
+
+    /* XXX(nnorwitz): need to check for overflow! */
+    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
+    if (indices == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    for (k=0; k<view->ndim;k++) {
+        indices[k] = 0;
+    }
+
+    if (fort == 'F') {
+        addone = _Py_add_one_to_index_F;
+    }
+    else {
+        addone = _Py_add_one_to_index_C;
+    }
+    dest = buf;
+    /* XXX : This is not going to be the fastest code in the world
+             several optimizations are possible.
+     */
+    elements = len / view->itemsize;
+    while (elements--) {
+        addone(view->ndim, indices, view->shape);
+        ptr = PyBuffer_GetPointer(view, indices);
+        memcpy(dest, ptr, view->itemsize);
+        dest += view->itemsize;
+    }
+    PyMem_Free(indices);
+    return 0;
+}
+
+int
+PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
+{
+    int k;
+    void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
+    Py_ssize_t *indices, elements;
+    char *src, *ptr;
+
+    if (len > view->len) {
+        len = view->len;
+    }
+
+    if (PyBuffer_IsContiguous(view, fort)) {
+        /* simplest copy is all that is needed */
+        memcpy(view->buf, buf, len);
+        return 0;
+    }
+
+    /* Otherwise a more elaborate scheme is needed */
+
+    /* XXX(nnorwitz): need to check for overflow! */
+    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
+    if (indices == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    for (k=0; k<view->ndim;k++) {
+        indices[k] = 0;
+    }
+
+    if (fort == 'F') {
+        addone = _Py_add_one_to_index_F;
+    }
+    else {
+        addone = _Py_add_one_to_index_C;
+    }
+    src = buf;
+    /* XXX : This is not going to be the fastest code in the world
+             several optimizations are possible.
+     */
+    elements = len / view->itemsize;
+    while (elements--) {
+        addone(view->ndim, indices, view->shape);
+        ptr = PyBuffer_GetPointer(view, indices);
+        memcpy(ptr, src, view->itemsize);
+        src += view->itemsize;
+    }
+
+    PyMem_Free(indices);
+    return 0;
+}
+
+int PyObject_CopyData(PyObject *dest, PyObject *src)
+{
+    Py_buffer view_dest, view_src;
+    int k;
+    Py_ssize_t *indices, elements;
+    char *dptr, *sptr;
+
+    if (!PyObject_CheckBuffer(dest) ||
+        !PyObject_CheckBuffer(src)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "both destination and source must have the "\
+                        "buffer interface");
+        return -1;
+    }
+
+    if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
+    if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
+        PyBuffer_Release(&view_dest);
+        return -1;
+    }
+
+    if (view_dest.len < view_src.len) {
+        PyErr_SetString(PyExc_BufferError,
+                        "destination is too small to receive data from source");
+        PyBuffer_Release(&view_dest);
+        PyBuffer_Release(&view_src);
+        return -1;
+    }
+
+    if ((PyBuffer_IsContiguous(&view_dest, 'C') &&
+         PyBuffer_IsContiguous(&view_src, 'C')) ||
+        (PyBuffer_IsContiguous(&view_dest, 'F') &&
+         PyBuffer_IsContiguous(&view_src, 'F'))) {
+        /* simplest copy is all that is needed */
+        memcpy(view_dest.buf, view_src.buf, view_src.len);
+        PyBuffer_Release(&view_dest);
+        PyBuffer_Release(&view_src);
+        return 0;
+    }
+
+    /* Otherwise a more elaborate copy scheme is needed */
+
+    /* XXX(nnorwitz): need to check for overflow! */
+    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
+    if (indices == NULL) {
+        PyErr_NoMemory();
+        PyBuffer_Release(&view_dest);
+        PyBuffer_Release(&view_src);
+        return -1;
+    }
+    for (k=0; k<view_src.ndim;k++) {
+        indices[k] = 0;
+    }
+    elements = 1;
+    for (k=0; k<view_src.ndim; k++) {
+        /* XXX(nnorwitz): can this overflow? */
+        elements *= view_src.shape[k];
+    }
+    while (elements--) {
+        _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape);
+        dptr = PyBuffer_GetPointer(&view_dest, indices);
+        sptr = PyBuffer_GetPointer(&view_src, indices);
+        memcpy(dptr, sptr, view_src.itemsize);
+    }
+    PyMem_Free(indices);
+    PyBuffer_Release(&view_dest);
+    PyBuffer_Release(&view_src);
+    return 0;
+}
+
+void
+PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
+                               Py_ssize_t *strides, int itemsize,
+                               char fort)
+{
+    int k;
+    Py_ssize_t sd;
+
+    sd = itemsize;
+    if (fort == 'F') {
+        for (k=0; k<nd; k++) {
+            strides[k] = sd;
+            sd *= shape[k];
+        }
+    }
+    else {
+        for (k=nd-1; k>=0; k--) {
+            strides[k] = sd;
+            sd *= shape[k];
+        }
+    }
+    return;
+}
+
+int
+PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
+              int readonly, int flags)
+{
+    if (view == NULL) return 0;
+    if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) &&
+        (readonly == 1)) {
+        PyErr_SetString(PyExc_BufferError,
+                        "Object is not writable.");
+        return -1;
+    }
+
+    view->obj = obj;
+    if (obj)
+        Py_INCREF(obj);
+    view->buf = buf;
+    view->len = len;
+    view->readonly = readonly;
+    view->itemsize = 1;
+    view->format = NULL;
+    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
+        view->format = "B";
+    view->ndim = 1;
+    view->shape = NULL;
+    if ((flags & PyBUF_ND) == PyBUF_ND)
+        view->shape = &(view->len);
+    view->strides = NULL;
+    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
+        view->strides = &(view->itemsize);
+    view->suboffsets = NULL;
+    view->internal = NULL;
+    return 0;
+}
+
+void
+PyBuffer_Release(Py_buffer *view)
+{
+    PyObject *obj = view->obj;
+    if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
+        Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
+    Py_XDECREF(obj);
+    view->obj = NULL;
+}
+
+PyObject *
+PyObject_Format(PyObject* obj, PyObject *format_spec)
+{
+    PyObject *empty = NULL;
+    PyObject *result = NULL;
+#ifdef Py_USING_UNICODE
+    int spec_is_unicode;
+    int result_is_unicode;
+#endif
+
+    /* If no format_spec is provided, use an empty string */
+    if (format_spec == NULL) {
+        empty = PyString_FromStringAndSize(NULL, 0);
+        format_spec = empty;
+    }
+
+    /* Check the format_spec type, and make sure it's str or unicode */
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(format_spec))
+        spec_is_unicode = 1;
+    else if (PyString_Check(format_spec))
+        spec_is_unicode = 0;
+    else {
+#else
+    if (!PyString_Check(format_spec)) {
+#endif
+        PyErr_Format(PyExc_TypeError,
+                     "format expects arg 2 to be string "
+                     "or unicode, not %.100s", Py_TYPE(format_spec)->tp_name);
+        goto done;
+    }
+
+    /* Check for a __format__ method and call it. */
+    if (PyInstance_Check(obj)) {
+        /* We're an instance of a classic class */
+        PyObject *bound_method = PyObject_GetAttrString(obj, "__format__");
+        if (bound_method != NULL) {
+            result = PyObject_CallFunctionObjArgs(bound_method,
+                                                  format_spec,
+                                                  NULL);
+            Py_DECREF(bound_method);
+        } else {
+            PyObject *self_as_str = NULL;
+            PyObject *format_method = NULL;
+            Py_ssize_t format_len;
+
+            PyErr_Clear();
+            /* Per the PEP, convert to str (or unicode,
+               depending on the type of the format
+               specifier).  For new-style classes, this
+               logic is done by object.__format__(). */
+#ifdef Py_USING_UNICODE
+            if (spec_is_unicode) {
+                format_len = PyUnicode_GET_SIZE(format_spec);
+                self_as_str = PyObject_Unicode(obj);
+            } else
+#endif
+            {
+                format_len = PyString_GET_SIZE(format_spec);
+                self_as_str = PyObject_Str(obj);
+            }
+            if (self_as_str == NULL)
+                goto done1;
+
+            if (format_len > 0) {
+                /* See the almost identical code in
+                   typeobject.c for new-style
+                   classes. */
+                if (PyErr_WarnEx(
+                    PyExc_PendingDeprecationWarning,
+                    "object.__format__ with a non-empty "
+                    "format string is deprecated", 1)
+                     < 0) {
+                    goto done1;
+                }
+                /* Eventually this will become an
+                   error:
+                PyErr_Format(PyExc_TypeError,
+                   "non-empty format string passed to "
+                   "object.__format__");
+                goto done1;
+                */
+            }
+
+            /* Then call str.__format__ on that result */
+            format_method = PyObject_GetAttrString(self_as_str, "__format__");
+            if (format_method == NULL) {
+                goto done1;
+            }
+            result = PyObject_CallFunctionObjArgs(format_method,
+                                                  format_spec,
+                                                  NULL);
+done1:
+            Py_XDECREF(self_as_str);
+            Py_XDECREF(format_method);
+            if (result == NULL)
+                goto done;
+        }
+    } else {
+        /* Not an instance of a classic class, use the code
+           from py3k */
+        static PyObject *format_cache = NULL;
+
+        /* Find the (unbound!) __format__ method (a borrowed
+           reference) */
+        PyObject *method = _PyObject_LookupSpecial(obj, "__format__",
+                                                   &format_cache);
+        if (method == NULL) {
+            if (!PyErr_Occurred())
+                PyErr_Format(PyExc_TypeError,
+                             "Type %.100s doesn't define __format__",
+                             Py_TYPE(obj)->tp_name);
+            goto done;
+        }
+        /* And call it. */
+        result = PyObject_CallFunctionObjArgs(method, format_spec, NULL);
+        Py_DECREF(method);
+    }
+
+    if (result == NULL)
+        goto done;
+
+    /* Check the result type, and make sure it's str or unicode */
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(result))
+        result_is_unicode = 1;
+    else if (PyString_Check(result))
+        result_is_unicode = 0;
+    else {
+#else
+    if (!PyString_Check(result)) {
+#endif
+        PyErr_Format(PyExc_TypeError,
+                     "%.100s.__format__ must return string or "
+                     "unicode, not %.100s", Py_TYPE(obj)->tp_name,
+                     Py_TYPE(result)->tp_name);
+        Py_DECREF(result);
+        result = NULL;
+        goto done;
+    }
+
+    /* Convert to unicode, if needed.  Required if spec is unicode
+       and result is str */
+#ifdef Py_USING_UNICODE
+    if (spec_is_unicode && !result_is_unicode) {
+        PyObject *tmp = PyObject_Unicode(result);
+        /* This logic works whether or not tmp is NULL */
+        Py_DECREF(result);
+        result = tmp;
+    }
+#endif
+
+done:
+    Py_XDECREF(empty);
+    return result;
+}
+
+/* Operations on numbers */
+
+int
+PyNumber_Check(PyObject *o)
+{
+    return o && o->ob_type->tp_as_number &&
+           (o->ob_type->tp_as_number->nb_int ||
+        o->ob_type->tp_as_number->nb_float);
+}
+
+/* Binary operators */
+
+/* New style number protocol support */
+
+#define NB_SLOT(x) offsetof(PyNumberMethods, x)
+#define NB_BINOP(nb_methods, slot) \
+        (*(binaryfunc*)(& ((char*)nb_methods)[slot]))
+#define NB_TERNOP(nb_methods, slot) \
+        (*(ternaryfunc*)(& ((char*)nb_methods)[slot]))
+
+/*
+  Calling scheme used for binary operations:
+
+  v     w       Action
+  -------------------------------------------------------------------
+  new   new     w.op(v,w)[*], v.op(v,w), w.op(v,w)
+  new   old     v.op(v,w), coerce(v,w), v.op(v,w)
+  old   new     w.op(v,w), coerce(v,w), v.op(v,w)
+  old   old     coerce(v,w), v.op(v,w)
+
+  [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of
+      v->ob_type
+
+  Legend:
+  -------
+  * new == new style number
+  * old == old style number
+  * Action indicates the order in which operations are tried until either
+    a valid result is produced or an error occurs.
+
+ */
+
+static PyObject *
+binary_op1(PyObject *v, PyObject *w, const int op_slot)
+{
+    PyObject *x;
+    binaryfunc slotv = NULL;
+    binaryfunc slotw = NULL;
+
+    if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v))
+        slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
+    if (w->ob_type != v->ob_type &&
+        w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) {
+        slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot);
+        if (slotw == slotv)
+            slotw = NULL;
+    }
+    if (slotv) {
+        if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
+            x = slotw(v, w);
+            if (x != Py_NotImplemented)
+                return x;
+            Py_DECREF(x); /* can't do it */
+            slotw = NULL;
+        }
+        x = slotv(v, w);
+        if (x != Py_NotImplemented)
+            return x;
+        Py_DECREF(x); /* can't do it */
+    }
+    if (slotw) {
+        x = slotw(v, w);
+        if (x != Py_NotImplemented)
+            return x;
+        Py_DECREF(x); /* can't do it */
+    }
+    if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) {
+        int err = PyNumber_CoerceEx(&v, &w);
+        if (err < 0) {
+            return NULL;
+        }
+        if (err == 0) {
+            PyNumberMethods *mv = v->ob_type->tp_as_number;
+            if (mv) {
+                binaryfunc slot;
+                slot = NB_BINOP(mv, op_slot);
+                if (slot) {
+                    x = slot(v, w);
+                    Py_DECREF(v);
+                    Py_DECREF(w);
+                    return x;
+                }
+            }
+            /* CoerceEx incremented the reference counts */
+            Py_DECREF(v);
+            Py_DECREF(w);
+        }
+    }
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+static PyObject *
+binop_type_error(PyObject *v, PyObject *w, const char *op_name)
+{
+    PyErr_Format(PyExc_TypeError,
+                 "unsupported operand type(s) for %.100s: "
+                 "'%.100s' and '%.100s'",
+                 op_name,
+                 v->ob_type->tp_name,
+                 w->ob_type->tp_name);
+    return NULL;
+}
+
+static PyObject *
+binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
+{
+    PyObject *result = binary_op1(v, w, op_slot);
+    if (result == Py_NotImplemented) {
+        Py_DECREF(result);
+        return binop_type_error(v, w, op_name);
+    }
+    return result;
+}
+
+
+/*
+  Calling scheme used for ternary operations:
+
+  *** In some cases, w.op is called before v.op; see binary_op1. ***
+
+  v     w       z       Action
+  -------------------------------------------------------------------
+  new   new     new     v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
+  new   old     new     v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old   new     new     w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old   old     new     z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  new   new     old     v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  new   old     old     v.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old   new     old     w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+  old   old     old     coerce(v,w,z), v.op(v,w,z)
+
+  Legend:
+  -------
+  * new == new style number
+  * old == old style number
+  * Action indicates the order in which operations are tried until either
+    a valid result is produced or an error occurs.
+  * coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and
+    only if z != Py_None; if z == Py_None, then it is treated as absent
+    variable and only coerce(v,w) is tried.
+
+ */
+
+static PyObject *
+ternary_op(PyObject *v,
+           PyObject *w,
+           PyObject *z,
+           const int op_slot,
+           const char *op_name)
+{
+    PyNumberMethods *mv, *mw, *mz;
+    PyObject *x = NULL;
+    ternaryfunc slotv = NULL;
+    ternaryfunc slotw = NULL;
+    ternaryfunc slotz = NULL;
+
+    mv = v->ob_type->tp_as_number;
+    mw = w->ob_type->tp_as_number;
+    if (mv != NULL && NEW_STYLE_NUMBER(v))
+        slotv = NB_TERNOP(mv, op_slot);
+    if (w->ob_type != v->ob_type &&
+        mw != NULL && NEW_STYLE_NUMBER(w)) {
+        slotw = NB_TERNOP(mw, op_slot);
+        if (slotw == slotv)
+            slotw = NULL;
+    }
+    if (slotv) {
+        if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
+            x = slotw(v, w, z);
+            if (x != Py_NotImplemented)
+                return x;
+            Py_DECREF(x); /* can't do it */
+            slotw = NULL;
+        }
+        x = slotv(v, w, z);
+        if (x != Py_NotImplemented)
+            return x;
+        Py_DECREF(x); /* can't do it */
+    }
+    if (slotw) {
+        x = slotw(v, w, z);
+        if (x != Py_NotImplemented)
+            return x;
+        Py_DECREF(x); /* can't do it */
+    }
+    mz = z->ob_type->tp_as_number;
+    if (mz != NULL && NEW_STYLE_NUMBER(z)) {
+        slotz = NB_TERNOP(mz, op_slot);
+        if (slotz == slotv || slotz == slotw)
+            slotz = NULL;
+        if (slotz) {
+            x = slotz(v, w, z);
+            if (x != Py_NotImplemented)
+                return x;
+            Py_DECREF(x); /* can't do it */
+        }
+    }
+
+    if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w) ||
+                    (z != Py_None && !NEW_STYLE_NUMBER(z))) {
+        /* we have an old style operand, coerce */
+        PyObject *v1, *z1, *w2, *z2;
+        int c;
+
+        c = PyNumber_Coerce(&v, &w);
+        if (c != 0)
+            goto error3;
+
+        /* Special case: if the third argument is None, it is
+           treated as absent argument and not coerced. */
+        if (z == Py_None) {
+            if (v->ob_type->tp_as_number) {
+                slotz = NB_TERNOP(v->ob_type->tp_as_number,
+                                  op_slot);
+                if (slotz)
+                    x = slotz(v, w, z);
+                else
+                    c = -1;
+            }
+            else
+                c = -1;
+            goto error2;
+        }
+        v1 = v;
+        z1 = z;
+        c = PyNumber_Coerce(&v1, &z1);
+        if (c != 0)
+            goto error2;
+        w2 = w;
+        z2 = z1;
+        c = PyNumber_Coerce(&w2, &z2);
+        if (c != 0)
+            goto error1;
+
+        if (v1->ob_type->tp_as_number != NULL) {
+            slotv = NB_TERNOP(v1->ob_type->tp_as_number,
+                              op_slot);
+            if (slotv)
+                x = slotv(v1, w2, z2);
+            else
+                c = -1;
+        }
+        else
+            c = -1;
+
+        Py_DECREF(w2);
+        Py_DECREF(z2);
+    error1:
+        Py_DECREF(v1);
+        Py_DECREF(z1);
+    error2:
+        Py_DECREF(v);
+        Py_DECREF(w);
+    error3:
+        if (c >= 0)
+            return x;
+    }
+
+    if (z == Py_None)
+        PyErr_Format(
+            PyExc_TypeError,
+            "unsupported operand type(s) for ** or pow(): "
+            "'%.100s' and '%.100s'",
+            v->ob_type->tp_name,
+            w->ob_type->tp_name);
+    else
+        PyErr_Format(
+            PyExc_TypeError,
+            "unsupported operand type(s) for pow(): "
+            "'%.100s', '%.100s', '%.100s'",
+            v->ob_type->tp_name,
+            w->ob_type->tp_name,
+            z->ob_type->tp_name);
+    return NULL;
+}
+
+#define BINARY_FUNC(func, op, op_name) \
+    PyObject * \
+    func(PyObject *v, PyObject *w) { \
+        return binary_op(v, w, NB_SLOT(op), op_name); \
+    }
+
+BINARY_FUNC(PyNumber_Or, nb_or, "|")
+BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
+BINARY_FUNC(PyNumber_And, nb_and, "&")
+BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
+BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
+BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
+BINARY_FUNC(PyNumber_Divide, nb_divide, "/")
+BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
+
+PyObject *
+PyNumber_Add(PyObject *v, PyObject *w)
+{
+    PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
+    if (result == Py_NotImplemented) {
+        PySequenceMethods *m = v->ob_type->tp_as_sequence;
+        Py_DECREF(result);
+        if (m && m->sq_concat) {
+            return (*m->sq_concat)(v, w);
+        }
+        result = binop_type_error(v, w, "+");
+    }
+    return result;
+}
+
+static PyObject *
+sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
+{
+    Py_ssize_t count;
+    if (PyIndex_Check(n)) {
+        count = PyNumber_AsSsize_t(n, PyExc_OverflowError);
+        if (count == -1 && PyErr_Occurred())
+            return NULL;
+    }
+    else {
+        return type_error("can't multiply sequence by "
+                          "non-int of type '%.200s'", n);
+    }
+    return (*repeatfunc)(seq, count);
+}
+
+PyObject *
+PyNumber_Multiply(PyObject *v, PyObject *w)
+{
+    PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply));
+    if (result == Py_NotImplemented) {
+        PySequenceMethods *mv = v->ob_type->tp_as_sequence;
+        PySequenceMethods *mw = w->ob_type->tp_as_sequence;
+        Py_DECREF(result);
+        if  (mv && mv->sq_repeat) {
+            return sequence_repeat(mv->sq_repeat, v, w);
+        }
+        else if (mw && mw->sq_repeat) {
+            return sequence_repeat(mw->sq_repeat, w, v);
+        }
+        result = binop_type_error(v, w, "*");
+    }
+    return result;
+}
+
+PyObject *
+PyNumber_FloorDivide(PyObject *v, PyObject *w)
+{
+    /* XXX tp_flags test */
+    return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
+}
+
+PyObject *
+PyNumber_TrueDivide(PyObject *v, PyObject *w)
+{
+    /* XXX tp_flags test */
+    return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
+}
+
+PyObject *
+PyNumber_Remainder(PyObject *v, PyObject *w)
+{
+    return binary_op(v, w, NB_SLOT(nb_remainder), "%");
+}
+
+PyObject *
+PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
+{
+    return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
+}
+
+/* Binary in-place operators */
+
+/* The in-place operators are defined to fall back to the 'normal',
+   non in-place operations, if the in-place methods are not in place.
+
+   - If the left hand object has the appropriate struct members, and
+     they are filled, call the appropriate function and return the
+     result.  No coercion is done on the arguments; the left-hand object
+     is the one the operation is performed on, and it's up to the
+     function to deal with the right-hand object.
+
+   - Otherwise, in-place modification is not supported. Handle it exactly as
+     a non in-place operation of the same kind.
+
+   */
+
+#define HASINPLACE(t) \
+    PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS)
+
+static PyObject *
+binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
+{
+    PyNumberMethods *mv = v->ob_type->tp_as_number;
+    if (mv != NULL && HASINPLACE(v)) {
+        binaryfunc slot = NB_BINOP(mv, iop_slot);
+        if (slot) {
+            PyObject *x = (slot)(v, w);
+            if (x != Py_NotImplemented) {
+                return x;
+            }
+            Py_DECREF(x);
+        }
+    }
+    return binary_op1(v, w, op_slot);
+}
+
+static PyObject *
+binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
+                const char *op_name)
+{
+    PyObject *result = binary_iop1(v, w, iop_slot, op_slot);
+    if (result == Py_NotImplemented) {
+        Py_DECREF(result);
+        return binop_type_error(v, w, op_name);
+    }
+    return result;
+}
+
+#define INPLACE_BINOP(func, iop, op, op_name) \
+    PyObject * \
+    func(PyObject *v, PyObject *w) { \
+        return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
+    }
+
+INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
+INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
+INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
+INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
+INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
+INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
+INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=")
+
+PyObject *
+PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
+{
+    /* XXX tp_flags test */
+    return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
+                      NB_SLOT(nb_floor_divide), "//=");
+}
+
+PyObject *
+PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
+{
+    /* XXX tp_flags test */
+    return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
+                      NB_SLOT(nb_true_divide), "/=");
+}
+
+PyObject *
+PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
+{
+    PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add),
+                                   NB_SLOT(nb_add));
+    if (result == Py_NotImplemented) {
+        PySequenceMethods *m = v->ob_type->tp_as_sequence;
+        Py_DECREF(result);
+        if (m != NULL) {
+            binaryfunc f = NULL;
+            if (HASINPLACE(v))
+                f = m->sq_inplace_concat;
+            if (f == NULL)
+                f = m->sq_concat;
+            if (f != NULL)
+                return (*f)(v, w);
+        }
+        result = binop_type_error(v, w, "+=");
+    }
+    return result;
+}
+
+PyObject *
+PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
+{
+    PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply),
+                                   NB_SLOT(nb_multiply));
+    if (result == Py_NotImplemented) {
+        ssizeargfunc f = NULL;
+        PySequenceMethods *mv = v->ob_type->tp_as_sequence;
+        PySequenceMethods *mw = w->ob_type->tp_as_sequence;
+        Py_DECREF(result);
+        if (mv != NULL) {
+            if (HASINPLACE(v))
+                f = mv->sq_inplace_repeat;
+            if (f == NULL)
+                f = mv->sq_repeat;
+            if (f != NULL)
+                return sequence_repeat(f, v, w);
+        }
+        else if (mw != NULL) {
+            /* Note that the right hand operand should not be
+             * mutated in this case so sq_inplace_repeat is not
+             * used. */
+            if (mw->sq_repeat)
+                return sequence_repeat(mw->sq_repeat, w, v);
+        }
+        result = binop_type_error(v, w, "*=");
+    }
+    return result;
+}
+
+PyObject *
+PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
+{
+    return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
+                            NB_SLOT(nb_remainder), "%=");
+}
+
+PyObject *
+PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
+{
+    if (HASINPLACE(v) && v->ob_type->tp_as_number &&
+        v->ob_type->tp_as_number->nb_inplace_power != NULL) {
+        return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
+    }
+    else {
+        return ternary_op(v, w, z, NB_SLOT(nb_power), "**=");
+    }
+}
+
+
+/* Unary operators and functions */
+
+PyObject *
+PyNumber_Negative(PyObject *o)
+{
+    PyNumberMethods *m;
+
+    if (o == NULL)
+        return null_error();
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_negative)
+        return (*m->nb_negative)(o);
+
+    return type_error("bad operand type for unary -: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Positive(PyObject *o)
+{
+    PyNumberMethods *m;
+
+    if (o == NULL)
+        return null_error();
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_positive)
+        return (*m->nb_positive)(o);
+
+    return type_error("bad operand type for unary +: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Invert(PyObject *o)
+{
+    PyNumberMethods *m;
+
+    if (o == NULL)
+        return null_error();
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_invert)
+        return (*m->nb_invert)(o);
+
+    return type_error("bad operand type for unary ~: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Absolute(PyObject *o)
+{
+    PyNumberMethods *m;
+
+    if (o == NULL)
+        return null_error();
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_absolute)
+        return m->nb_absolute(o);
+
+    return type_error("bad operand type for abs(): '%.200s'", o);
+}
+
+/* Add a check for embedded NULL-bytes in the argument. */
+static PyObject *
+int_from_string(const char *s, Py_ssize_t len)
+{
+    char *end;
+    PyObject *x;
+
+    x = PyInt_FromString((char*)s, &end, 10);
+    if (x == NULL)
+        return NULL;
+    if (end != s + len) {
+        PyErr_SetString(PyExc_ValueError,
+                        "null byte in argument for int()");
+        Py_DECREF(x);
+        return NULL;
+    }
+    return x;
+}
+
+/* Return a Python Int or Long from the object item
+   Raise TypeError if the result is not an int-or-long
+   or if the object cannot be interpreted as an index.
+*/
+PyObject *
+PyNumber_Index(PyObject *item)
+{
+    PyObject *result = NULL;
+    if (item == NULL)
+        return null_error();
+    if (PyInt_Check(item) || PyLong_Check(item)) {
+        Py_INCREF(item);
+        return item;
+    }
+    if (PyIndex_Check(item)) {
+        result = item->ob_type->tp_as_number->nb_index(item);
+        if (result &&
+            !PyInt_Check(result) && !PyLong_Check(result)) {
+            PyErr_Format(PyExc_TypeError,
+                         "__index__ returned non-(int,long) " \
+                         "(type %.200s)",
+                         result->ob_type->tp_name);
+            Py_DECREF(result);
+            return NULL;
+        }
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "'%.200s' object cannot be interpreted "
+                     "as an index", item->ob_type->tp_name);
+    }
+    return result;
+}
+
+/* Return an error on Overflow only if err is not NULL*/
+
+Py_ssize_t
+PyNumber_AsSsize_t(PyObject *item, PyObject *err)
+{
+    Py_ssize_t result;
+    PyObject *runerr;
+    PyObject *value = PyNumber_Index(item);
+    if (value == NULL)
+        return -1;
+
+    /* We're done if PyInt_AsSsize_t() returns without error. */
+    result = PyInt_AsSsize_t(value);
+    if (result != -1 || !(runerr = PyErr_Occurred()))
+        goto finish;
+
+    /* Error handling code -- only manage OverflowError differently */
+    if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
+        goto finish;
+
+    PyErr_Clear();
+    /* If no error-handling desired then the default clipping
+       is sufficient.
+     */
+    if (!err) {
+        assert(PyLong_Check(value));
+        /* Whether or not it is less than or equal to
+           zero is determined by the sign of ob_size
+        */
+        if (_PyLong_Sign(value) < 0)
+            result = PY_SSIZE_T_MIN;
+        else
+            result = PY_SSIZE_T_MAX;
+    }
+    else {
+        /* Otherwise replace the error with caller's error object. */
+        PyErr_Format(err,
+                     "cannot fit '%.200s' into an index-sized integer",
+                     item->ob_type->tp_name);
+    }
+
+ finish:
+    Py_DECREF(value);
+    return result;
+}
+
+
+PyObject *
+_PyNumber_ConvertIntegralToInt(PyObject *integral, const char* error_format)
+{
+    const char *type_name;
+    static PyObject *int_name = NULL;
+    if (int_name == NULL) {
+        int_name = PyString_InternFromString("__int__");
+        if (int_name == NULL)
+            return NULL;
+    }
+
+    if (integral && (!PyInt_Check(integral) &&
+                     !PyLong_Check(integral))) {
+        /* Don't go through tp_as_number->nb_int to avoid
+           hitting the classic class fallback to __trunc__. */
+        PyObject *int_func = PyObject_GetAttr(integral, int_name);
+        if (int_func == NULL) {
+            PyErr_Clear(); /* Raise a different error. */
+            goto non_integral_error;
+        }
+        Py_DECREF(integral);
+        integral = PyEval_CallObject(int_func, NULL);
+        Py_DECREF(int_func);
+        if (integral && (!PyInt_Check(integral) &&
+                          !PyLong_Check(integral))) {
+            goto non_integral_error;
+        }
+    }
+    return integral;
+
+non_integral_error:
+    if (PyInstance_Check(integral)) {
+        type_name = PyString_AS_STRING(((PyInstanceObject *)integral)
+                                       ->in_class->cl_name);
+    }
+    else {
+        type_name = integral->ob_type->tp_name;
+    }
+    PyErr_Format(PyExc_TypeError, error_format, type_name);
+    Py_DECREF(integral);
+    return NULL;
+}
+
+
+PyObject *
+PyNumber_Int(PyObject *o)
+{
+    PyNumberMethods *m;
+    static PyObject *trunc_name = NULL;
+    PyObject *trunc_func;
+    const char *buffer;
+    Py_ssize_t buffer_len;
+
+    if (trunc_name == NULL) {
+        trunc_name = PyString_InternFromString("__trunc__");
+        if (trunc_name == NULL)
+            return NULL;
+    }
+
+    if (o == NULL)
+        return null_error();
+    if (PyInt_CheckExact(o)) {
+        Py_INCREF(o);
+        return o;
+    }
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_int) { /* This should include subclasses of int */
+        /* Classic classes always take this branch. */
+        PyObject *res = m->nb_int(o);
+        if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+            PyErr_Format(PyExc_TypeError,
+                         "__int__ returned non-int (type %.200s)",
+                         res->ob_type->tp_name);
+            Py_DECREF(res);
+            return NULL;
+        }
+        return res;
+    }
+    if (PyInt_Check(o)) { /* A int subclass without nb_int */
+        PyIntObject *io = (PyIntObject*)o;
+        return PyInt_FromLong(io->ob_ival);
+    }
+    trunc_func = PyObject_GetAttr(o, trunc_name);
+    if (trunc_func) {
+        PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
+        Py_DECREF(trunc_func);
+        /* __trunc__ is specified to return an Integral type, but
+           int() needs to return an int. */
+        return _PyNumber_ConvertIntegralToInt(
+            truncated,
+            "__trunc__ returned non-Integral (type %.200s)");
+    }
+    PyErr_Clear();  /* It's not an error if  o.__trunc__ doesn't exist. */
+
+    if (PyString_Check(o))
+        return int_from_string(PyString_AS_STRING(o),
+                               PyString_GET_SIZE(o));
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(o))
+        return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
+                                 PyUnicode_GET_SIZE(o),
+                                 10);
+#endif
+    if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
+        return int_from_string((char*)buffer, buffer_len);
+
+    return type_error("int() argument must be a string or a "
+                      "number, not '%.200s'", o);
+}
+
+/* Add a check for embedded NULL-bytes in the argument. */
+static PyObject *
+long_from_string(const char *s, Py_ssize_t len)
+{
+    char *end;
+    PyObject *x;
+
+    x = PyLong_FromString((char*)s, &end, 10);
+    if (x == NULL)
+        return NULL;
+    if (end != s + len) {
+        PyErr_SetString(PyExc_ValueError,
+                        "null byte in argument for long()");
+        Py_DECREF(x);
+        return NULL;
+    }
+    return x;
+}
+
+PyObject *
+PyNumber_Long(PyObject *o)
+{
+    PyNumberMethods *m;
+    static PyObject *trunc_name = NULL;
+    PyObject *trunc_func;
+    const char *buffer;
+    Py_ssize_t buffer_len;
+
+    if (trunc_name == NULL) {
+        trunc_name = PyString_InternFromString("__trunc__");
+        if (trunc_name == NULL)
+            return NULL;
+    }
+
+    if (o == NULL)
+        return null_error();
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_long) { /* This should include subclasses of long */
+        /* Classic classes always take this branch. */
+        PyObject *res = m->nb_long(o);
+        if (res == NULL)
+            return NULL;
+        if (PyInt_Check(res)) {
+            long value = PyInt_AS_LONG(res);
+            Py_DECREF(res);
+            return PyLong_FromLong(value);
+        }
+        else if (!PyLong_Check(res)) {
+            PyErr_Format(PyExc_TypeError,
+                         "__long__ returned non-long (type %.200s)",
+                         res->ob_type->tp_name);
+            Py_DECREF(res);
+            return NULL;
+        }
+        return res;
+    }
+    if (PyLong_Check(o)) /* A long subclass without nb_long */
+        return _PyLong_Copy((PyLongObject *)o);
+    trunc_func = PyObject_GetAttr(o, trunc_name);
+    if (trunc_func) {
+        PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
+        PyObject *int_instance;
+        Py_DECREF(trunc_func);
+        /* __trunc__ is specified to return an Integral type,
+           but long() needs to return a long. */
+        int_instance = _PyNumber_ConvertIntegralToInt(
+            truncated,
+            "__trunc__ returned non-Integral (type %.200s)");
+        if (int_instance && PyInt_Check(int_instance)) {
+            /* Make sure that long() returns a long instance. */
+            long value = PyInt_AS_LONG(int_instance);
+            Py_DECREF(int_instance);
+            return PyLong_FromLong(value);
+        }
+        return int_instance;
+    }
+    PyErr_Clear();  /* It's not an error if  o.__trunc__ doesn't exist. */
+
+    if (PyString_Check(o))
+        /* need to do extra error checking that PyLong_FromString()
+         * doesn't do.  In particular long('9.5') must raise an
+         * exception, not truncate the float.
+         */
+        return long_from_string(PyString_AS_STRING(o),
+                                PyString_GET_SIZE(o));
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(o))
+        /* The above check is done in PyLong_FromUnicode(). */
+        return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
+                                  PyUnicode_GET_SIZE(o),
+                                  10);
+#endif
+    if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
+        return long_from_string(buffer, buffer_len);
+
+    return type_error("long() argument must be a string or a "
+                      "number, not '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Float(PyObject *o)
+{
+    PyNumberMethods *m;
+
+    if (o == NULL)
+        return null_error();
+    m = o->ob_type->tp_as_number;
+    if (m && m->nb_float) { /* This should include subclasses of float */
+        PyObject *res = m->nb_float(o);
+        if (res && !PyFloat_Check(res)) {
+            PyErr_Format(PyExc_TypeError,
+              "__float__ returned non-float (type %.200s)",
+              res->ob_type->tp_name);
+            Py_DECREF(res);
+            return NULL;
+        }
+        return res;
+    }
+    if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */
+        PyFloatObject *po = (PyFloatObject *)o;
+        return PyFloat_FromDouble(po->ob_fval);
+    }
+    return PyFloat_FromString(o, NULL);
+}
+
+PyObject *
+PyNumber_ToBase(PyObject *n, int base)
+{
+    PyObject *res = NULL;
+    PyObject *index = PyNumber_Index(n);
+
+    if (!index)
+        return NULL;
+    if (PyLong_Check(index))
+        res = _PyLong_Format(index, base, 0, 1);
+    else if (PyInt_Check(index))
+        res = _PyInt_Format((PyIntObject*)index, base, 1);
+    else
+        /* It should not be possible to get here, as
+           PyNumber_Index already has a check for the same
+           condition */
+        PyErr_SetString(PyExc_ValueError, "PyNumber_ToBase: index not "
+                        "int or long");
+    Py_DECREF(index);
+    return res;
+}
+
+
+/* Operations on sequences */
+
+int
+PySequence_Check(PyObject *s)
+{
+    if (s == NULL)
+        return 0;
+    if (PyInstance_Check(s))
+        return PyObject_HasAttrString(s, "__getitem__");
+    if (PyDict_Check(s))
+        return 0;
+    return  s->ob_type->tp_as_sequence &&
+        s->ob_type->tp_as_sequence->sq_item != NULL;
+}
+
+Py_ssize_t
+PySequence_Size(PyObject *s)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_length)
+        return m->sq_length(s);
+
+    type_error("object of type '%.200s' has no len()", s);
+    return -1;
+}
+
+#undef PySequence_Length
+Py_ssize_t
+PySequence_Length(PyObject *s)
+{
+    return PySequence_Size(s);
+}
+#define PySequence_Length PySequence_Size
+
+PyObject *
+PySequence_Concat(PyObject *s, PyObject *o)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL || o == NULL)
+        return null_error();
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_concat)
+        return m->sq_concat(s, o);
+
+    /* Instances of user classes defining an __add__() method only
+       have an nb_add slot, not an sq_concat slot.  So we fall back
+       to nb_add if both arguments appear to be sequences. */
+    if (PySequence_Check(s) && PySequence_Check(o)) {
+        PyObject *result = binary_op1(s, o, NB_SLOT(nb_add));
+        if (result != Py_NotImplemented)
+            return result;
+        Py_DECREF(result);
+    }
+    return type_error("'%.200s' object can't be concatenated", s);
+}
+
+PyObject *
+PySequence_Repeat(PyObject *o, Py_ssize_t count)
+{
+    PySequenceMethods *m;
+
+    if (o == NULL)
+        return null_error();
+
+    m = o->ob_type->tp_as_sequence;
+    if (m && m->sq_repeat)
+        return m->sq_repeat(o, count);
+
+    /* Instances of user classes defining a __mul__() method only
+       have an nb_multiply slot, not an sq_repeat slot. so we fall back
+       to nb_multiply if o appears to be a sequence. */
+    if (PySequence_Check(o)) {
+        PyObject *n, *result;
+        n = PyInt_FromSsize_t(count);
+        if (n == NULL)
+            return NULL;
+        result = binary_op1(o, n, NB_SLOT(nb_multiply));
+        Py_DECREF(n);
+        if (result != Py_NotImplemented)
+            return result;
+        Py_DECREF(result);
+    }
+    return type_error("'%.200s' object can't be repeated", o);
+}
+
+PyObject *
+PySequence_InPlaceConcat(PyObject *s, PyObject *o)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL || o == NULL)
+        return null_error();
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && HASINPLACE(s) && m->sq_inplace_concat)
+        return m->sq_inplace_concat(s, o);
+    if (m && m->sq_concat)
+        return m->sq_concat(s, o);
+
+    if (PySequence_Check(s) && PySequence_Check(o)) {
+        PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add),
+                                       NB_SLOT(nb_add));
+        if (result != Py_NotImplemented)
+            return result;
+        Py_DECREF(result);
+    }
+    return type_error("'%.200s' object can't be concatenated", s);
+}
+
+PyObject *
+PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
+{
+    PySequenceMethods *m;
+
+    if (o == NULL)
+        return null_error();
+
+    m = o->ob_type->tp_as_sequence;
+    if (m && HASINPLACE(o) && m->sq_inplace_repeat)
+        return m->sq_inplace_repeat(o, count);
+    if (m && m->sq_repeat)
+        return m->sq_repeat(o, count);
+
+    if (PySequence_Check(o)) {
+        PyObject *n, *result;
+        n = PyInt_FromSsize_t(count);
+        if (n == NULL)
+            return NULL;
+        result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply),
+                             NB_SLOT(nb_multiply));
+        Py_DECREF(n);
+        if (result != Py_NotImplemented)
+            return result;
+        Py_DECREF(result);
+    }
+    return type_error("'%.200s' object can't be repeated", o);
+}
+
+PyObject *
+PySequence_GetItem(PyObject *s, Py_ssize_t i)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL)
+        return null_error();
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_item) {
+        if (i < 0) {
+            if (m->sq_length) {
+                Py_ssize_t l = (*m->sq_length)(s);
+                if (l < 0)
+                    return NULL;
+                i += l;
+            }
+        }
+        return m->sq_item(s, i);
+    }
+
+    return type_error("'%.200s' object does not support indexing", s);
+}
+
+PyObject *
+PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
+{
+    PySequenceMethods *m;
+    PyMappingMethods *mp;
+
+    if (!s) return null_error();
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_slice) {
+        if (i1 < 0 || i2 < 0) {
+            if (m->sq_length) {
+                Py_ssize_t l = (*m->sq_length)(s);
+                if (l < 0)
+                    return NULL;
+                if (i1 < 0)
+                    i1 += l;
+                if (i2 < 0)
+                    i2 += l;
+            }
+        }
+        return m->sq_slice(s, i1, i2);
+    } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
+        PyObject *res;
+        PyObject *slice = _PySlice_FromIndices(i1, i2);
+        if (!slice)
+            return NULL;
+        res = mp->mp_subscript(s, slice);
+        Py_DECREF(slice);
+        return res;
+    }
+
+    return type_error("'%.200s' object is unsliceable", s);
+}
+
+int
+PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_ass_item) {
+        if (i < 0) {
+            if (m->sq_length) {
+                Py_ssize_t l = (*m->sq_length)(s);
+                if (l < 0)
+                    return -1;
+                i += l;
+            }
+        }
+        return m->sq_ass_item(s, i, o);
+    }
+
+    type_error("'%.200s' object does not support item assignment", s);
+    return -1;
+}
+
+int
+PySequence_DelItem(PyObject *s, Py_ssize_t i)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_ass_item) {
+        if (i < 0) {
+            if (m->sq_length) {
+                Py_ssize_t l = (*m->sq_length)(s);
+                if (l < 0)
+                    return -1;
+                i += l;
+            }
+        }
+        return m->sq_ass_item(s, i, (PyObject *)NULL);
+    }
+
+    type_error("'%.200s' object doesn't support item deletion", s);
+    return -1;
+}
+
+int
+PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
+{
+    PySequenceMethods *m;
+    PyMappingMethods *mp;
+
+    if (s == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_ass_slice) {
+        if (i1 < 0 || i2 < 0) {
+            if (m->sq_length) {
+                Py_ssize_t l = (*m->sq_length)(s);
+                if (l < 0)
+                    return -1;
+                if (i1 < 0)
+                    i1 += l;
+                if (i2 < 0)
+                    i2 += l;
+            }
+        }
+        return m->sq_ass_slice(s, i1, i2, o);
+    } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
+        int res;
+        PyObject *slice = _PySlice_FromIndices(i1, i2);
+        if (!slice)
+            return -1;
+        res = mp->mp_ass_subscript(s, slice, o);
+        Py_DECREF(slice);
+        return res;
+    }
+
+    type_error("'%.200s' object doesn't support slice assignment", s);
+    return -1;
+}
+
+int
+PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
+{
+    PySequenceMethods *m;
+
+    if (s == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = s->ob_type->tp_as_sequence;
+    if (m && m->sq_ass_slice) {
+        if (i1 < 0 || i2 < 0) {
+            if (m->sq_length) {
+                Py_ssize_t l = (*m->sq_length)(s);
+                if (l < 0)
+                    return -1;
+                if (i1 < 0)
+                    i1 += l;
+                if (i2 < 0)
+                    i2 += l;
+            }
+        }
+        return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
+    }
+    type_error("'%.200s' object doesn't support slice deletion", s);
+    return -1;
+}
+
+PyObject *
+PySequence_Tuple(PyObject *v)
+{
+    PyObject *it;  /* iter(v) */
+    Py_ssize_t n;         /* guess for result tuple size */
+    PyObject *result = NULL;
+    Py_ssize_t j;
+
+    if (v == NULL)
+        return null_error();
+
+    /* Special-case the common tuple and list cases, for efficiency. */
+    if (PyTuple_CheckExact(v)) {
+        /* Note that we can't know whether it's safe to return
+           a tuple *subclass* instance as-is, hence the restriction
+           to exact tuples here.  In contrast, lists always make
+           a copy, so there's no need for exactness below. */
+        Py_INCREF(v);
+        return v;
+    }
+    if (PyList_Check(v))
+        return PyList_AsTuple(v);
+
+    /* Get iterator. */
+    it = PyObject_GetIter(v);
+    if (it == NULL)
+        return NULL;
+
+    /* Guess result size and allocate space. */
+    n = _PyObject_LengthHint(v, 10);
+    if (n == -1)
+        goto Fail;
+    result = PyTuple_New(n);
+    if (result == NULL)
+        goto Fail;
+
+    /* Fill the tuple. */
+    for (j = 0; ; ++j) {
+        PyObject *item = PyIter_Next(it);
+        if (item == NULL) {
+            if (PyErr_Occurred())
+                goto Fail;
+            break;
+        }
+        if (j >= n) {
+            Py_ssize_t oldn = n;
+            /* The over-allocation strategy can grow a bit faster
+               than for lists because unlike lists the
+               over-allocation isn't permanent -- we reclaim
+               the excess before the end of this routine.
+               So, grow by ten and then add 25%.
+            */
+            n += 10;
+            n += n >> 2;
+            if (n < oldn) {
+                /* Check for overflow */
+                PyErr_NoMemory();
+                Py_DECREF(item);
+                goto Fail;
+            }
+            if (_PyTuple_Resize(&result, n) != 0) {
+                Py_DECREF(item);
+                goto Fail;
+            }
+        }
+        PyTuple_SET_ITEM(result, j, item);
+    }
+
+    /* Cut tuple back if guess was too large. */
+    if (j < n &&
+        _PyTuple_Resize(&result, j) != 0)
+        goto Fail;
+
+    Py_DECREF(it);
+    return result;
+
+Fail:
+    Py_XDECREF(result);
+    Py_DECREF(it);
+    return NULL;
+}
+
+PyObject *
+PySequence_List(PyObject *v)
+{
+    PyObject *result;  /* result list */
+    PyObject *rv;      /* return value from PyList_Extend */
+
+    if (v == NULL)
+        return null_error();
+
+    result = PyList_New(0);
+    if (result == NULL)
+        return NULL;
+
+    rv = _PyList_Extend((PyListObject *)result, v);
+    if (rv == NULL) {
+        Py_DECREF(result);
+        return NULL;
+    }
+    Py_DECREF(rv);
+    return result;
+}
+
+PyObject *
+PySequence_Fast(PyObject *v, const char *m)
+{
+    PyObject *it;
+
+    if (v == NULL)
+        return null_error();
+
+    if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) {
+        Py_INCREF(v);
+        return v;
+    }
+
+    it = PyObject_GetIter(v);
+    if (it == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_TypeError))
+            PyErr_SetString(PyExc_TypeError, m);
+        return NULL;
+    }
+
+    v = PySequence_List(it);
+    Py_DECREF(it);
+
+    return v;
+}
+
+/* Iterate over seq.  Result depends on the operation:
+   PY_ITERSEARCH_COUNT:  -1 if error, else # of times obj appears in seq.
+   PY_ITERSEARCH_INDEX:  0-based index of first occurrence of obj in seq;
+    set ValueError and return -1 if none found; also return -1 on error.
+   Py_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on error.
+*/
+Py_ssize_t
+_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
+{
+    Py_ssize_t n;
+    int wrapped;  /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */
+    PyObject *it;  /* iter(seq) */
+
+    if (seq == NULL || obj == NULL) {
+        null_error();
+        return -1;
+    }
+
+    it = PyObject_GetIter(seq);
+    if (it == NULL) {
+        type_error("argument of type '%.200s' is not iterable", seq);
+        return -1;
+    }
+
+    n = wrapped = 0;
+    for (;;) {
+        int cmp;
+        PyObject *item = PyIter_Next(it);
+        if (item == NULL) {
+            if (PyErr_Occurred())
+                goto Fail;
+            break;
+        }
+
+        cmp = PyObject_RichCompareBool(obj, item, Py_EQ);
+        Py_DECREF(item);
+        if (cmp < 0)
+            goto Fail;
+        if (cmp > 0) {
+            switch (operation) {
+            case PY_ITERSEARCH_COUNT:
+                if (n == PY_SSIZE_T_MAX) {
+                    PyErr_SetString(PyExc_OverflowError,
+                           "count exceeds C integer size");
+                    goto Fail;
+                }
+                ++n;
+                break;
+
+            case PY_ITERSEARCH_INDEX:
+                if (wrapped) {
+                    PyErr_SetString(PyExc_OverflowError,
+                           "index exceeds C integer size");
+                    goto Fail;
+                }
+                goto Done;
+
+            case PY_ITERSEARCH_CONTAINS:
+                n = 1;
+                goto Done;
+
+            default:
+                assert(!"unknown operation");
+            }
+        }
+
+        if (operation == PY_ITERSEARCH_INDEX) {
+            if (n == PY_SSIZE_T_MAX)
+                wrapped = 1;
+            ++n;
+        }
+    }
+
+    if (operation != PY_ITERSEARCH_INDEX)
+        goto Done;
+
+    PyErr_SetString(PyExc_ValueError,
+                    "sequence.index(x): x not in sequence");
+    /* fall into failure code */
+Fail:
+    n = -1;
+    /* fall through */
+Done:
+    Py_DECREF(it);
+    return n;
+
+}
+
+/* Return # of times o appears in s. */
+Py_ssize_t
+PySequence_Count(PyObject *s, PyObject *o)
+{
+    return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT);
+}
+
+/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq.
+ * Use sq_contains if possible, else defer to _PySequence_IterSearch().
+ */
+int
+PySequence_Contains(PyObject *seq, PyObject *ob)
+{
+    Py_ssize_t result;
+    if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
+        PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
+        if (sqm != NULL && sqm->sq_contains != NULL)
+            return (*sqm->sq_contains)(seq, ob);
+    }
+    result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
+    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+/* Backwards compatibility */
+#undef PySequence_In
+int
+PySequence_In(PyObject *w, PyObject *v)
+{
+    return PySequence_Contains(w, v);
+}
+
+Py_ssize_t
+PySequence_Index(PyObject *s, PyObject *o)
+{
+    return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX);
+}
+
+/* Operations on mappings */
+
+int
+PyMapping_Check(PyObject *o)
+{
+    if (o && PyInstance_Check(o))
+        return PyObject_HasAttrString(o, "__getitem__");
+
+    return  o && o->ob_type->tp_as_mapping &&
+        o->ob_type->tp_as_mapping->mp_subscript &&
+        !(o->ob_type->tp_as_sequence &&
+          o->ob_type->tp_as_sequence->sq_slice);
+}
+
+Py_ssize_t
+PyMapping_Size(PyObject *o)
+{
+    PyMappingMethods *m;
+
+    if (o == NULL) {
+        null_error();
+        return -1;
+    }
+
+    m = o->ob_type->tp_as_mapping;
+    if (m && m->mp_length)
+        return m->mp_length(o);
+
+    type_error("object of type '%.200s' has no len()", o);
+    return -1;
+}
+
+#undef PyMapping_Length
+Py_ssize_t
+PyMapping_Length(PyObject *o)
+{
+    return PyMapping_Size(o);
+}
+#define PyMapping_Length PyMapping_Size
+
+PyObject *
+PyMapping_GetItemString(PyObject *o, char *key)
+{
+    PyObject *okey, *r;
+
+    if (key == NULL)
+        return null_error();
+
+    okey = PyString_FromString(key);
+    if (okey == NULL)
+        return NULL;
+    r = PyObject_GetItem(o, okey);
+    Py_DECREF(okey);
+    return r;
+}
+
+int
+PyMapping_SetItemString(PyObject *o, char *key, PyObject *value)
+{
+    PyObject *okey;
+    int r;
+
+    if (key == NULL) {
+        null_error();
+        return -1;
+    }
+
+    okey = PyString_FromString(key);
+    if (okey == NULL)
+        return -1;
+    r = PyObject_SetItem(o, okey, value);
+    Py_DECREF(okey);
+    return r;
+}
+
+int
+PyMapping_HasKeyString(PyObject *o, char *key)
+{
+    PyObject *v;
+
+    v = PyMapping_GetItemString(o, key);
+    if (v) {
+        Py_DECREF(v);
+        return 1;
+    }
+    PyErr_Clear();
+    return 0;
+}
+
+int
+PyMapping_HasKey(PyObject *o, PyObject *key)
+{
+    PyObject *v;
+
+    v = PyObject_GetItem(o, key);
+    if (v) {
+        Py_DECREF(v);
+        return 1;
+    }
+    PyErr_Clear();
+    return 0;
+}
+
+/* Operations on callable objects */
+
+/* XXX PyCallable_Check() is in object.c */
+
+PyObject *
+PyObject_CallObject(PyObject *o, PyObject *a)
+{
+    return PyEval_CallObjectWithKeywords(o, a, NULL);
+}
+
+PyObject *
+PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+    ternaryfunc call;
+
+    if ((call = func->ob_type->tp_call) != NULL) {
+        PyObject *result;
+        if (Py_EnterRecursiveCall(" while calling a Python object"))
+            return NULL;
+        result = (*call)(func, arg, kw);
+        Py_LeaveRecursiveCall();
+        if (result == NULL && !PyErr_Occurred())
+            PyErr_SetString(
+                PyExc_SystemError,
+                "NULL result without error in PyObject_Call");
+        return result;
+    }
+    PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
+                 func->ob_type->tp_name);
+    return NULL;
+}
+
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+    PyObject *retval;
+
+    if (args == NULL)
+        return NULL;
+
+    if (!PyTuple_Check(args)) {
+        PyObject *a;
+
+        a = PyTuple_New(1);
+        if (a == NULL) {
+            Py_DECREF(args);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(a, 0, args);
+        args = a;
+    }
+    retval = PyObject_Call(callable, args, NULL);
+
+    Py_DECREF(args);
+
+    return retval;
+}
+
+PyObject *
+PyObject_CallFunction(PyObject *callable, char *format, ...)
+{
+    va_list va;
+    PyObject *args;
+
+    if (callable == NULL)
+        return null_error();
+
+    if (format && *format) {
+        va_start(va, format);
+        args = Py_VaBuildValue(format, va);
+        va_end(va);
+    }
+    else
+        args = PyTuple_New(0);
+
+    return call_function_tail(callable, args);
+}
+
+PyObject *
+_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
+{
+    va_list va;
+    PyObject *args;
+
+    if (callable == NULL)
+        return null_error();
+
+    if (format && *format) {
+        va_start(va, format);
+        args = _Py_VaBuildValue_SizeT(format, va);
+        va_end(va);
+    }
+    else
+        args = PyTuple_New(0);
+
+    return call_function_tail(callable, args);
+}
+
+PyObject *
+PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+{
+    va_list va;
+    PyObject *args;
+    PyObject *func = NULL;
+    PyObject *retval = NULL;
+
+    if (o == NULL || name == NULL)
+        return null_error();
+
+    func = PyObject_GetAttrString(o, name);
+    if (func == NULL) {
+        PyErr_SetString(PyExc_AttributeError, name);
+        return 0;
+    }
+
+    if (!PyCallable_Check(func)) {
+        type_error("attribute of type '%.200s' is not callable", func);
+        goto exit;
+    }
+
+    if (format && *format) {
+        va_start(va, format);
+        args = Py_VaBuildValue(format, va);
+        va_end(va);
+    }
+    else
+        args = PyTuple_New(0);
+
+    retval = call_function_tail(func, args);
+
+  exit:
+    /* args gets consumed in call_function_tail */
+    Py_XDECREF(func);
+
+    return retval;
+}
+
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+    va_list va;
+    PyObject *args;
+    PyObject *func = NULL;
+    PyObject *retval = NULL;
+
+    if (o == NULL || name == NULL)
+        return null_error();
+
+    func = PyObject_GetAttrString(o, name);
+    if (func == NULL) {
+        PyErr_SetString(PyExc_AttributeError, name);
+        return 0;
+    }
+
+    if (!PyCallable_Check(func)) {
+        type_error("attribute of type '%.200s' is not callable", func);
+        goto exit;
+    }
+
+    if (format && *format) {
+        va_start(va, format);
+        args = _Py_VaBuildValue_SizeT(format, va);
+        va_end(va);
+    }
+    else
+        args = PyTuple_New(0);
+
+    retval = call_function_tail(func, args);
+
+  exit:
+    /* args gets consumed in call_function_tail */
+    Py_XDECREF(func);
+
+    return retval;
+}
+
+
+static PyObject *
+objargs_mktuple(va_list va)
+{
+    int i, n = 0;
+    va_list countva;
+    PyObject *result, *tmp;
+
+#ifdef VA_LIST_IS_ARRAY
+    memcpy(countva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+    __va_copy(countva, va);
+#else
+    countva = va;
+#endif
+#endif
+
+    while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
+        ++n;
+    result = PyTuple_New(n);
+    if (result != NULL && n > 0) {
+        for (i = 0; i < n; ++i) {
+            tmp = (PyObject *)va_arg(va, PyObject *);
+            PyTuple_SET_ITEM(result, i, tmp);
+            Py_INCREF(tmp);
+        }
+    }
+    return result;
+}
+
+PyObject *
+PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
+{
+    PyObject *args, *tmp;
+    va_list vargs;
+
+    if (callable == NULL || name == NULL)
+        return null_error();
+
+    callable = PyObject_GetAttr(callable, name);
+    if (callable == NULL)
+        return NULL;
+
+    /* count the args */
+    va_start(vargs, name);
+    args = objargs_mktuple(vargs);
+    va_end(vargs);
+    if (args == NULL) {
+        Py_DECREF(callable);
+        return NULL;
+    }
+    tmp = PyObject_Call(callable, args, NULL);
+    Py_DECREF(args);
+    Py_DECREF(callable);
+
+    return tmp;
+}
+
+PyObject *
+PyObject_CallFunctionObjArgs(PyObject *callable, ...)
+{
+    PyObject *args, *tmp;
+    va_list vargs;
+
+    if (callable == NULL)
+        return null_error();
+
+    /* count the args */
+    va_start(vargs, callable);
+    args = objargs_mktuple(vargs);
+    va_end(vargs);
+    if (args == NULL)
+        return NULL;
+    tmp = PyObject_Call(callable, args, NULL);
+    Py_DECREF(args);
+
+    return tmp;
+}
+
+
+/* isinstance(), issubclass() */
+
+/* abstract_get_bases() has logically 4 return states, with a sort of 0th
+ * state that will almost never happen.
+ *
+ * 0. creating the __bases__ static string could get a MemoryError
+ * 1. getattr(cls, '__bases__') could raise an AttributeError
+ * 2. getattr(cls, '__bases__') could raise some other exception
+ * 3. getattr(cls, '__bases__') could return a tuple
+ * 4. getattr(cls, '__bases__') could return something other than a tuple
+ *
+ * Only state #3 is a non-error state and only it returns a non-NULL object
+ * (it returns the retrieved tuple).
+ *
+ * Any raised AttributeErrors are masked by clearing the exception and
+ * returning NULL.  If an object other than a tuple comes out of __bases__,
+ * then again, the return value is NULL.  So yes, these two situations
+ * produce exactly the same results: NULL is returned and no error is set.
+ *
+ * If some exception other than AttributeError is raised, then NULL is also
+ * returned, but the exception is not cleared.  That's because we want the
+ * exception to be propagated along.
+ *
+ * Callers are expected to test for PyErr_Occurred() when the return value
+ * is NULL to decide whether a valid exception should be propagated or not.
+ * When there's no exception to propagate, it's customary for the caller to
+ * set a TypeError.
+ */
+static PyObject *
+abstract_get_bases(PyObject *cls)
+{
+    static PyObject *__bases__ = NULL;
+    PyObject *bases;
+
+    if (__bases__ == NULL) {
+        __bases__ = PyString_InternFromString("__bases__");
+        if (__bases__ == NULL)
+            return NULL;
+    }
+    bases = PyObject_GetAttr(cls, __bases__);
+    if (bases == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Clear();
+        return NULL;
+    }
+    if (!PyTuple_Check(bases)) {
+        Py_DECREF(bases);
+        return NULL;
+    }
+    return bases;
+}
+
+
+static int
+abstract_issubclass(PyObject *derived, PyObject *cls)
+{
+    PyObject *bases = NULL;
+    Py_ssize_t i, n;
+    int r = 0;
+
+    while (1) {
+        if (derived == cls)
+            return 1;
+        bases = abstract_get_bases(derived);
+        if (bases == NULL) {
+            if (PyErr_Occurred())
+                return -1;
+            return 0;
+        }
+        n = PyTuple_GET_SIZE(bases);
+        if (n == 0) {
+            Py_DECREF(bases);
+            return 0;
+        }
+        /* Avoid recursivity in the single inheritance case */
+        if (n == 1) {
+            derived = PyTuple_GET_ITEM(bases, 0);
+            Py_DECREF(bases);
+            continue;
+        }
+        for (i = 0; i < n; i++) {
+            r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
+            if (r != 0)
+                break;
+        }
+        Py_DECREF(bases);
+        return r;
+    }
+}
+
+static int
+check_class(PyObject *cls, const char *error)
+{
+    PyObject *bases = abstract_get_bases(cls);
+    if (bases == NULL) {
+        /* Do not mask errors. */
+        if (!PyErr_Occurred())
+            PyErr_SetString(PyExc_TypeError, error);
+        return 0;
+    }
+    Py_DECREF(bases);
+    return -1;
+}
+
+static int
+recursive_isinstance(PyObject *inst, PyObject *cls)
+{
+    PyObject *icls;
+    static PyObject *__class__ = NULL;
+    int retval = 0;
+
+    if (__class__ == NULL) {
+        __class__ = PyString_InternFromString("__class__");
+        if (__class__ == NULL)
+            return -1;
+    }
+
+    if (PyClass_Check(cls) && PyInstance_Check(inst)) {
+        PyObject *inclass =
+            (PyObject*)((PyInstanceObject*)inst)->in_class;
+        retval = PyClass_IsSubclass(inclass, cls);
+    }
+    else if (PyType_Check(cls)) {
+        retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
+        if (retval == 0) {
+            PyObject *c = PyObject_GetAttr(inst, __class__);
+            if (c == NULL) {
+                PyErr_Clear();
+            }
+            else {
+                if (c != (PyObject *)(inst->ob_type) &&
+                    PyType_Check(c))
+                    retval = PyType_IsSubtype(
+                        (PyTypeObject *)c,
+                        (PyTypeObject *)cls);
+                Py_DECREF(c);
+            }
+        }
+    }
+    else {
+        if (!check_class(cls,
+            "isinstance() arg 2 must be a class, type,"
+            " or tuple of classes and types"))
+            return -1;
+        icls = PyObject_GetAttr(inst, __class__);
+        if (icls == NULL) {
+            PyErr_Clear();
+            retval = 0;
+        }
+        else {
+            retval = abstract_issubclass(icls, cls);
+            Py_DECREF(icls);
+        }
+    }
+
+    return retval;
+}
+
+int
+PyObject_IsInstance(PyObject *inst, PyObject *cls)
+{
+    static PyObject *name = NULL;
+
+    /* Quick test for an exact match */
+    if (Py_TYPE(inst) == (PyTypeObject *)cls)
+        return 1;
+
+    if (PyTuple_Check(cls)) {
+        Py_ssize_t i;
+        Py_ssize_t n;
+        int r = 0;
+
+        if (Py_EnterRecursiveCall(" in __instancecheck__"))
+            return -1;
+        n = PyTuple_GET_SIZE(cls);
+        for (i = 0; i < n; ++i) {
+            PyObject *item = PyTuple_GET_ITEM(cls, i);
+            r = PyObject_IsInstance(inst, item);
+            if (r != 0)
+                /* either found it, or got an error */
+                break;
+        }
+        Py_LeaveRecursiveCall();
+        return r;
+    }
+
+    if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
+        PyObject *checker;
+        checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name);
+        if (checker != NULL) {
+            PyObject *res;
+            int ok = -1;
+            if (Py_EnterRecursiveCall(" in __instancecheck__")) {
+                Py_DECREF(checker);
+                return ok;
+            }
+            res = PyObject_CallFunctionObjArgs(checker, inst, NULL);
+            Py_LeaveRecursiveCall();
+            Py_DECREF(checker);
+            if (res != NULL) {
+                ok = PyObject_IsTrue(res);
+                Py_DECREF(res);
+            }
+            return ok;
+        }
+        else if (PyErr_Occurred())
+            return -1;
+    }
+    return recursive_isinstance(inst, cls);
+}
+
+static  int
+recursive_issubclass(PyObject *derived, PyObject *cls)
+{
+    int retval;
+
+    if (PyType_Check(cls) && PyType_Check(derived)) {
+        /* Fast path (non-recursive) */
+        return PyType_IsSubtype(
+            (PyTypeObject *)derived, (PyTypeObject *)cls);
+    }
+    if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
+        if (!check_class(derived,
+                         "issubclass() arg 1 must be a class"))
+            return -1;
+
+        if (!check_class(cls,
+                        "issubclass() arg 2 must be a class"
+                        " or tuple of classes"))
+            return -1;
+        retval = abstract_issubclass(derived, cls);
+    }
+    else {
+        /* shortcut */
+        if (!(retval = (derived == cls)))
+            retval = PyClass_IsSubclass(derived, cls);
+    }
+
+    return retval;
+}
+
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+    static PyObject *name = NULL;
+
+    if (PyTuple_Check(cls)) {
+        Py_ssize_t i;
+        Py_ssize_t n;
+        int r = 0;
+
+        if (Py_EnterRecursiveCall(" in __subclasscheck__"))
+            return -1;
+        n = PyTuple_GET_SIZE(cls);
+        for (i = 0; i < n; ++i) {
+            PyObject *item = PyTuple_GET_ITEM(cls, i);
+            r = PyObject_IsSubclass(derived, item);
+            if (r != 0)
+                /* either found it, or got an error */
+                break;
+        }
+        Py_LeaveRecursiveCall();
+        return r;
+    }
+    if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
+        PyObject *checker;
+        checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
+        if (checker != NULL) {
+            PyObject *res;
+            int ok = -1;
+            if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
+                Py_DECREF(checker);
+                return ok;
+            }
+            res = PyObject_CallFunctionObjArgs(checker, derived, NULL);
+            Py_LeaveRecursiveCall();
+            Py_DECREF(checker);
+            if (res != NULL) {
+                ok = PyObject_IsTrue(res);
+                Py_DECREF(res);
+            }
+            return ok;
+        }
+        else if (PyErr_Occurred()) {
+            return -1;
+        }
+    }
+    return recursive_issubclass(derived, cls);
+}
+
+int
+_PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
+{
+    return recursive_isinstance(inst, cls);
+}
+
+int
+_PyObject_RealIsSubclass(PyObject *derived, PyObject *cls)
+{
+    return recursive_issubclass(derived, cls);
+}
+
+
+PyObject *
+PyObject_GetIter(PyObject *o)
+{
+    PyTypeObject *t = o->ob_type;
+    getiterfunc f = NULL;
+    if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
+        f = t->tp_iter;
+    if (f == NULL) {
+        if (PySequence_Check(o))
+            return PySeqIter_New(o);
+        return type_error("'%.200s' object is not iterable", o);
+    }
+    else {
+        PyObject *res = (*f)(o);
+        if (res != NULL && !PyIter_Check(res)) {
+            PyErr_Format(PyExc_TypeError,
+                         "iter() returned non-iterator "
+                         "of type '%.100s'",
+                         res->ob_type->tp_name);
+            Py_DECREF(res);
+            res = NULL;
+        }
+        return res;
+    }
+}
+
+/* Return next item.
+ * If an error occurs, return NULL.  PyErr_Occurred() will be true.
+ * If the iteration terminates normally, return NULL and clear the
+ * PyExc_StopIteration exception (if it was set).  PyErr_Occurred()
+ * will be false.
+ * Else return the next object.  PyErr_Occurred() will be false.
+ */
+PyObject *
+PyIter_Next(PyObject *iter)
+{
+    PyObject *result;
+    result = (*iter->ob_type->tp_iternext)(iter);
+    if (result == NULL &&
+        PyErr_Occurred() &&
+        PyErr_ExceptionMatches(PyExc_StopIteration))
+        PyErr_Clear();
+    return result;
+}
diff --git a/Python-2.7.5/Objects/boolobject.c b/Python-2.7.5/Objects/boolobject.c
new file mode 100644
index 0000000..595832a
--- /dev/null
+++ b/Python-2.7.5/Objects/boolobject.c
@@ -0,0 +1,202 @@
+/* Boolean type, a subtype of int */
+
+#include "Python.h"
+
+/* We need to define bool_print to override int_print */
+
+static int
+bool_print(PyBoolObject *self, FILE *fp, int flags)
+{
+    Py_BEGIN_ALLOW_THREADS
+    fputs(self->ob_ival == 0 ? "False" : "True", fp);
+    Py_END_ALLOW_THREADS
+    return 0;
+}
+
+/* We define bool_repr to return "False" or "True" */
+
+static PyObject *false_str = NULL;
+static PyObject *true_str = NULL;
+
+static PyObject *
+bool_repr(PyBoolObject *self)
+{
+    PyObject *s;
+
+    if (self->ob_ival)
+        s = true_str ? true_str :
+            (true_str = PyString_InternFromString("True"));
+    else
+        s = false_str ? false_str :
+            (false_str = PyString_InternFromString("False"));
+    Py_XINCREF(s);
+    return s;
+}
+
+/* Function to return a bool from a C long */
+
+PyObject *PyBool_FromLong(long ok)
+{
+    PyObject *result;
+
+    if (ok)
+        result = Py_True;
+    else
+        result = Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
+/* We define bool_new to always return either Py_True or Py_False */
+
+static PyObject *
+bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"x", 0};
+    PyObject *x = Py_False;
+    long ok;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
+        return NULL;
+    ok = PyObject_IsTrue(x);
+    if (ok < 0)
+        return NULL;
+    return PyBool_FromLong(ok);
+}
+
+/* Arithmetic operations redefined to return bool if both args are bool. */
+
+static PyObject *
+bool_and(PyObject *a, PyObject *b)
+{
+    if (!PyBool_Check(a) || !PyBool_Check(b))
+        return PyInt_Type.tp_as_number->nb_and(a, b);
+    return PyBool_FromLong(
+        ((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival);
+}
+
+static PyObject *
+bool_or(PyObject *a, PyObject *b)
+{
+    if (!PyBool_Check(a) || !PyBool_Check(b))
+        return PyInt_Type.tp_as_number->nb_or(a, b);
+    return PyBool_FromLong(
+        ((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival);
+}
+
+static PyObject *
+bool_xor(PyObject *a, PyObject *b)
+{
+    if (!PyBool_Check(a) || !PyBool_Check(b))
+        return PyInt_Type.tp_as_number->nb_xor(a, b);
+    return PyBool_FromLong(
+        ((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival);
+}
+
+/* Doc string */
+
+PyDoc_STRVAR(bool_doc,
+"bool(x) -> bool\n\
+\n\
+Returns True when the argument x is true, False otherwise.\n\
+The builtins True and False are the only two instances of the class bool.\n\
+The class bool is a subclass of the class int, and cannot be subclassed.");
+
+/* Arithmetic methods -- only so we can override &, |, ^. */
+
+static PyNumberMethods bool_as_number = {
+    0,                          /* nb_add */
+    0,                          /* nb_subtract */
+    0,                          /* nb_multiply */
+    0,                          /* nb_divide */
+    0,                          /* nb_remainder */
+    0,                          /* nb_divmod */
+    0,                          /* nb_power */
+    0,                          /* nb_negative */
+    0,                          /* nb_positive */
+    0,                          /* nb_absolute */
+    0,                          /* nb_nonzero */
+    0,                          /* nb_invert */
+    0,                          /* nb_lshift */
+    0,                          /* nb_rshift */
+    bool_and,                   /* nb_and */
+    bool_xor,                   /* nb_xor */
+    bool_or,                    /* nb_or */
+    0,                          /* nb_coerce */
+    0,                          /* nb_int */
+    0,                          /* nb_long */
+    0,                          /* nb_float */
+    0,                          /* nb_oct */
+    0,                          /* nb_hex */
+    0,                          /* nb_inplace_add */
+    0,                          /* nb_inplace_subtract */
+    0,                          /* nb_inplace_multiply */
+    0,                          /* nb_inplace_divide */
+    0,                          /* nb_inplace_remainder */
+    0,                          /* nb_inplace_power */
+    0,                          /* nb_inplace_lshift */
+    0,                          /* nb_inplace_rshift */
+    0,                          /* nb_inplace_and */
+    0,                          /* nb_inplace_xor */
+    0,                          /* nb_inplace_or */
+    0,                          /* nb_floor_divide */
+    0,                          /* nb_true_divide */
+    0,                          /* nb_inplace_floor_divide */
+    0,                          /* nb_inplace_true_divide */
+};
+
+/* The type object for bool.  Note that this cannot be subclassed! */
+
+PyTypeObject PyBool_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "bool",
+    sizeof(PyIntObject),
+    0,
+    0,                                          /* tp_dealloc */
+    (printfunc)bool_print,                      /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)bool_repr,                        /* tp_repr */
+    &bool_as_number,                            /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    (reprfunc)bool_repr,                        /* tp_str */
+    0,                                          /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+    bool_doc,                                   /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    &PyInt_Type,                                /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    bool_new,                                   /* tp_new */
+};
+
+/* The objects representing bool values False and True */
+
+/* Named Zero for link-level compatibility */
+PyIntObject _Py_ZeroStruct = {
+    PyObject_HEAD_INIT(&PyBool_Type)
+    0
+};
+
+PyIntObject _Py_TrueStruct = {
+    PyObject_HEAD_INIT(&PyBool_Type)
+    1
+};
diff --git a/Python-2.7.5/Objects/bufferobject.c b/Python-2.7.5/Objects/bufferobject.c
new file mode 100644
index 0000000..23b97b2
--- /dev/null
+++ b/Python-2.7.5/Objects/bufferobject.c
@@ -0,0 +1,878 @@
+
+/* Buffer object implementation */
+
+#include "Python.h"
+
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *b_base;
+    void *b_ptr;
+    Py_ssize_t b_size;
+    Py_ssize_t b_offset;
+    int b_readonly;
+    long b_hash;
+} PyBufferObject;
+
+
+enum buffer_t {
+    READ_BUFFER,
+    WRITE_BUFFER,
+    CHAR_BUFFER,
+    ANY_BUFFER
+};
+
+static int
+get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
+    enum buffer_t buffer_type)
+{
+    if (self->b_base == NULL) {
+        assert (ptr != NULL);
+        *ptr = self->b_ptr;
+        *size = self->b_size;
+    }
+    else {
+        Py_ssize_t count, offset;
+        readbufferproc proc = 0;
+        PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
+        if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
+            PyErr_SetString(PyExc_TypeError,
+                "single-segment buffer object expected");
+            return 0;
+        }
+        if ((buffer_type == READ_BUFFER) ||
+            ((buffer_type == ANY_BUFFER) && self->b_readonly))
+            proc = bp->bf_getreadbuffer;
+        else if ((buffer_type == WRITE_BUFFER) ||
+            (buffer_type == ANY_BUFFER))
+            proc = (readbufferproc)bp->bf_getwritebuffer;
+        else if (buffer_type == CHAR_BUFFER) {
+            if (!PyType_HasFeature(self->ob_type,
+                        Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
+            PyErr_SetString(PyExc_TypeError,
+                "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
+            return 0;
+            }
+            proc = (readbufferproc)bp->bf_getcharbuffer;
+        }
+        if (!proc) {
+            char *buffer_type_name;
+            switch (buffer_type) {
+            case READ_BUFFER:
+                buffer_type_name = "read";
+                break;
+            case WRITE_BUFFER:
+                buffer_type_name = "write";
+                break;
+            case CHAR_BUFFER:
+                buffer_type_name = "char";
+                break;
+            default:
+                buffer_type_name = "no";
+                break;
+            }
+            PyErr_Format(PyExc_TypeError,
+                "%s buffer type not available",
+                buffer_type_name);
+            return 0;
+        }
+        if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
+            return 0;
+        /* apply constraints to the start/end */
+        if (self->b_offset > count)
+            offset = count;
+        else
+            offset = self->b_offset;
+        *(char **)ptr = *(char **)ptr + offset;
+        if (self->b_size == Py_END_OF_BUFFER)
+            *size = count;
+        else
+            *size = self->b_size;
+        if (offset + *size > count)
+            *size = count - offset;
+    }
+    return 1;
+}
+
+
+static PyObject *
+buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
+                   int readonly)
+{
+    PyBufferObject * b;
+
+    if (size < 0 && size != Py_END_OF_BUFFER) {
+        PyErr_SetString(PyExc_ValueError,
+                        "size must be zero or positive");
+        return NULL;
+    }
+    if (offset < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "offset must be zero or positive");
+        return NULL;
+    }
+
+    b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
+    if ( b == NULL )
+        return NULL;
+
+    Py_XINCREF(base);
+    b->b_base = base;
+    b->b_ptr = ptr;
+    b->b_size = size;
+    b->b_offset = offset;
+    b->b_readonly = readonly;
+    b->b_hash = -1;
+
+    return (PyObject *) b;
+}
+
+static PyObject *
+buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
+{
+    if (offset < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "offset must be zero or positive");
+        return NULL;
+    }
+    if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
+        /* another buffer, refer to the base object */
+        PyBufferObject *b = (PyBufferObject *)base;
+        if (b->b_size != Py_END_OF_BUFFER) {
+            Py_ssize_t base_size = b->b_size - offset;
+            if (base_size < 0)
+                base_size = 0;
+            if (size == Py_END_OF_BUFFER || size > base_size)
+                size = base_size;
+        }
+        offset += b->b_offset;
+        base = b->b_base;
+    }
+    return buffer_from_memory(base, size, offset, NULL, readonly);
+}
+
+
+PyObject *
+PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+{
+    PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+
+    if ( pb == NULL ||
+         pb->bf_getreadbuffer == NULL ||
+         pb->bf_getsegcount == NULL )
+    {
+        PyErr_SetString(PyExc_TypeError, "buffer object expected");
+        return NULL;
+    }
+
+    return buffer_from_object(base, size, offset, 1);
+}
+
+PyObject *
+PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+{
+    PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+
+    if ( pb == NULL ||
+         pb->bf_getwritebuffer == NULL ||
+         pb->bf_getsegcount == NULL )
+    {
+        PyErr_SetString(PyExc_TypeError, "buffer object expected");
+        return NULL;
+    }
+
+    return buffer_from_object(base, size,  offset, 0);
+}
+
+PyObject *
+PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
+{
+    return buffer_from_memory(NULL, size, 0, ptr, 1);
+}
+
+PyObject *
+PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
+{
+    return buffer_from_memory(NULL, size, 0, ptr, 0);
+}
+
+PyObject *
+PyBuffer_New(Py_ssize_t size)
+{
+    PyObject *o;
+    PyBufferObject * b;
+
+    if (size < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "size must be zero or positive");
+        return NULL;
+    }
+    if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
+        /* unlikely */
+        return PyErr_NoMemory();
+    }
+    /* Inline PyObject_New */
+    o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
+    if ( o == NULL )
+        return PyErr_NoMemory();
+    b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
+
+    b->b_base = NULL;
+    b->b_ptr = (void *)(b + 1);
+    b->b_size = size;
+    b->b_offset = 0;
+    b->b_readonly = 0;
+    b->b_hash = -1;
+
+    return o;
+}
+
+/* Methods */
+
+static PyObject *
+buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+    PyObject *ob;
+    Py_ssize_t offset = 0;
+    Py_ssize_t size = Py_END_OF_BUFFER;
+
+    if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
+        return NULL;
+
+    if (!_PyArg_NoKeywords("buffer()", kw))
+        return NULL;
+
+    if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
+        return NULL;
+    return PyBuffer_FromObject(ob, offset, size);
+}
+
+PyDoc_STRVAR(buffer_doc,
+"buffer(object [, offset[, size]])\n\
+\n\
+Create a new buffer object which references the given object.\n\
+The buffer will reference a slice of the target object from the\n\
+start of the object (or at the specified offset). The slice will\n\
+extend to the end of the target object (or with the specified size).");
+
+
+static void
+buffer_dealloc(PyBufferObject *self)
+{
+    Py_XDECREF(self->b_base);
+    PyObject_DEL(self);
+}
+
+static int
+buffer_compare(PyBufferObject *self, PyBufferObject *other)
+{
+    void *p1, *p2;
+    Py_ssize_t len_self, len_other, min_len;
+    int cmp;
+
+    if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
+        return -1;
+    if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
+        return -1;
+    min_len = (len_self < len_other) ? len_self : len_other;
+    if (min_len > 0) {
+        cmp = memcmp(p1, p2, min_len);
+        if (cmp != 0)
+            return cmp < 0 ? -1 : 1;
+    }
+    return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
+}
+
+static PyObject *
+buffer_repr(PyBufferObject *self)
+{
+    const char *status = self->b_readonly ? "read-only" : "read-write";
+
+    if ( self->b_base == NULL )
+        return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
+                                   status,
+                                   self->b_ptr,
+                                   self->b_size,
+                                   self);
+    else
+        return PyString_FromFormat(
+            "<%s buffer for %p, size %zd, offset %zd at %p>",
+            status,
+            self->b_base,
+            self->b_size,
+            self->b_offset,
+            self);
+}
+
+static long
+buffer_hash(PyBufferObject *self)
+{
+    void *ptr;
+    Py_ssize_t size;
+    register Py_ssize_t len;
+    register unsigned char *p;
+    register long x;
+
+    if ( self->b_hash != -1 )
+        return self->b_hash;
+
+    /* XXX potential bugs here, a readonly buffer does not imply that the
+     * underlying memory is immutable.  b_readonly is a necessary but not
+     * sufficient condition for a buffer to be hashable.  Perhaps it would
+     * be better to only allow hashing if the underlying object is known to
+     * be immutable (e.g. PyString_Check() is true).  Another idea would
+     * be to call tp_hash on the underlying object and see if it raises
+     * an error. */
+    if ( !self->b_readonly )
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "writable buffers are not hashable");
+        return -1;
+    }
+
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return -1;
+    p = (unsigned char *) ptr;
+    len = size;
+    /*
+      We make the hash of the empty buffer be 0, rather than using
+      (prefix ^ suffix), since this slightly obfuscates the hash secret
+    */
+    if (len == 0) {
+        self->b_hash = 0;
+        return 0;
+    }
+    x = _Py_HashSecret.prefix;
+    x ^= *p << 7;
+    while (--len >= 0)
+        x = (1000003*x) ^ *p++;
+    x ^= size;
+    x ^= _Py_HashSecret.suffix;
+    if (x == -1)
+        x = -2;
+    self->b_hash = x;
+    return x;
+}
+
+static PyObject *
+buffer_str(PyBufferObject *self)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return NULL;
+    return PyString_FromStringAndSize((const char *)ptr, size);
+}
+
+/* Sequence methods */
+
+static Py_ssize_t
+buffer_length(PyBufferObject *self)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return -1;
+    return size;
+}
+
+static PyObject *
+buffer_concat(PyBufferObject *self, PyObject *other)
+{
+    PyBufferProcs *pb = other->ob_type->tp_as_buffer;
+    void *ptr1, *ptr2;
+    char *p;
+    PyObject *ob;
+    Py_ssize_t size, count;
+
+    if ( pb == NULL ||
+         pb->bf_getreadbuffer == NULL ||
+         pb->bf_getsegcount == NULL )
+    {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+    {
+        /* ### use a different exception type/message? */
+        PyErr_SetString(PyExc_TypeError,
+                        "single-segment buffer object expected");
+        return NULL;
+    }
+
+    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+        return NULL;
+
+    /* optimize special case */
+    if ( size == 0 )
+    {
+        Py_INCREF(other);
+        return other;
+    }
+
+    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+        return NULL;
+
+    assert(count <= PY_SIZE_MAX - size);
+
+    ob = PyString_FromStringAndSize(NULL, size + count);
+    if ( ob == NULL )
+        return NULL;
+    p = PyString_AS_STRING(ob);
+    memcpy(p, ptr1, size);
+    memcpy(p + size, ptr2, count);
+
+    /* there is an extra byte in the string object, so this is safe */
+    p[size + count] = '\0';
+
+    return ob;
+}
+
+static PyObject *
+buffer_repeat(PyBufferObject *self, Py_ssize_t count)
+{
+    PyObject *ob;
+    register char *p;
+    void *ptr;
+    Py_ssize_t size;
+
+    if ( count < 0 )
+        count = 0;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return NULL;
+    if (count > PY_SSIZE_T_MAX / size) {
+        PyErr_SetString(PyExc_MemoryError, "result too large");
+        return NULL;
+    }
+    ob = PyString_FromStringAndSize(NULL, size * count);
+    if ( ob == NULL )
+        return NULL;
+
+    p = PyString_AS_STRING(ob);
+    while ( count-- )
+    {
+        memcpy(p, ptr, size);
+        p += size;
+    }
+
+    /* there is an extra byte in the string object, so this is safe */
+    *p = '\0';
+
+    return ob;
+}
+
+static PyObject *
+buffer_item(PyBufferObject *self, Py_ssize_t idx)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return NULL;
+    if ( idx < 0 || idx >= size ) {
+        PyErr_SetString(PyExc_IndexError, "buffer index out of range");
+        return NULL;
+    }
+    return PyString_FromStringAndSize((char *)ptr + idx, 1);
+}
+
+static PyObject *
+buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return NULL;
+    if ( left < 0 )
+        left = 0;
+    if ( right < 0 )
+        right = 0;
+    if ( right > size )
+        right = size;
+    if ( right < left )
+        right = left;
+    return PyString_FromStringAndSize((char *)ptr + left,
+                                      right - left);
+}
+
+static PyObject *
+buffer_subscript(PyBufferObject *self, PyObject *item)
+{
+    void *p;
+    Py_ssize_t size;
+
+    if (!get_buf(self, &p, &size, ANY_BUFFER))
+        return NULL;
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += size;
+        return buffer_item(self, i);
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item, size,
+                         &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0)
+            return PyString_FromStringAndSize("", 0);
+        else if (step == 1)
+            return PyString_FromStringAndSize((char *)p + start,
+                                              stop - start);
+        else {
+            PyObject *result;
+            char *source_buf = (char *)p;
+            char *result_buf = (char *)PyMem_Malloc(slicelength);
+
+            if (result_buf == NULL)
+                return PyErr_NoMemory();
+
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                result_buf[i] = source_buf[cur];
+            }
+
+            result = PyString_FromStringAndSize(result_buf,
+                                                slicelength);
+            PyMem_Free(result_buf);
+            return result;
+        }
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "sequence index must be integer");
+        return NULL;
+    }
+}
+
+static int
+buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
+{
+    PyBufferProcs *pb;
+    void *ptr1, *ptr2;
+    Py_ssize_t size;
+    Py_ssize_t count;
+
+    if ( self->b_readonly ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "buffer is read-only");
+        return -1;
+    }
+
+    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+        return -1;
+
+    if (idx < 0 || idx >= size) {
+        PyErr_SetString(PyExc_IndexError,
+                        "buffer assignment index out of range");
+        return -1;
+    }
+
+    pb = other ? other->ob_type->tp_as_buffer : NULL;
+    if ( pb == NULL ||
+         pb->bf_getreadbuffer == NULL ||
+         pb->bf_getsegcount == NULL )
+    {
+        PyErr_BadArgument();
+        return -1;
+    }
+    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+    {
+        /* ### use a different exception type/message? */
+        PyErr_SetString(PyExc_TypeError,
+                        "single-segment buffer object expected");
+        return -1;
+    }
+
+    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+        return -1;
+    if ( count != 1 ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "right operand must be a single byte");
+        return -1;
+    }
+
+    ((char *)ptr1)[idx] = *(char *)ptr2;
+    return 0;
+}
+
+static int
+buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
+{
+    PyBufferProcs *pb;
+    void *ptr1, *ptr2;
+    Py_ssize_t size;
+    Py_ssize_t slice_len;
+    Py_ssize_t count;
+
+    if ( self->b_readonly ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "buffer is read-only");
+        return -1;
+    }
+
+    pb = other ? other->ob_type->tp_as_buffer : NULL;
+    if ( pb == NULL ||
+         pb->bf_getreadbuffer == NULL ||
+         pb->bf_getsegcount == NULL )
+    {
+        PyErr_BadArgument();
+        return -1;
+    }
+    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+    {
+        /* ### use a different exception type/message? */
+        PyErr_SetString(PyExc_TypeError,
+                        "single-segment buffer object expected");
+        return -1;
+    }
+    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+        return -1;
+    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+        return -1;
+
+    if ( left < 0 )
+        left = 0;
+    else if ( left > size )
+        left = size;
+    if ( right < left )
+        right = left;
+    else if ( right > size )
+        right = size;
+    slice_len = right - left;
+
+    if ( count != slice_len ) {
+        PyErr_SetString(
+            PyExc_TypeError,
+            "right operand length must match slice length");
+        return -1;
+    }
+
+    if ( slice_len )
+        memcpy((char *)ptr1 + left, ptr2, slice_len);
+
+    return 0;
+}
+
+static int
+buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
+{
+    PyBufferProcs *pb;
+    void *ptr1, *ptr2;
+    Py_ssize_t selfsize;
+    Py_ssize_t othersize;
+
+    if ( self->b_readonly ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "buffer is read-only");
+        return -1;
+    }
+
+    pb = value ? value->ob_type->tp_as_buffer : NULL;
+    if ( pb == NULL ||
+         pb->bf_getreadbuffer == NULL ||
+         pb->bf_getsegcount == NULL )
+    {
+        PyErr_BadArgument();
+        return -1;
+    }
+    if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
+    {
+        /* ### use a different exception type/message? */
+        PyErr_SetString(PyExc_TypeError,
+                        "single-segment buffer object expected");
+        return -1;
+    }
+    if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
+        return -1;
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return -1;
+        if (i < 0)
+            i += selfsize;
+        return buffer_ass_item(self, i, value);
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength;
+
+        if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
+                        &start, &stop, &step, &slicelength) < 0)
+            return -1;
+
+        if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
+            return -1;
+
+        if (othersize != slicelength) {
+            PyErr_SetString(
+                PyExc_TypeError,
+                "right operand length must match slice length");
+            return -1;
+        }
+
+        if (slicelength == 0)
+            return 0;
+        else if (step == 1) {
+            memcpy((char *)ptr1 + start, ptr2, slicelength);
+            return 0;
+        }
+        else {
+            Py_ssize_t cur, i;
+
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                ((char *)ptr1)[cur] = ((char *)ptr2)[i];
+            }
+
+            return 0;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+                        "buffer indices must be integers");
+        return -1;
+    }
+}
+
+/* Buffer methods */
+
+static Py_ssize_t
+buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
+{
+    Py_ssize_t size;
+    if ( idx != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent buffer segment");
+        return -1;
+    }
+    if (!get_buf(self, pp, &size, READ_BUFFER))
+        return -1;
+    return size;
+}
+
+static Py_ssize_t
+buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
+{
+    Py_ssize_t size;
+
+    if ( self->b_readonly )
+    {
+        PyErr_SetString(PyExc_TypeError, "buffer is read-only");
+        return -1;
+    }
+
+    if ( idx != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent buffer segment");
+        return -1;
+    }
+    if (!get_buf(self, pp, &size, WRITE_BUFFER))
+        return -1;
+    return size;
+}
+
+static Py_ssize_t
+buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return -1;
+    if (lenp)
+        *lenp = size;
+    return 1;
+}
+
+static Py_ssize_t
+buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if ( idx != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent buffer segment");
+        return -1;
+    }
+    if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
+        return -1;
+    *pp = (const char *)ptr;
+    return size;
+}
+
+static int buffer_getbuffer(PyBufferObject *self, Py_buffer *buf, int flags)
+{
+    void *ptr;
+    Py_ssize_t size;
+    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        return -1;
+    return PyBuffer_FillInfo(buf, (PyObject*)self, ptr, size,
+                             self->b_readonly, flags);
+}
+
+static PySequenceMethods buffer_as_sequence = {
+    (lenfunc)buffer_length, /*sq_length*/
+    (binaryfunc)buffer_concat, /*sq_concat*/
+    (ssizeargfunc)buffer_repeat, /*sq_repeat*/
+    (ssizeargfunc)buffer_item, /*sq_item*/
+    (ssizessizeargfunc)buffer_slice, /*sq_slice*/
+    (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
+    (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+};
+
+static PyMappingMethods buffer_as_mapping = {
+    (lenfunc)buffer_length,
+    (binaryfunc)buffer_subscript,
+    (objobjargproc)buffer_ass_subscript,
+};
+
+static PyBufferProcs buffer_as_buffer = {
+    (readbufferproc)buffer_getreadbuf,
+    (writebufferproc)buffer_getwritebuf,
+    (segcountproc)buffer_getsegcount,
+    (charbufferproc)buffer_getcharbuf,
+    (getbufferproc)buffer_getbuffer,
+};
+
+PyTypeObject PyBuffer_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "buffer",
+    sizeof(PyBufferObject),
+    0,
+    (destructor)buffer_dealloc,                 /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)buffer_compare,                    /* tp_compare */
+    (reprfunc)buffer_repr,                      /* tp_repr */
+    0,                                          /* tp_as_number */
+    &buffer_as_sequence,                        /* tp_as_sequence */
+    &buffer_as_mapping,                         /* tp_as_mapping */
+    (hashfunc)buffer_hash,                      /* tp_hash */
+    0,                                          /* tp_call */
+    (reprfunc)buffer_str,                       /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    &buffer_as_buffer,                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
+    buffer_doc,                                 /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    buffer_new,                                 /* tp_new */
+};
\ No newline at end of file
diff --git a/Python-2.7.5/Objects/bytearrayobject.c b/Python-2.7.5/Objects/bytearrayobject.c
new file mode 100644
index 0000000..21c58ce
--- /dev/null
+++ b/Python-2.7.5/Objects/bytearrayobject.c
@@ -0,0 +1,3054 @@
+/* PyBytes (bytearray) implementation */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+#include "bytes_methods.h"
+
+char _PyByteArray_empty_string[] = "";
+
+void
+PyByteArray_Fini(void)
+{
+}
+
+int
+PyByteArray_Init(void)
+{
+    return 1;
+}
+
+/* end nullbytes support */
+
+/* Helpers */
+
+static int
+_getbytevalue(PyObject* arg, int *value)
+{
+    long face_value;
+
+    if (PyBytes_CheckExact(arg)) {
+        if (Py_SIZE(arg) != 1) {
+            PyErr_SetString(PyExc_ValueError, "string must be of size 1");
+            return 0;
+        }
+        *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
+        return 1;
+    }
+    else if (PyInt_Check(arg) || PyLong_Check(arg)) {
+        face_value = PyLong_AsLong(arg);
+    }
+    else {
+        PyObject *index = PyNumber_Index(arg);
+        if (index == NULL) {
+            PyErr_Format(PyExc_TypeError,
+                         "an integer or string of size 1 is required");
+            return 0;
+        }
+        face_value = PyLong_AsLong(index);
+        Py_DECREF(index);
+    }
+
+    if (face_value < 0 || face_value >= 256) {
+        /* this includes the OverflowError in case the long is too large */
+        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+        return 0;
+    }
+
+    *value = face_value;
+    return 1;
+}
+
+static Py_ssize_t
+bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+{
+    if ( index != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                "accessing non-existent bytes segment");
+        return -1;
+    }
+    *ptr = (void *)PyByteArray_AS_STRING(self);
+    return Py_SIZE(self);
+}
+
+static Py_ssize_t
+bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+{
+    if ( index != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                "accessing non-existent bytes segment");
+        return -1;
+    }
+    *ptr = (void *)PyByteArray_AS_STRING(self);
+    return Py_SIZE(self);
+}
+
+static Py_ssize_t
+bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
+{
+    if ( lenp )
+        *lenp = Py_SIZE(self);
+    return 1;
+}
+
+static Py_ssize_t
+bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
+{
+    if ( index != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                "accessing non-existent bytes segment");
+        return -1;
+    }
+    *ptr = PyByteArray_AS_STRING(self);
+    return Py_SIZE(self);
+}
+
+static int
+bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
+{
+    int ret;
+    void *ptr;
+    if (view == NULL) {
+        obj->ob_exports++;
+        return 0;
+    }
+    ptr = (void *) PyByteArray_AS_STRING(obj);
+    ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
+    if (ret >= 0) {
+        obj->ob_exports++;
+    }
+    return ret;
+}
+
+static void
+bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
+{
+    obj->ob_exports--;
+}
+
+static Py_ssize_t
+_getbuffer(PyObject *obj, Py_buffer *view)
+{
+    PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
+
+    if (buffer == NULL || buffer->bf_getbuffer == NULL)
+    {
+        PyErr_Format(PyExc_TypeError,
+                     "Type %.100s doesn't support the buffer API",
+                     Py_TYPE(obj)->tp_name);
+        return -1;
+    }
+
+    if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
+            return -1;
+    return view->len;
+}
+
+static int
+_canresize(PyByteArrayObject *self)
+{
+    if (self->ob_exports > 0) {
+        PyErr_SetString(PyExc_BufferError,
+                "Existing exports of data: object cannot be re-sized");
+        return 0;
+    }
+    return 1;
+}
+
+/* Direct API functions */
+
+PyObject *
+PyByteArray_FromObject(PyObject *input)
+{
+    return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
+                                        input, NULL);
+}
+
+PyObject *
+PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
+{
+    PyByteArrayObject *new;
+    Py_ssize_t alloc;
+
+    if (size < 0) {
+        PyErr_SetString(PyExc_SystemError,
+            "Negative size passed to PyByteArray_FromStringAndSize");
+        return NULL;
+    }
+
+    new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
+    if (new == NULL)
+        return NULL;
+
+    if (size == 0) {
+        new->ob_bytes = NULL;
+        alloc = 0;
+    }
+    else {
+        alloc = size + 1;
+        new->ob_bytes = PyMem_Malloc(alloc);
+        if (new->ob_bytes == NULL) {
+            Py_DECREF(new);
+            return PyErr_NoMemory();
+        }
+        if (bytes != NULL && size > 0)
+            memcpy(new->ob_bytes, bytes, size);
+        new->ob_bytes[size] = '\0';  /* Trailing null byte */
+    }
+    Py_SIZE(new) = size;
+    new->ob_alloc = alloc;
+    new->ob_exports = 0;
+
+    return (PyObject *)new;
+}
+
+Py_ssize_t
+PyByteArray_Size(PyObject *self)
+{
+    assert(self != NULL);
+    assert(PyByteArray_Check(self));
+
+    return PyByteArray_GET_SIZE(self);
+}
+
+char  *
+PyByteArray_AsString(PyObject *self)
+{
+    assert(self != NULL);
+    assert(PyByteArray_Check(self));
+
+    return PyByteArray_AS_STRING(self);
+}
+
+int
+PyByteArray_Resize(PyObject *self, Py_ssize_t size)
+{
+    void *sval;
+    Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
+
+    assert(self != NULL);
+    assert(PyByteArray_Check(self));
+    assert(size >= 0);
+
+    if (size == Py_SIZE(self)) {
+        return 0;
+    }
+    if (!_canresize((PyByteArrayObject *)self)) {
+        return -1;
+    }
+
+    if (size < alloc / 2) {
+        /* Major downsize; resize down to exact size */
+        alloc = size + 1;
+    }
+    else if (size < alloc) {
+        /* Within allocated size; quick exit */
+        Py_SIZE(self) = size;
+        ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
+        return 0;
+    }
+    else if (size <= alloc * 1.125) {
+        /* Moderate upsize; overallocate similar to list_resize() */
+        alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
+    }
+    else {
+        /* Major upsize; resize up to exact size */
+        alloc = size + 1;
+    }
+
+    sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
+    if (sval == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+
+    ((PyByteArrayObject *)self)->ob_bytes = sval;
+    Py_SIZE(self) = size;
+    ((PyByteArrayObject *)self)->ob_alloc = alloc;
+    ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
+
+    return 0;
+}
+
+PyObject *
+PyByteArray_Concat(PyObject *a, PyObject *b)
+{
+    Py_ssize_t size;
+    Py_buffer va, vb;
+    PyByteArrayObject *result = NULL;
+
+    va.len = -1;
+    vb.len = -1;
+    if (_getbuffer(a, &va) < 0  ||
+        _getbuffer(b, &vb) < 0) {
+            PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
+                         Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
+            goto done;
+    }
+
+    size = va.len + vb.len;
+    if (size < 0) {
+            PyErr_NoMemory();
+            goto done;
+    }
+
+    result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
+    if (result != NULL) {
+        memcpy(result->ob_bytes, va.buf, va.len);
+        memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
+    }
+
+  done:
+    if (va.len != -1)
+        PyBuffer_Release(&va);
+    if (vb.len != -1)
+        PyBuffer_Release(&vb);
+    return (PyObject *)result;
+}
+
+/* Functions stuffed into the type object */
+
+static Py_ssize_t
+bytearray_length(PyByteArrayObject *self)
+{
+    return Py_SIZE(self);
+}
+
+static PyObject *
+bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
+{
+    Py_ssize_t mysize;
+    Py_ssize_t size;
+    Py_buffer vo;
+
+    if (_getbuffer(other, &vo) < 0) {
+        PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
+                     Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
+        return NULL;
+    }
+
+    mysize = Py_SIZE(self);
+    size = mysize + vo.len;
+    if (size < 0) {
+        PyBuffer_Release(&vo);
+        return PyErr_NoMemory();
+    }
+    if (size < self->ob_alloc) {
+        Py_SIZE(self) = size;
+        self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
+    }
+    else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
+        PyBuffer_Release(&vo);
+        return NULL;
+    }
+    memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
+    PyBuffer_Release(&vo);
+    Py_INCREF(self);
+    return (PyObject *)self;
+}
+
+static PyObject *
+bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
+{
+    PyByteArrayObject *result;
+    Py_ssize_t mysize;
+    Py_ssize_t size;
+
+    if (count < 0)
+        count = 0;
+    mysize = Py_SIZE(self);
+    size = mysize * count;
+    if (count != 0 && size / count != mysize)
+        return PyErr_NoMemory();
+    result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
+    if (result != NULL && size != 0) {
+        if (mysize == 1)
+            memset(result->ob_bytes, self->ob_bytes[0], size);
+        else {
+            Py_ssize_t i;
+            for (i = 0; i < count; i++)
+                memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
+        }
+    }
+    return (PyObject *)result;
+}
+
+static PyObject *
+bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
+{
+    Py_ssize_t mysize;
+    Py_ssize_t size;
+
+    if (count < 0)
+        count = 0;
+    mysize = Py_SIZE(self);
+    size = mysize * count;
+    if (count != 0 && size / count != mysize)
+        return PyErr_NoMemory();
+    if (size < self->ob_alloc) {
+        Py_SIZE(self) = size;
+        self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
+    }
+    else if (PyByteArray_Resize((PyObject *)self, size) < 0)
+        return NULL;
+
+    if (mysize == 1)
+        memset(self->ob_bytes, self->ob_bytes[0], size);
+    else {
+        Py_ssize_t i;
+        for (i = 1; i < count; i++)
+            memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
+    }
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+}
+
+static PyObject *
+bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
+{
+    if (i < 0)
+        i += Py_SIZE(self);
+    if (i < 0 || i >= Py_SIZE(self)) {
+        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+        return NULL;
+    }
+    return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
+}
+
+static PyObject *
+bytearray_subscript(PyByteArrayObject *self, PyObject *index)
+{
+    if (PyIndex_Check(index)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
+
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+
+        if (i < 0)
+            i += PyByteArray_GET_SIZE(self);
+
+        if (i < 0 || i >= Py_SIZE(self)) {
+            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+            return NULL;
+        }
+        return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
+    }
+    else if (PySlice_Check(index)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+        if (PySlice_GetIndicesEx((PySliceObject *)index,
+                                 PyByteArray_GET_SIZE(self),
+                                 &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0)
+            return PyByteArray_FromStringAndSize("", 0);
+        else if (step == 1) {
+            return PyByteArray_FromStringAndSize(self->ob_bytes + start,
+                                             slicelength);
+        }
+        else {
+            char *source_buf = PyByteArray_AS_STRING(self);
+            char *result_buf = (char *)PyMem_Malloc(slicelength);
+            PyObject *result;
+
+            if (result_buf == NULL)
+                return PyErr_NoMemory();
+
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                     result_buf[i] = source_buf[cur];
+            }
+            result = PyByteArray_FromStringAndSize(result_buf, slicelength);
+            PyMem_Free(result_buf);
+            return result;
+        }
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
+        return NULL;
+    }
+}
+
+static int
+bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
+               PyObject *values)
+{
+    Py_ssize_t avail, needed;
+    void *bytes;
+    Py_buffer vbytes;
+    int res = 0;
+
+    vbytes.len = -1;
+    if (values == (PyObject *)self) {
+        /* Make a copy and call this function recursively */
+        int err;
+        values = PyByteArray_FromObject(values);
+        if (values == NULL)
+            return -1;
+        err = bytearray_setslice(self, lo, hi, values);
+        Py_DECREF(values);
+        return err;
+    }
+    if (values == NULL) {
+        /* del b[lo:hi] */
+        bytes = NULL;
+        needed = 0;
+    }
+    else {
+            if (_getbuffer(values, &vbytes) < 0) {
+                    PyErr_Format(PyExc_TypeError,
+                                 "can't set bytearray slice from %.100s",
+                                 Py_TYPE(values)->tp_name);
+                    return -1;
+            }
+            needed = vbytes.len;
+            bytes = vbytes.buf;
+    }
+
+    if (lo < 0)
+        lo = 0;
+    if (hi < lo)
+        hi = lo;
+    if (hi > Py_SIZE(self))
+        hi = Py_SIZE(self);
+
+    avail = hi - lo;
+    if (avail < 0)
+        lo = hi = avail = 0;
+
+    if (avail != needed) {
+        if (avail > needed) {
+            if (!_canresize(self)) {
+                res = -1;
+                goto finish;
+            }
+            /*
+              0   lo               hi               old_size
+              |   |<----avail----->|<-----tomove------>|
+              |   |<-needed->|<-----tomove------>|
+              0   lo      new_hi              new_size
+            */
+            memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
+                    Py_SIZE(self) - hi);
+        }
+        /* XXX(nnorwitz): need to verify this can't overflow! */
+        if (PyByteArray_Resize((PyObject *)self,
+                           Py_SIZE(self) + needed - avail) < 0) {
+                res = -1;
+                goto finish;
+        }
+        if (avail < needed) {
+            /*
+              0   lo        hi               old_size
+              |   |<-avail->|<-----tomove------>|
+              |   |<----needed---->|<-----tomove------>|
+              0   lo            new_hi              new_size
+             */
+            memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
+                    Py_SIZE(self) - lo - needed);
+        }
+    }
+
+    if (needed > 0)
+        memcpy(self->ob_bytes + lo, bytes, needed);
+
+
+ finish:
+    if (vbytes.len != -1)
+            PyBuffer_Release(&vbytes);
+    return res;
+}
+
+static int
+bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
+{
+    int ival;
+
+    if (i < 0)
+        i += Py_SIZE(self);
+
+    if (i < 0 || i >= Py_SIZE(self)) {
+        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+        return -1;
+    }
+
+    if (value == NULL)
+        return bytearray_setslice(self, i, i+1, NULL);
+
+    if (!_getbytevalue(value, &ival))
+        return -1;
+
+    self->ob_bytes[i] = ival;
+    return 0;
+}
+
+static int
+bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
+{
+    Py_ssize_t start, stop, step, slicelen, needed;
+    char *bytes;
+
+    if (PyIndex_Check(index)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
+
+        if (i == -1 && PyErr_Occurred())
+            return -1;
+
+        if (i < 0)
+            i += PyByteArray_GET_SIZE(self);
+
+        if (i < 0 || i >= Py_SIZE(self)) {
+            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+            return -1;
+        }
+
+        if (values == NULL) {
+            /* Fall through to slice assignment */
+            start = i;
+            stop = i + 1;
+            step = 1;
+            slicelen = 1;
+        }
+        else {
+            int ival;
+            if (!_getbytevalue(values, &ival))
+                return -1;
+            self->ob_bytes[i] = (char)ival;
+            return 0;
+        }
+    }
+    else if (PySlice_Check(index)) {
+        if (PySlice_GetIndicesEx((PySliceObject *)index,
+                                 PyByteArray_GET_SIZE(self),
+                                 &start, &stop, &step, &slicelen) < 0) {
+            return -1;
+        }
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
+        return -1;
+    }
+
+    if (values == NULL) {
+        bytes = NULL;
+        needed = 0;
+    }
+    else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
+        int err;
+        if (PyNumber_Check(values) || PyUnicode_Check(values)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "can assign only bytes, buffers, or iterables "
+                            "of ints in range(0, 256)");
+            return -1;
+        }
+        /* Make a copy and call this function recursively */
+        values = PyByteArray_FromObject(values);
+        if (values == NULL)
+            return -1;
+        err = bytearray_ass_subscript(self, index, values);
+        Py_DECREF(values);
+        return err;
+    }
+    else {
+        assert(PyByteArray_Check(values));
+        bytes = ((PyByteArrayObject *)values)->ob_bytes;
+        needed = Py_SIZE(values);
+    }
+    /* Make sure b[5:2] = ... inserts before 5, not before 2. */
+    if ((step < 0 && start < stop) ||
+        (step > 0 && start > stop))
+        stop = start;
+    if (step == 1) {
+        if (slicelen != needed) {
+            if (!_canresize(self))
+                return -1;
+            if (slicelen > needed) {
+                /*
+                  0   start           stop              old_size
+                  |   |<---slicelen--->|<-----tomove------>|
+                  |   |<-needed->|<-----tomove------>|
+                  0   lo      new_hi              new_size
+                */
+                memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
+                        Py_SIZE(self) - stop);
+            }
+            if (PyByteArray_Resize((PyObject *)self,
+                               Py_SIZE(self) + needed - slicelen) < 0)
+                return -1;
+            if (slicelen < needed) {
+                /*
+                  0   lo        hi               old_size
+                  |   |<-avail->|<-----tomove------>|
+                  |   |<----needed---->|<-----tomove------>|
+                  0   lo            new_hi              new_size
+                 */
+                memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
+                        Py_SIZE(self) - start - needed);
+            }
+        }
+
+        if (needed > 0)
+            memcpy(self->ob_bytes + start, bytes, needed);
+
+        return 0;
+    }
+    else {
+        if (needed == 0) {
+            /* Delete slice */
+            size_t cur;
+            Py_ssize_t i;
+
+            if (!_canresize(self))
+                return -1;
+            if (step < 0) {
+                stop = start + 1;
+                start = stop + step * (slicelen - 1) - 1;
+                step = -step;
+            }
+            for (cur = start, i = 0;
+                 i < slicelen; cur += step, i++) {
+                Py_ssize_t lim = step - 1;
+
+                if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
+                    lim = PyByteArray_GET_SIZE(self) - cur - 1;
+
+                memmove(self->ob_bytes + cur - i,
+                        self->ob_bytes + cur + 1, lim);
+            }
+            /* Move the tail of the bytes, in one chunk */
+            cur = start + slicelen*step;
+            if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
+                memmove(self->ob_bytes + cur - slicelen,
+                        self->ob_bytes + cur,
+                        PyByteArray_GET_SIZE(self) - cur);
+            }
+            if (PyByteArray_Resize((PyObject *)self,
+                               PyByteArray_GET_SIZE(self) - slicelen) < 0)
+                return -1;
+
+            return 0;
+        }
+        else {
+            /* Assign slice */
+            Py_ssize_t cur, i;
+
+            if (needed != slicelen) {
+                PyErr_Format(PyExc_ValueError,
+                             "attempt to assign bytes of size %zd "
+                             "to extended slice of size %zd",
+                             needed, slicelen);
+                return -1;
+            }
+            for (cur = start, i = 0; i < slicelen; cur += step, i++)
+                self->ob_bytes[cur] = bytes[i];
+            return 0;
+        }
+    }
+}
+
+static int
+bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"source", "encoding", "errors", 0};
+    PyObject *arg = NULL;
+    const char *encoding = NULL;
+    const char *errors = NULL;
+    Py_ssize_t count;
+    PyObject *it;
+    PyObject *(*iternext)(PyObject *);
+
+    if (Py_SIZE(self) != 0) {
+        /* Empty previous contents (yes, do this first of all!) */
+        if (PyByteArray_Resize((PyObject *)self, 0) < 0)
+            return -1;
+    }
+
+    /* Parse arguments */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
+                                     &arg, &encoding, &errors))
+        return -1;
+
+    /* Make a quick exit if no first argument */
+    if (arg == NULL) {
+        if (encoding != NULL || errors != NULL) {
+            PyErr_SetString(PyExc_TypeError,
+                            "encoding or errors without sequence argument");
+            return -1;
+        }
+        return 0;
+    }
+
+    if (PyBytes_Check(arg)) {
+        PyObject *new, *encoded;
+        if (encoding != NULL) {
+            encoded = PyCodec_Encode(arg, encoding, errors);
+            if (encoded == NULL)
+                return -1;
+            assert(PyBytes_Check(encoded));
+        }
+        else {
+            encoded = arg;
+            Py_INCREF(arg);
+        }
+        new = bytearray_iconcat(self, arg);
+        Py_DECREF(encoded);
+        if (new == NULL)
+            return -1;
+        Py_DECREF(new);
+        return 0;
+    }
+
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(arg)) {
+        /* Encode via the codec registry */
+        PyObject *encoded, *new;
+        if (encoding == NULL) {
+            PyErr_SetString(PyExc_TypeError,
+                            "unicode argument without an encoding");
+            return -1;
+        }
+        encoded = PyCodec_Encode(arg, encoding, errors);
+        if (encoded == NULL)
+            return -1;
+        assert(PyBytes_Check(encoded));
+        new = bytearray_iconcat(self, encoded);
+        Py_DECREF(encoded);
+        if (new == NULL)
+            return -1;
+        Py_DECREF(new);
+        return 0;
+    }
+#endif
+
+    /* If it's not unicode, there can't be encoding or errors */
+    if (encoding != NULL || errors != NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "encoding or errors without a string argument");
+        return -1;
+    }
+
+    /* Is it an int? */
+    count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
+    if (count == -1 && PyErr_Occurred()) {
+        if (PyErr_ExceptionMatches(PyExc_OverflowError))
+            return -1;
+        PyErr_Clear();
+    }
+    else if (count < 0) {
+        PyErr_SetString(PyExc_ValueError, "negative count");
+        return -1;
+    }
+    else {
+        if (count > 0) {
+            if (PyByteArray_Resize((PyObject *)self, count))
+                return -1;
+            memset(self->ob_bytes, 0, count);
+        }
+        return 0;
+    }
+
+    /* Use the buffer API */
+    if (PyObject_CheckBuffer(arg)) {
+        Py_ssize_t size;
+        Py_buffer view;
+        if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
+            return -1;
+        size = view.len;
+        if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
+        if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
+                goto fail;
+        PyBuffer_Release(&view);
+        return 0;
+    fail:
+        PyBuffer_Release(&view);
+        return -1;
+    }
+
+    /* XXX Optimize this if the arguments is a list, tuple */
+
+    /* Get the iterator */
+    it = PyObject_GetIter(arg);
+    if (it == NULL)
+        return -1;
+    iternext = *Py_TYPE(it)->tp_iternext;
+
+    /* Run the iterator to exhaustion */
+    for (;;) {
+        PyObject *item;
+        int rc, value;
+
+        /* Get the next item */
+        item = iternext(it);
+        if (item == NULL) {
+            if (PyErr_Occurred()) {
+                if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+                    goto error;
+                PyErr_Clear();
+            }
+            break;
+        }
+
+        /* Interpret it as an int (__index__) */
+        rc = _getbytevalue(item, &value);
+        Py_DECREF(item);
+        if (!rc)
+            goto error;
+
+        /* Append the byte */
+        if (Py_SIZE(self) < self->ob_alloc)
+            Py_SIZE(self)++;
+        else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
+            goto error;
+        self->ob_bytes[Py_SIZE(self)-1] = value;
+    }
+
+    /* Clean up and return success */
+    Py_DECREF(it);
+    return 0;
+
+ error:
+    /* Error handling when it != NULL */
+    Py_DECREF(it);
+    return -1;
+}
+
+/* Mostly copied from string_repr, but without the
+   "smart quote" functionality. */
+static PyObject *
+bytearray_repr(PyByteArrayObject *self)
+{
+    static const char *hexdigits = "0123456789abcdef";
+    const char *quote_prefix = "bytearray(b";
+    const char *quote_postfix = ")";
+    Py_ssize_t length = Py_SIZE(self);
+    /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
+    size_t newsize;
+    PyObject *v;
+    if (length > (PY_SSIZE_T_MAX - 14) / 4) {
+        PyErr_SetString(PyExc_OverflowError,
+            "bytearray object is too large to make repr");
+        return NULL;
+    }
+    newsize = 14 + 4 * length;
+    v = PyString_FromStringAndSize(NULL, newsize);
+    if (v == NULL) {
+        return NULL;
+    }
+    else {
+        register Py_ssize_t i;
+        register char c;
+        register char *p;
+        int quote;
+
+        /* Figure out which quote to use; single is preferred */
+        quote = '\'';
+        {
+            char *test, *start;
+            start = PyByteArray_AS_STRING(self);
+            for (test = start; test < start+length; ++test) {
+                if (*test == '"') {
+                    quote = '\''; /* back to single */
+                    goto decided;
+                }
+                else if (*test == '\'')
+                    quote = '"';
+            }
+          decided:
+            ;
+        }
+
+        p = PyString_AS_STRING(v);
+        while (*quote_prefix)
+            *p++ = *quote_prefix++;
+        *p++ = quote;
+
+        for (i = 0; i < length; i++) {
+            /* There's at least enough room for a hex escape
+               and a closing quote. */
+            assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+            c = self->ob_bytes[i];
+            if (c == '\'' || c == '\\')
+                *p++ = '\\', *p++ = c;
+            else if (c == '\t')
+                *p++ = '\\', *p++ = 't';
+            else if (c == '\n')
+                *p++ = '\\', *p++ = 'n';
+            else if (c == '\r')
+                *p++ = '\\', *p++ = 'r';
+            else if (c == 0)
+                *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
+            else if (c < ' ' || c >= 0x7f) {
+                *p++ = '\\';
+                *p++ = 'x';
+                *p++ = hexdigits[(c & 0xf0) >> 4];
+                *p++ = hexdigits[c & 0xf];
+            }
+            else
+                *p++ = c;
+        }
+        assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+        *p++ = quote;
+        while (*quote_postfix) {
+           *p++ = *quote_postfix++;
+        }
+        *p = '\0';
+        if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
+            Py_DECREF(v);
+            return NULL;
+        }
+        return v;
+    }
+}
+
+static PyObject *
+bytearray_str(PyObject *op)
+{
+#if 0
+    if (Py_BytesWarningFlag) {
+        if (PyErr_WarnEx(PyExc_BytesWarning,
+                 "str() on a bytearray instance", 1))
+            return NULL;
+    }
+    return bytearray_repr((PyByteArrayObject*)op);
+#endif
+    return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
+}
+
+static PyObject *
+bytearray_richcompare(PyObject *self, PyObject *other, int op)
+{
+    Py_ssize_t self_size, other_size;
+    Py_buffer self_bytes, other_bytes;
+    PyObject *res;
+    Py_ssize_t minsize;
+    int cmp;
+
+    /* Bytes can be compared to anything that supports the (binary)
+       buffer API.  Except that a comparison with Unicode is always an
+       error, even if the comparison is for equality. */
+#ifdef Py_USING_UNICODE
+    if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
+        PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
+        if (Py_BytesWarningFlag && op == Py_EQ) {
+            if (PyErr_WarnEx(PyExc_BytesWarning,
+                            "Comparison between bytearray and string", 1))
+                return NULL;
+        }
+
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+#endif
+
+    self_size = _getbuffer(self, &self_bytes);
+    if (self_size < 0) {
+        PyErr_Clear();
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    other_size = _getbuffer(other, &other_bytes);
+    if (other_size < 0) {
+        PyErr_Clear();
+        PyBuffer_Release(&self_bytes);
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
+        /* Shortcut: if the lengths differ, the objects differ */
+        cmp = (op == Py_NE);
+    }
+    else {
+        minsize = self_size;
+        if (other_size < minsize)
+            minsize = other_size;
+
+        cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
+        /* In ISO C, memcmp() guarantees to use unsigned bytes! */
+
+        if (cmp == 0) {
+            if (self_size < other_size)
+                cmp = -1;
+            else if (self_size > other_size)
+                cmp = 1;
+        }
+
+        switch (op) {
+        case Py_LT: cmp = cmp <  0; break;
+        case Py_LE: cmp = cmp <= 0; break;
+        case Py_EQ: cmp = cmp == 0; break;
+        case Py_NE: cmp = cmp != 0; break;
+        case Py_GT: cmp = cmp >  0; break;
+        case Py_GE: cmp = cmp >= 0; break;
+        }
+    }
+
+    res = cmp ? Py_True : Py_False;
+    PyBuffer_Release(&self_bytes);
+    PyBuffer_Release(&other_bytes);
+    Py_INCREF(res);
+    return res;
+}
+
+static void
+bytearray_dealloc(PyByteArrayObject *self)
+{
+    if (self->ob_exports > 0) {
+        PyErr_SetString(PyExc_SystemError,
+                        "deallocated bytearray object has exported buffers");
+        PyErr_Print();
+    }
+    if (self->ob_bytes != 0) {
+        PyMem_Free(self->ob_bytes);
+    }
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Methods */
+
+#define STRINGLIB_CHAR char
+#define STRINGLIB_LEN PyByteArray_GET_SIZE
+#define STRINGLIB_STR PyByteArray_AS_STRING
+#define STRINGLIB_NEW PyByteArray_FromStringAndSize
+#define STRINGLIB_ISSPACE Py_ISSPACE
+#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
+#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
+#define STRINGLIB_MUTABLE 1
+
+#include "stringlib/fastsearch.h"
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+#include "stringlib/split.h"
+#include "stringlib/ctype.h"
+#include "stringlib/transmogrify.h"
+
+
+/* The following Py_LOCAL_INLINE and Py_LOCAL functions
+were copied from the old char* style string object. */
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len)         \
+    if (end > len)                              \
+        end = len;                              \
+    else if (end < 0) {                         \
+        end += len;                             \
+        if (end < 0)                            \
+            end = 0;                            \
+    }                                           \
+    if (start < 0) {                            \
+        start += len;                           \
+        if (start < 0)                          \
+            start = 0;                          \
+    }
+
+Py_LOCAL_INLINE(Py_ssize_t)
+bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
+{
+    PyObject *subobj;
+    Py_buffer subbuf;
+    Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+    Py_ssize_t res;
+
+    if (!stringlib_parse_args_finds("find/rfind/index/rindex",
+                                    args, &subobj, &start, &end))
+        return -2;
+    if (_getbuffer(subobj, &subbuf) < 0)
+        return -2;
+    if (dir > 0)
+        res = stringlib_find_slice(
+            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+            subbuf.buf, subbuf.len, start, end);
+    else
+        res = stringlib_rfind_slice(
+            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+            subbuf.buf, subbuf.len, start, end);
+    PyBuffer_Release(&subbuf);
+    return res;
+}
+
+PyDoc_STRVAR(find__doc__,
+"B.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in B where subsection sub is found,\n\
+such that sub is contained within B[start,end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+bytearray_find(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t result = bytearray_find_internal(self, args, +1);
+    if (result == -2)
+        return NULL;
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(count__doc__,
+"B.count(sub [,start [,end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of subsection sub in\n\
+bytes B[start:end].  Optional arguments start and end are interpreted\n\
+as in slice notation.");
+
+static PyObject *
+bytearray_count(PyByteArrayObject *self, PyObject *args)
+{
+    PyObject *sub_obj;
+    const char *str = PyByteArray_AS_STRING(self);
+    Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
+    Py_buffer vsub;
+    PyObject *count_obj;
+
+    if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
+        return NULL;
+
+    if (_getbuffer(sub_obj, &vsub) < 0)
+        return NULL;
+
+    ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
+
+    count_obj = PyInt_FromSsize_t(
+        stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
+        );
+    PyBuffer_Release(&vsub);
+    return count_obj;
+}
+
+
+PyDoc_STRVAR(index__doc__,
+"B.index(sub [,start [,end]]) -> int\n\
+\n\
+Like B.find() but raise ValueError when the subsection is not found.");
+
+static PyObject *
+bytearray_index(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t result = bytearray_find_internal(self, args, +1);
+    if (result == -2)
+        return NULL;
+    if (result == -1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "subsection not found");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"B.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in B where subsection sub is found,\n\
+such that sub is contained within B[start,end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+bytearray_rfind(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t result = bytearray_find_internal(self, args, -1);
+    if (result == -2)
+        return NULL;
+    return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rindex__doc__,
+"B.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like B.rfind() but raise ValueError when the subsection is not found.");
+
+static PyObject *
+bytearray_rindex(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t result = bytearray_find_internal(self, args, -1);
+    if (result == -2)
+        return NULL;
+    if (result == -1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "subsection not found");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(result);
+}
+
+
+static int
+bytearray_contains(PyObject *self, PyObject *arg)
+{
+    Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
+    if (ival == -1 && PyErr_Occurred()) {
+        Py_buffer varg;
+        int pos;
+        PyErr_Clear();
+        if (_getbuffer(arg, &varg) < 0)
+            return -1;
+        pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
+                             varg.buf, varg.len, 0);
+        PyBuffer_Release(&varg);
+        return pos >= 0;
+    }
+    if (ival < 0 || ival >= 256) {
+        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+        return -1;
+    }
+
+    return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
+}
+
+
+/* Matches the end (direction >= 0) or start (direction < 0) of self
+ * against substr, using the start and end arguments. Returns
+ * -1 on error, 0 if not found and 1 if found.
+ */
+Py_LOCAL(int)
+_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
+                 Py_ssize_t end, int direction)
+{
+    Py_ssize_t len = PyByteArray_GET_SIZE(self);
+    const char* str;
+    Py_buffer vsubstr;
+    int rv = 0;
+
+    str = PyByteArray_AS_STRING(self);
+
+    if (_getbuffer(substr, &vsubstr) < 0)
+        return -1;
+
+    ADJUST_INDICES(start, end, len);
+
+    if (direction < 0) {
+        /* startswith */
+        if (start+vsubstr.len > len) {
+            goto done;
+        }
+    } else {
+        /* endswith */
+        if (end-start < vsubstr.len || start > len) {
+            goto done;
+        }
+
+        if (end-vsubstr.len > start)
+            start = end - vsubstr.len;
+    }
+    if (end-start >= vsubstr.len)
+        rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
+
+done:
+    PyBuffer_Release(&vsubstr);
+    return rv;
+}
+
+
+PyDoc_STRVAR(startswith__doc__,
+"B.startswith(prefix [,start [,end]]) -> bool\n\
+\n\
+Return True if B starts with the specified prefix, False otherwise.\n\
+With optional start, test B beginning at that position.\n\
+With optional end, stop comparing B at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+bytearray_startswith(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    PyObject *subobj;
+    int result;
+
+    if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
+        return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            result = _bytearray_tailmatch(self,
+                                      PyTuple_GET_ITEM(subobj, i),
+                                      start, end, -1);
+            if (result == -1)
+                return NULL;
+            else if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        Py_RETURN_FALSE;
+    }
+    result = _bytearray_tailmatch(self, subobj, start, end, -1);
+    if (result == -1)
+        return NULL;
+    else
+        return PyBool_FromLong(result);
+}
+
+PyDoc_STRVAR(endswith__doc__,
+"B.endswith(suffix [,start [,end]]) -> bool\n\
+\n\
+Return True if B ends with the specified suffix, False otherwise.\n\
+With optional start, test B beginning at that position.\n\
+With optional end, stop comparing B at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+bytearray_endswith(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    PyObject *subobj;
+    int result;
+
+    if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
+        return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            result = _bytearray_tailmatch(self,
+                                      PyTuple_GET_ITEM(subobj, i),
+                                      start, end, +1);
+            if (result == -1)
+                return NULL;
+            else if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        Py_RETURN_FALSE;
+    }
+    result = _bytearray_tailmatch(self, subobj, start, end, +1);
+    if (result == -1)
+        return NULL;
+    else
+        return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"B.translate(table[, deletechars]) -> bytearray\n\
+\n\
+Return a copy of B, where all characters occurring in the\n\
+optional argument deletechars are removed, and the remaining\n\
+characters have been mapped through the given translation\n\
+table, which must be a bytes object of length 256.");
+
+static PyObject *
+bytearray_translate(PyByteArrayObject *self, PyObject *args)
+{
+    register char *input, *output;
+    register const char *table;
+    register Py_ssize_t i, c;
+    PyObject *input_obj = (PyObject*)self;
+    const char *output_start;
+    Py_ssize_t inlen;
+    PyObject *result = NULL;
+    int trans_table[256];
+    PyObject *tableobj = NULL, *delobj = NULL;
+    Py_buffer vtable, vdel;
+
+    if (!PyArg_UnpackTuple(args, "translate", 1, 2,
+                           &tableobj, &delobj))
+          return NULL;
+
+    if (tableobj == Py_None) {
+        table = NULL;
+        tableobj = NULL;
+    } else if (_getbuffer(tableobj, &vtable) < 0) {
+        return NULL;
+    } else {
+        if (vtable.len != 256) {
+            PyErr_SetString(PyExc_ValueError,
+                            "translation table must be 256 characters long");
+            PyBuffer_Release(&vtable);
+            return NULL;
+        }
+        table = (const char*)vtable.buf;
+    }
+
+    if (delobj != NULL) {
+        if (_getbuffer(delobj, &vdel) < 0) {
+            if (tableobj != NULL)
+                PyBuffer_Release(&vtable);
+            return NULL;
+        }
+    }
+    else {
+        vdel.buf = NULL;
+        vdel.len = 0;
+    }
+
+    inlen = PyByteArray_GET_SIZE(input_obj);
+    result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
+    if (result == NULL)
+        goto done;
+    output_start = output = PyByteArray_AsString(result);
+    input = PyByteArray_AS_STRING(input_obj);
+
+    if (vdel.len == 0 && table != NULL) {
+        /* If no deletions are required, use faster code */
+        for (i = inlen; --i >= 0; ) {
+            c = Py_CHARMASK(*input++);
+            *output++ = table[c];
+        }
+        goto done;
+    }
+
+    if (table == NULL) {
+        for (i = 0; i < 256; i++)
+            trans_table[i] = Py_CHARMASK(i);
+    } else {
+        for (i = 0; i < 256; i++)
+            trans_table[i] = Py_CHARMASK(table[i]);
+    }
+
+    for (i = 0; i < vdel.len; i++)
+        trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
+
+    for (i = inlen; --i >= 0; ) {
+        c = Py_CHARMASK(*input++);
+        if (trans_table[c] != -1)
+            if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+                    continue;
+    }
+    /* Fix the size of the resulting string */
+    if (inlen > 0)
+        PyByteArray_Resize(result, output - output_start);
+
+done:
+    if (tableobj != NULL)
+        PyBuffer_Release(&vtable);
+    if (delobj != NULL)
+        PyBuffer_Release(&vdel);
+    return result;
+}
+
+
+/* find and count characters and substrings */
+
+#define findchar(target, target_len, c)                         \
+  ((char *)memchr((const void *)(target), c, target_len))
+
+
+/* Bytes ops must return a string, create a copy */
+Py_LOCAL(PyByteArrayObject *)
+return_self(PyByteArrayObject *self)
+{
+    return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
+            PyByteArray_AS_STRING(self),
+            PyByteArray_GET_SIZE(self));
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
+{
+    Py_ssize_t count=0;
+    const char *start=target;
+    const char *end=target+target_len;
+
+    while ( (start=findchar(start, end-start, c)) != NULL ) {
+        count++;
+        if (count >= maxcount)
+            break;
+        start += 1;
+    }
+    return count;
+}
+
+
+/* Algorithms for different cases of string replacement */
+
+/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_interleave(PyByteArrayObject *self,
+                   const char *to_s, Py_ssize_t to_len,
+                   Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, i, product;
+    PyByteArrayObject *result;
+
+    self_len = PyByteArray_GET_SIZE(self);
+
+    /* 1 at the end plus 1 after every character */
+    count = self_len+1;
+    if (maxcount < count)
+        count = maxcount;
+
+    /* Check for overflow */
+    /*   result_len = count * to_len + self_len; */
+    product = count * to_len;
+    if (product / to_len != count) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "replace string is too long");
+        return NULL;
+    }
+    result_len = product + self_len;
+    if (result_len < 0) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "replace string is too long");
+        return NULL;
+    }
+
+    if (! (result = (PyByteArrayObject *)
+                     PyByteArray_FromStringAndSize(NULL, result_len)) )
+        return NULL;
+
+    self_s = PyByteArray_AS_STRING(self);
+    result_s = PyByteArray_AS_STRING(result);
+
+    /* TODO: special case single character, which doesn't need memcpy */
+
+    /* Lay the first one down (guaranteed this will occur) */
+    Py_MEMCPY(result_s, to_s, to_len);
+    result_s += to_len;
+    count -= 1;
+
+    for (i=0; i<count; i++) {
+        *result_s++ = *self_s++;
+        Py_MEMCPY(result_s, to_s, to_len);
+        result_s += to_len;
+    }
+
+    /* Copy the rest of the original string */
+    Py_MEMCPY(result_s, self_s, self_len-i);
+
+    return result;
+}
+
+/* Special case for deleting a single character */
+/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_delete_single_character(PyByteArrayObject *self,
+                                char from_c, Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count;
+    PyByteArrayObject *result;
+
+    self_len = PyByteArray_GET_SIZE(self);
+    self_s = PyByteArray_AS_STRING(self);
+
+    count = countchar(self_s, self_len, from_c, maxcount);
+    if (count == 0) {
+        return return_self(self);
+    }
+
+    result_len = self_len - count;  /* from_len == 1 */
+    assert(result_len>=0);
+
+    if ( (result = (PyByteArrayObject *)
+                    PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
+        return NULL;
+    result_s = PyByteArray_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        next = findchar(start, end-start, from_c);
+        if (next == NULL)
+            break;
+        Py_MEMCPY(result_s, start, next-start);
+        result_s += (next-start);
+        start = next+1;
+    }
+    Py_MEMCPY(result_s, start, end-start);
+
+    return result;
+}
+
+/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
+
+Py_LOCAL(PyByteArrayObject *)
+replace_delete_substring(PyByteArrayObject *self,
+                         const char *from_s, Py_ssize_t from_len,
+                         Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, offset;
+    PyByteArrayObject *result;
+
+    self_len = PyByteArray_GET_SIZE(self);
+    self_s = PyByteArray_AS_STRING(self);
+
+    count = stringlib_count(self_s, self_len,
+                            from_s, from_len,
+                            maxcount);
+
+    if (count == 0) {
+        /* no matches */
+        return return_self(self);
+    }
+
+    result_len = self_len - (count * from_len);
+    assert (result_len>=0);
+
+    if ( (result = (PyByteArrayObject *)
+        PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
+            return NULL;
+
+    result_s = PyByteArray_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        offset = stringlib_find(start, end-start,
+                                from_s, from_len,
+                                0);
+        if (offset == -1)
+            break;
+        next = start + offset;
+
+        Py_MEMCPY(result_s, start, next-start);
+
+        result_s += (next-start);
+        start = next+from_len;
+    }
+    Py_MEMCPY(result_s, start, end-start);
+    return result;
+}
+
+/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_single_character_in_place(PyByteArrayObject *self,
+                                  char from_c, char to_c,
+                                  Py_ssize_t maxcount)
+{
+    char *self_s, *result_s, *start, *end, *next;
+    Py_ssize_t self_len;
+    PyByteArrayObject *result;
+
+    /* The result string will be the same size */
+    self_s = PyByteArray_AS_STRING(self);
+    self_len = PyByteArray_GET_SIZE(self);
+
+    next = findchar(self_s, self_len, from_c);
+
+    if (next == NULL) {
+        /* No matches; return the original bytes */
+        return return_self(self);
+    }
+
+    /* Need to make a new bytes */
+    result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
+    if (result == NULL)
+        return NULL;
+    result_s = PyByteArray_AS_STRING(result);
+    Py_MEMCPY(result_s, self_s, self_len);
+
+    /* change everything in-place, starting with this one */
+    start =  result_s + (next-self_s);
+    *start = to_c;
+    start++;
+    end = result_s + self_len;
+
+    while (--maxcount > 0) {
+        next = findchar(start, end-start, from_c);
+        if (next == NULL)
+            break;
+        *next = to_c;
+        start = next+1;
+    }
+
+    return result;
+}
+
+/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_substring_in_place(PyByteArrayObject *self,
+                           const char *from_s, Py_ssize_t from_len,
+                           const char *to_s, Py_ssize_t to_len,
+                           Py_ssize_t maxcount)
+{
+    char *result_s, *start, *end;
+    char *self_s;
+    Py_ssize_t self_len, offset;
+    PyByteArrayObject *result;
+
+    /* The result bytes will be the same size */
+
+    self_s = PyByteArray_AS_STRING(self);
+    self_len = PyByteArray_GET_SIZE(self);
+
+    offset = stringlib_find(self_s, self_len,
+                            from_s, from_len,
+                            0);
+    if (offset == -1) {
+        /* No matches; return the original bytes */
+        return return_self(self);
+    }
+
+    /* Need to make a new bytes */
+    result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
+    if (result == NULL)
+        return NULL;
+    result_s = PyByteArray_AS_STRING(result);
+    Py_MEMCPY(result_s, self_s, self_len);
+
+    /* change everything in-place, starting with this one */
+    start =  result_s + offset;
+    Py_MEMCPY(start, to_s, from_len);
+    start += from_len;
+    end = result_s + self_len;
+
+    while ( --maxcount > 0) {
+        offset = stringlib_find(start, end-start,
+                                from_s, from_len,
+                                0);
+        if (offset==-1)
+            break;
+        Py_MEMCPY(start+offset, to_s, from_len);
+        start += offset+from_len;
+    }
+
+    return result;
+}
+
+/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_single_character(PyByteArrayObject *self,
+                         char from_c,
+                         const char *to_s, Py_ssize_t to_len,
+                         Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, product;
+    PyByteArrayObject *result;
+
+    self_s = PyByteArray_AS_STRING(self);
+    self_len = PyByteArray_GET_SIZE(self);
+
+    count = countchar(self_s, self_len, from_c, maxcount);
+    if (count == 0) {
+        /* no matches, return unchanged */
+        return return_self(self);
+    }
+
+    /* use the difference between current and new, hence the "-1" */
+    /*   result_len = self_len + count * (to_len-1)  */
+    product = count * (to_len-1);
+    if (product / (to_len-1) != count) {
+        PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+        return NULL;
+    }
+    result_len = self_len + product;
+    if (result_len < 0) {
+            PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+            return NULL;
+    }
+
+    if ( (result = (PyByteArrayObject *)
+          PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
+            return NULL;
+    result_s = PyByteArray_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        next = findchar(start, end-start, from_c);
+        if (next == NULL)
+            break;
+
+        if (next == start) {
+            /* replace with the 'to' */
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start += 1;
+        } else {
+            /* copy the unchanged old then the 'to' */
+            Py_MEMCPY(result_s, start, next-start);
+            result_s += (next-start);
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start = next+1;
+        }
+    }
+    /* Copy the remainder of the remaining bytes */
+    Py_MEMCPY(result_s, start, end-start);
+
+    return result;
+}
+
+/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_substring(PyByteArrayObject *self,
+                  const char *from_s, Py_ssize_t from_len,
+                  const char *to_s, Py_ssize_t to_len,
+                  Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, offset, product;
+    PyByteArrayObject *result;
+
+    self_s = PyByteArray_AS_STRING(self);
+    self_len = PyByteArray_GET_SIZE(self);
+
+    count = stringlib_count(self_s, self_len,
+                            from_s, from_len,
+                            maxcount);
+
+    if (count == 0) {
+        /* no matches, return unchanged */
+        return return_self(self);
+    }
+
+    /* Check for overflow */
+    /*    result_len = self_len + count * (to_len-from_len) */
+    product = count * (to_len-from_len);
+    if (product / (to_len-from_len) != count) {
+        PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+        return NULL;
+    }
+    result_len = self_len + product;
+    if (result_len < 0) {
+        PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+        return NULL;
+    }
+
+    if ( (result = (PyByteArrayObject *)
+          PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
+        return NULL;
+    result_s = PyByteArray_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        offset = stringlib_find(start, end-start,
+                                from_s, from_len,
+                                0);
+        if (offset == -1)
+            break;
+        next = start+offset;
+        if (next == start) {
+            /* replace with the 'to' */
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start += from_len;
+        } else {
+            /* copy the unchanged old then the 'to' */
+            Py_MEMCPY(result_s, start, next-start);
+            result_s += (next-start);
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start = next+from_len;
+        }
+    }
+    /* Copy the remainder of the remaining bytes */
+    Py_MEMCPY(result_s, start, end-start);
+
+    return result;
+}
+
+
+Py_LOCAL(PyByteArrayObject *)
+replace(PyByteArrayObject *self,
+        const char *from_s, Py_ssize_t from_len,
+        const char *to_s, Py_ssize_t to_len,
+        Py_ssize_t maxcount)
+{
+    if (maxcount < 0) {
+        maxcount = PY_SSIZE_T_MAX;
+    } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
+        /* nothing to do; return the original bytes */
+        return return_self(self);
+    }
+
+    if (maxcount == 0 ||
+        (from_len == 0 && to_len == 0)) {
+        /* nothing to do; return the original bytes */
+        return return_self(self);
+    }
+
+    /* Handle zero-length special cases */
+
+    if (from_len == 0) {
+        /* insert the 'to' bytes everywhere.   */
+        /*    >>> "Python".replace("", ".")     */
+        /*    '.P.y.t.h.o.n.'                   */
+        return replace_interleave(self, to_s, to_len, maxcount);
+    }
+
+    /* Except for "".replace("", "A") == "A" there is no way beyond this */
+    /* point for an empty self bytes to generate a non-empty bytes */
+    /* Special case so the remaining code always gets a non-empty bytes */
+    if (PyByteArray_GET_SIZE(self) == 0) {
+        return return_self(self);
+    }
+
+    if (to_len == 0) {
+        /* delete all occurances of 'from' bytes */
+        if (from_len == 1) {
+            return replace_delete_single_character(
+                    self, from_s[0], maxcount);
+        } else {
+            return replace_delete_substring(self, from_s, from_len, maxcount);
+        }
+    }
+
+    /* Handle special case where both bytes have the same length */
+
+    if (from_len == to_len) {
+        if (from_len == 1) {
+            return replace_single_character_in_place(
+                    self,
+                    from_s[0],
+                    to_s[0],
+                    maxcount);
+        } else {
+            return replace_substring_in_place(
+                self, from_s, from_len, to_s, to_len, maxcount);
+        }
+    }
+
+    /* Otherwise use the more generic algorithms */
+    if (from_len == 1) {
+        return replace_single_character(self, from_s[0],
+                                        to_s, to_len, maxcount);
+    } else {
+        /* len('from')>=2, len('to')>=1 */
+        return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
+    }
+}
+
+
+PyDoc_STRVAR(replace__doc__,
+"B.replace(old, new[, count]) -> bytes\n\
+\n\
+Return a copy of B with all occurrences of subsection\n\
+old replaced by new.  If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject *
+bytearray_replace(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t count = -1;
+    PyObject *from, *to, *res;
+    Py_buffer vfrom, vto;
+
+    if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
+        return NULL;
+
+    if (_getbuffer(from, &vfrom) < 0)
+        return NULL;
+    if (_getbuffer(to, &vto) < 0) {
+        PyBuffer_Release(&vfrom);
+        return NULL;
+    }
+
+    res = (PyObject *)replace((PyByteArrayObject *) self,
+                              vfrom.buf, vfrom.len,
+                              vto.buf, vto.len, count);
+
+    PyBuffer_Release(&vfrom);
+    PyBuffer_Release(&vto);
+    return res;
+}
+
+PyDoc_STRVAR(split__doc__,
+"B.split([sep[, maxsplit]]) -> list of bytearray\n\
+\n\
+Return a list of the sections in B, using sep as the delimiter.\n\
+If sep is not given, B is split on ASCII whitespace characters\n\
+(space, tab, return, newline, formfeed, vertical tab).\n\
+If maxsplit is given, at most maxsplit splits are done.");
+
+static PyObject *
+bytearray_split(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
+    Py_ssize_t maxsplit = -1;
+    const char *s = PyByteArray_AS_STRING(self), *sub;
+    PyObject *list, *subobj = Py_None;
+    Py_buffer vsub;
+
+    if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
+        return NULL;
+    if (maxsplit < 0)
+        maxsplit = PY_SSIZE_T_MAX;
+
+    if (subobj == Py_None)
+        return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
+
+    if (_getbuffer(subobj, &vsub) < 0)
+        return NULL;
+    sub = vsub.buf;
+    n = vsub.len;
+
+    list = stringlib_split(
+        (PyObject*) self, s, len, sub, n, maxsplit
+        );
+    PyBuffer_Release(&vsub);
+    return list;
+}
+
+PyDoc_STRVAR(partition__doc__,
+"B.partition(sep) -> (head, sep, tail)\n\
+\n\
+Searches for the separator sep in B, and returns the part before it,\n\
+the separator itself, and the part after it.  If the separator is not\n\
+found, returns B and two empty bytearray objects.");
+
+static PyObject *
+bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
+{
+    PyObject *bytesep, *result;
+
+    bytesep = PyByteArray_FromObject(sep_obj);
+    if (! bytesep)
+        return NULL;
+
+    result = stringlib_partition(
+            (PyObject*) self,
+            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+            bytesep,
+            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
+            );
+
+    Py_DECREF(bytesep);
+    return result;
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+"B.rpartition(sep) -> (head, sep, tail)\n\
+\n\
+Searches for the separator sep in B, starting at the end of B,\n\
+and returns the part before it, the separator itself, and the\n\
+part after it.  If the separator is not found, returns two empty\n\
+bytearray objects and B.");
+
+static PyObject *
+bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
+{
+    PyObject *bytesep, *result;
+
+    bytesep = PyByteArray_FromObject(sep_obj);
+    if (! bytesep)
+        return NULL;
+
+    result = stringlib_rpartition(
+            (PyObject*) self,
+            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+            bytesep,
+            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
+            );
+
+    Py_DECREF(bytesep);
+    return result;
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
+\n\
+Return a list of the sections in B, using sep as the delimiter,\n\
+starting at the end of B and working to the front.\n\
+If sep is not given, B is split on ASCII whitespace characters\n\
+(space, tab, return, newline, formfeed, vertical tab).\n\
+If maxsplit is given, at most maxsplit splits are done.");
+
+static PyObject *
+bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
+    Py_ssize_t maxsplit = -1;
+    const char *s = PyByteArray_AS_STRING(self), *sub;
+    PyObject *list, *subobj = Py_None;
+    Py_buffer vsub;
+
+    if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
+        return NULL;
+    if (maxsplit < 0)
+        maxsplit = PY_SSIZE_T_MAX;
+
+    if (subobj == Py_None)
+        return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
+
+    if (_getbuffer(subobj, &vsub) < 0)
+        return NULL;
+    sub = vsub.buf;
+    n = vsub.len;
+
+    list = stringlib_rsplit(
+        (PyObject*) self, s, len, sub, n, maxsplit
+        );
+    PyBuffer_Release(&vsub);
+    return list;
+}
+
+PyDoc_STRVAR(reverse__doc__,
+"B.reverse() -> None\n\
+\n\
+Reverse the order of the values in B in place.");
+static PyObject *
+bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
+{
+    char swap, *head, *tail;
+    Py_ssize_t i, j, n = Py_SIZE(self);
+
+    j = n / 2;
+    head = self->ob_bytes;
+    tail = head + n - 1;
+    for (i = 0; i < j; i++) {
+        swap = *head;
+        *head++ = *tail;
+        *tail-- = swap;
+    }
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(insert__doc__,
+"B.insert(index, int) -> None\n\
+\n\
+Insert a single item into the bytearray before the given index.");
+static PyObject *
+bytearray_insert(PyByteArrayObject *self, PyObject *args)
+{
+    PyObject *value;
+    int ival;
+    Py_ssize_t where, n = Py_SIZE(self);
+
+    if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
+        return NULL;
+
+    if (n == PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "cannot add more objects to bytearray");
+        return NULL;
+    }
+    if (!_getbytevalue(value, &ival))
+        return NULL;
+    if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
+        return NULL;
+
+    if (where < 0) {
+        where += n;
+        if (where < 0)
+            where = 0;
+    }
+    if (where > n)
+        where = n;
+    memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
+    self->ob_bytes[where] = ival;
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(append__doc__,
+"B.append(int) -> None\n\
+\n\
+Append a single item to the end of B.");
+static PyObject *
+bytearray_append(PyByteArrayObject *self, PyObject *arg)
+{
+    int value;
+    Py_ssize_t n = Py_SIZE(self);
+
+    if (! _getbytevalue(arg, &value))
+        return NULL;
+    if (n == PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "cannot add more objects to bytearray");
+        return NULL;
+    }
+    if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
+        return NULL;
+
+    self->ob_bytes[n] = value;
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(extend__doc__,
+"B.extend(iterable int) -> None\n\
+\n\
+Append all the elements from the iterator or sequence to the\n\
+end of B.");
+static PyObject *
+bytearray_extend(PyByteArrayObject *self, PyObject *arg)
+{
+    PyObject *it, *item, *bytearray_obj;
+    Py_ssize_t buf_size = 0, len = 0;
+    int value;
+    char *buf;
+
+    /* bytearray_setslice code only accepts something supporting PEP 3118. */
+    if (PyObject_CheckBuffer(arg)) {
+        if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
+            return NULL;
+
+        Py_RETURN_NONE;
+    }
+
+    it = PyObject_GetIter(arg);
+    if (it == NULL)
+        return NULL;
+
+    /* Try to determine the length of the argument. 32 is arbitrary. */
+    buf_size = _PyObject_LengthHint(arg, 32);
+    if (buf_size == -1) {
+        Py_DECREF(it);
+        return NULL;
+    }
+
+    bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
+    if (bytearray_obj == NULL) {
+        Py_DECREF(it);
+        return NULL;
+    }
+    buf = PyByteArray_AS_STRING(bytearray_obj);
+
+    while ((item = PyIter_Next(it)) != NULL) {
+        if (! _getbytevalue(item, &value)) {
+            Py_DECREF(item);
+            Py_DECREF(it);
+            Py_DECREF(bytearray_obj);
+            return NULL;
+        }
+        buf[len++] = value;
+        Py_DECREF(item);
+
+        if (len >= buf_size) {
+            buf_size = len + (len >> 1) + 1;
+            if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
+                Py_DECREF(it);
+                Py_DECREF(bytearray_obj);
+                return NULL;
+            }
+            /* Recompute the `buf' pointer, since the resizing operation may
+               have invalidated it. */
+            buf = PyByteArray_AS_STRING(bytearray_obj);
+        }
+    }
+    Py_DECREF(it);
+
+    /* Resize down to exact size. */
+    if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
+        Py_DECREF(bytearray_obj);
+        return NULL;
+    }
+
+    if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
+        Py_DECREF(bytearray_obj);
+        return NULL;
+    }
+    Py_DECREF(bytearray_obj);
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(pop__doc__,
+"B.pop([index]) -> int\n\
+\n\
+Remove and return a single item from B. If no index\n\
+argument is given, will pop the last value.");
+static PyObject *
+bytearray_pop(PyByteArrayObject *self, PyObject *args)
+{
+    int value;
+    Py_ssize_t where = -1, n = Py_SIZE(self);
+
+    if (!PyArg_ParseTuple(args, "|n:pop", &where))
+        return NULL;
+
+    if (n == 0) {
+        PyErr_SetString(PyExc_IndexError,
+                        "pop from empty bytearray");
+        return NULL;
+    }
+    if (where < 0)
+        where += Py_SIZE(self);
+    if (where < 0 || where >= Py_SIZE(self)) {
+        PyErr_SetString(PyExc_IndexError, "pop index out of range");
+        return NULL;
+    }
+    if (!_canresize(self))
+        return NULL;
+
+    value = self->ob_bytes[where];
+    memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
+    if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
+        return NULL;
+
+    return PyInt_FromLong((unsigned char)value);
+}
+
+PyDoc_STRVAR(remove__doc__,
+"B.remove(int) -> None\n\
+\n\
+Remove the first occurance of a value in B.");
+static PyObject *
+bytearray_remove(PyByteArrayObject *self, PyObject *arg)
+{
+    int value;
+    Py_ssize_t where, n = Py_SIZE(self);
+
+    if (! _getbytevalue(arg, &value))
+        return NULL;
+
+    for (where = 0; where < n; where++) {
+        if (self->ob_bytes[where] == value)
+            break;
+    }
+    if (where == n) {
+        PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
+        return NULL;
+    }
+    if (!_canresize(self))
+        return NULL;
+
+    memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
+    if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+/* XXX These two helpers could be optimized if argsize == 1 */
+
+static Py_ssize_t
+lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
+              void *argptr, Py_ssize_t argsize)
+{
+    Py_ssize_t i = 0;
+    while (i < mysize && memchr(argptr, myptr[i], argsize))
+        i++;
+    return i;
+}
+
+static Py_ssize_t
+rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
+              void *argptr, Py_ssize_t argsize)
+{
+    Py_ssize_t i = mysize - 1;
+    while (i >= 0 && memchr(argptr, myptr[i], argsize))
+        i--;
+    return i + 1;
+}
+
+PyDoc_STRVAR(strip__doc__,
+"B.strip([bytes]) -> bytearray\n\
+\n\
+Strip leading and trailing bytes contained in the argument.\n\
+If the argument is omitted, strip ASCII whitespace.");
+static PyObject *
+bytearray_strip(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t left, right, mysize, argsize;
+    void *myptr, *argptr;
+    PyObject *arg = Py_None;
+    Py_buffer varg;
+    if (!PyArg_ParseTuple(args, "|O:strip", &arg))
+        return NULL;
+    if (arg == Py_None) {
+        argptr = "\t\n\r\f\v ";
+        argsize = 6;
+    }
+    else {
+        if (_getbuffer(arg, &varg) < 0)
+            return NULL;
+        argptr = varg.buf;
+        argsize = varg.len;
+    }
+    myptr = self->ob_bytes;
+    mysize = Py_SIZE(self);
+    left = lstrip_helper(myptr, mysize, argptr, argsize);
+    if (left == mysize)
+        right = left;
+    else
+        right = rstrip_helper(myptr, mysize, argptr, argsize);
+    if (arg != Py_None)
+        PyBuffer_Release(&varg);
+    return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+}
+
+PyDoc_STRVAR(lstrip__doc__,
+"B.lstrip([bytes]) -> bytearray\n\
+\n\
+Strip leading bytes contained in the argument.\n\
+If the argument is omitted, strip leading ASCII whitespace.");
+static PyObject *
+bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t left, right, mysize, argsize;
+    void *myptr, *argptr;
+    PyObject *arg = Py_None;
+    Py_buffer varg;
+    if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
+        return NULL;
+    if (arg == Py_None) {
+        argptr = "\t\n\r\f\v ";
+        argsize = 6;
+    }
+    else {
+        if (_getbuffer(arg, &varg) < 0)
+            return NULL;
+        argptr = varg.buf;
+        argsize = varg.len;
+    }
+    myptr = self->ob_bytes;
+    mysize = Py_SIZE(self);
+    left = lstrip_helper(myptr, mysize, argptr, argsize);
+    right = mysize;
+    if (arg != Py_None)
+        PyBuffer_Release(&varg);
+    return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+}
+
+PyDoc_STRVAR(rstrip__doc__,
+"B.rstrip([bytes]) -> bytearray\n\
+\n\
+Strip trailing bytes contained in the argument.\n\
+If the argument is omitted, strip trailing ASCII whitespace.");
+static PyObject *
+bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
+{
+    Py_ssize_t left, right, mysize, argsize;
+    void *myptr, *argptr;
+    PyObject *arg = Py_None;
+    Py_buffer varg;
+    if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
+        return NULL;
+    if (arg == Py_None) {
+        argptr = "\t\n\r\f\v ";
+        argsize = 6;
+    }
+    else {
+        if (_getbuffer(arg, &varg) < 0)
+            return NULL;
+        argptr = varg.buf;
+        argsize = varg.len;
+    }
+    myptr = self->ob_bytes;
+    mysize = Py_SIZE(self);
+    left = 0;
+    right = rstrip_helper(myptr, mysize, argptr, argsize);
+    if (arg != Py_None)
+        PyBuffer_Release(&varg);
+    return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+}
+
+PyDoc_STRVAR(decode_doc,
+"B.decode([encoding[, errors]]) -> unicode object.\n\
+\n\
+Decodes B using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme.  Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError.  Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registered with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    const char *encoding = NULL;
+    const char *errors = NULL;
+    static char *kwlist[] = {"encoding", "errors", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
+        return NULL;
+    if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+        encoding = PyUnicode_GetDefaultEncoding();
+#else
+        PyErr_SetString(PyExc_ValueError, "no encoding specified");
+        return NULL;
+#endif
+    }
+    return PyCodec_Decode(self, encoding, errors);
+}
+
+PyDoc_STRVAR(alloc_doc,
+"B.__alloc__() -> int\n\
+\n\
+Returns the number of bytes actually allocated.");
+
+static PyObject *
+bytearray_alloc(PyByteArrayObject *self)
+{
+    return PyInt_FromSsize_t(self->ob_alloc);
+}
+
+PyDoc_STRVAR(join_doc,
+"B.join(iterable_of_bytes) -> bytes\n\
+\n\
+Concatenates any number of bytearray objects, with B in between each pair.");
+
+static PyObject *
+bytearray_join(PyByteArrayObject *self, PyObject *it)
+{
+    PyObject *seq;
+    Py_ssize_t mysize = Py_SIZE(self);
+    Py_ssize_t i;
+    Py_ssize_t n;
+    PyObject **items;
+    Py_ssize_t totalsize = 0;
+    PyObject *result;
+    char *dest;
+
+    seq = PySequence_Fast(it, "can only join an iterable");
+    if (seq == NULL)
+        return NULL;
+    n = PySequence_Fast_GET_SIZE(seq);
+    items = PySequence_Fast_ITEMS(seq);
+
+    /* Compute the total size, and check that they are all bytes */
+    /* XXX Shouldn't we use _getbuffer() on these items instead? */
+    for (i = 0; i < n; i++) {
+        PyObject *obj = items[i];
+        if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
+            PyErr_Format(PyExc_TypeError,
+                         "can only join an iterable of bytes "
+                         "(item %ld has type '%.100s')",
+                         /* XXX %ld isn't right on Win64 */
+                         (long)i, Py_TYPE(obj)->tp_name);
+            goto error;
+        }
+        if (i > 0)
+            totalsize += mysize;
+        totalsize += Py_SIZE(obj);
+        if (totalsize < 0) {
+            PyErr_NoMemory();
+            goto error;
+        }
+    }
+
+    /* Allocate the result, and copy the bytes */
+    result = PyByteArray_FromStringAndSize(NULL, totalsize);
+    if (result == NULL)
+        goto error;
+    dest = PyByteArray_AS_STRING(result);
+    for (i = 0; i < n; i++) {
+        PyObject *obj = items[i];
+        Py_ssize_t size = Py_SIZE(obj);
+        char *buf;
+        if (PyByteArray_Check(obj))
+           buf = PyByteArray_AS_STRING(obj);
+        else
+           buf = PyBytes_AS_STRING(obj);
+        if (i) {
+            memcpy(dest, self->ob_bytes, mysize);
+            dest += mysize;
+        }
+        memcpy(dest, buf, size);
+        dest += size;
+    }
+
+    /* Done */
+    Py_DECREF(seq);
+    return result;
+
+    /* Error handling */
+  error:
+    Py_DECREF(seq);
+    return NULL;
+}
+
+PyDoc_STRVAR(splitlines__doc__,
+"B.splitlines(keepends=False) -> list of lines\n\
+\n\
+Return a list of the lines in B, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+bytearray_splitlines(PyObject *self, PyObject *args)
+{
+    int keepends = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+        return NULL;
+
+    return stringlib_splitlines(
+        (PyObject*) self, PyByteArray_AS_STRING(self),
+        PyByteArray_GET_SIZE(self), keepends
+        );
+}
+
+PyDoc_STRVAR(fromhex_doc,
+"bytearray.fromhex(string) -> bytearray\n\
+\n\
+Create a bytearray object from a string of hexadecimal numbers.\n\
+Spaces between two numbers are accepted.\n\
+Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
+
+static int
+hex_digit_to_int(char c)
+{
+    if (Py_ISDIGIT(c))
+        return c - '0';
+    else {
+        if (Py_ISUPPER(c))
+            c = Py_TOLOWER(c);
+        if (c >= 'a' && c <= 'f')
+            return c - 'a' + 10;
+    }
+    return -1;
+}
+
+static PyObject *
+bytearray_fromhex(PyObject *cls, PyObject *args)
+{
+    PyObject *newbytes;
+    char *buf;
+    char *hex;
+    Py_ssize_t hexlen, byteslen, i, j;
+    int top, bot;
+
+    if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
+        return NULL;
+    byteslen = hexlen/2; /* This overestimates if there are spaces */
+    newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
+    if (!newbytes)
+        return NULL;
+    buf = PyByteArray_AS_STRING(newbytes);
+    for (i = j = 0; i < hexlen; i += 2) {
+        /* skip over spaces in the input */
+        while (hex[i] == ' ')
+            i++;
+        if (i >= hexlen)
+            break;
+        top = hex_digit_to_int(hex[i]);
+        bot = hex_digit_to_int(hex[i+1]);
+        if (top == -1 || bot == -1) {
+            PyErr_Format(PyExc_ValueError,
+                         "non-hexadecimal number found in "
+                         "fromhex() arg at position %zd", i);
+            goto error;
+        }
+        buf[j++] = (top << 4) + bot;
+    }
+    if (PyByteArray_Resize(newbytes, j) < 0)
+        goto error;
+    return newbytes;
+
+  error:
+    Py_DECREF(newbytes);
+    return NULL;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyObject *
+bytearray_reduce(PyByteArrayObject *self)
+{
+    PyObject *latin1, *dict;
+    if (self->ob_bytes)
+#ifdef Py_USING_UNICODE
+        latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
+                                        Py_SIZE(self), NULL);
+#else
+        latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
+#endif
+    else
+#ifdef Py_USING_UNICODE
+        latin1 = PyUnicode_FromString("");
+#else
+        latin1 = PyString_FromString("");
+#endif
+
+    dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
+    if (dict == NULL) {
+        PyErr_Clear();
+        dict = Py_None;
+        Py_INCREF(dict);
+    }
+
+    return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
+}
+
+PyDoc_STRVAR(sizeof_doc,
+"B.__sizeof__() -> int\n\
+ \n\
+Returns the size of B in memory, in bytes");
+static PyObject *
+bytearray_sizeof(PyByteArrayObject *self)
+{
+    Py_ssize_t res;
+
+    res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
+    return PyInt_FromSsize_t(res);
+}
+
+static PySequenceMethods bytearray_as_sequence = {
+    (lenfunc)bytearray_length,              /* sq_length */
+    (binaryfunc)PyByteArray_Concat,         /* sq_concat */
+    (ssizeargfunc)bytearray_repeat,         /* sq_repeat */
+    (ssizeargfunc)bytearray_getitem,        /* sq_item */
+    0,                                      /* sq_slice */
+    (ssizeobjargproc)bytearray_setitem,     /* sq_ass_item */
+    0,                                      /* sq_ass_slice */
+    (objobjproc)bytearray_contains,         /* sq_contains */
+    (binaryfunc)bytearray_iconcat,          /* sq_inplace_concat */
+    (ssizeargfunc)bytearray_irepeat,        /* sq_inplace_repeat */
+};
+
+static PyMappingMethods bytearray_as_mapping = {
+    (lenfunc)bytearray_length,
+    (binaryfunc)bytearray_subscript,
+    (objobjargproc)bytearray_ass_subscript,
+};
+
+static PyBufferProcs bytearray_as_buffer = {
+    (readbufferproc)bytearray_buffer_getreadbuf,
+    (writebufferproc)bytearray_buffer_getwritebuf,
+    (segcountproc)bytearray_buffer_getsegcount,
+    (charbufferproc)bytearray_buffer_getcharbuf,
+    (getbufferproc)bytearray_getbuffer,
+    (releasebufferproc)bytearray_releasebuffer,
+};
+
+static PyMethodDef
+bytearray_methods[] = {
+    {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
+    {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
+    {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
+    {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
+    {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
+     _Py_capitalize__doc__},
+    {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
+    {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
+    {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
+    {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
+    {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
+     expandtabs__doc__},
+    {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
+    {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
+    {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
+     fromhex_doc},
+    {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
+    {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
+    {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
+     _Py_isalnum__doc__},
+    {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
+     _Py_isalpha__doc__},
+    {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
+     _Py_isdigit__doc__},
+    {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
+     _Py_islower__doc__},
+    {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
+     _Py_isspace__doc__},
+    {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
+     _Py_istitle__doc__},
+    {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
+     _Py_isupper__doc__},
+    {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
+    {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
+    {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
+    {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
+    {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
+    {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
+    {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
+    {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
+    {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
+    {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
+    {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
+    {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
+    {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
+    {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
+    {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
+    {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
+    {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
+     splitlines__doc__},
+    {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
+     startswith__doc__},
+    {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
+    {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
+     _Py_swapcase__doc__},
+    {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
+    {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
+     translate__doc__},
+    {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
+    {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
+    {NULL}
+};
+
+PyDoc_STRVAR(bytearray_doc,
+"bytearray(iterable_of_ints) -> bytearray.\n\
+bytearray(string, encoding[, errors]) -> bytearray.\n\
+bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
+bytearray(memory_view) -> bytearray.\n\
+\n\
+Construct an mutable bytearray object from:\n\
+  - an iterable yielding integers in range(256)\n\
+  - a text string encoded using the specified encoding\n\
+  - a bytes or a bytearray object\n\
+  - any object implementing the buffer API.\n\
+\n\
+bytearray(int) -> bytearray.\n\
+\n\
+Construct a zero-initialized bytearray of the given length.");
+
+
+static PyObject *bytearray_iter(PyObject *seq);
+
+PyTypeObject PyByteArray_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "bytearray",
+    sizeof(PyByteArrayObject),
+    0,
+    (destructor)bytearray_dealloc,       /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    0,                                  /* tp_compare */
+    (reprfunc)bytearray_repr,           /* tp_repr */
+    0,                                  /* tp_as_number */
+    &bytearray_as_sequence,             /* tp_as_sequence */
+    &bytearray_as_mapping,              /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    0,                                  /* tp_call */
+    bytearray_str,                      /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    &bytearray_as_buffer,               /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+    Py_TPFLAGS_HAVE_NEWBUFFER,          /* tp_flags */
+    bytearray_doc,                      /* tp_doc */
+    0,                                  /* tp_traverse */
+    0,                                  /* tp_clear */
+    (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    bytearray_iter,                     /* tp_iter */
+    0,                                  /* tp_iternext */
+    bytearray_methods,                  /* tp_methods */
+    0,                                  /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
+    0,                                  /* tp_dictoffset */
+    (initproc)bytearray_init,           /* tp_init */
+    PyType_GenericAlloc,                /* tp_alloc */
+    PyType_GenericNew,                  /* tp_new */
+    PyObject_Del,                       /* tp_free */
+};
+
+/*********************** Bytes Iterator ****************************/
+
+typedef struct {
+    PyObject_HEAD
+    Py_ssize_t it_index;
+    PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
+} bytesiterobject;
+
+static void
+bytearrayiter_dealloc(bytesiterobject *it)
+{
+    _PyObject_GC_UNTRACK(it);
+    Py_XDECREF(it->it_seq);
+    PyObject_GC_Del(it);
+}
+
+static int
+bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
+{
+    Py_VISIT(it->it_seq);
+    return 0;
+}
+
+static PyObject *
+bytearrayiter_next(bytesiterobject *it)
+{
+    PyByteArrayObject *seq;
+    PyObject *item;
+
+    assert(it != NULL);
+    seq = it->it_seq;
+    if (seq == NULL)
+        return NULL;
+    assert(PyByteArray_Check(seq));
+
+    if (it->it_index < PyByteArray_GET_SIZE(seq)) {
+        item = PyInt_FromLong(
+            (unsigned char)seq->ob_bytes[it->it_index]);
+        if (item != NULL)
+            ++it->it_index;
+        return item;
+    }
+
+    Py_DECREF(seq);
+    it->it_seq = NULL;
+    return NULL;
+}
+
+static PyObject *
+bytesarrayiter_length_hint(bytesiterobject *it)
+{
+    Py_ssize_t len = 0;
+    if (it->it_seq)
+        len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
+    return PyInt_FromSsize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc,
+    "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef bytearrayiter_methods[] = {
+    {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
+     length_hint_doc},
+    {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyByteArrayIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "bytearray_iterator",              /* tp_name */
+    sizeof(bytesiterobject),           /* tp_basicsize */
+    0,                                 /* tp_itemsize */
+    /* methods */
+    (destructor)bytearrayiter_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 */
+    0,                                 /* tp_str */
+    PyObject_GenericGetAttr,           /* tp_getattro */
+    0,                                 /* tp_setattro */
+    0,                                 /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                 /* tp_doc */
+    (traverseproc)bytearrayiter_traverse,  /* tp_traverse */
+    0,                                 /* tp_clear */
+    0,                                 /* tp_richcompare */
+    0,                                 /* tp_weaklistoffset */
+    PyObject_SelfIter,                 /* tp_iter */
+    (iternextfunc)bytearrayiter_next,  /* tp_iternext */
+    bytearrayiter_methods,             /* tp_methods */
+    0,
+};
+
+static PyObject *
+bytearray_iter(PyObject *seq)
+{
+    bytesiterobject *it;
+
+    if (!PyByteArray_Check(seq)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
+    if (it == NULL)
+        return NULL;
+    it->it_index = 0;
+    Py_INCREF(seq);
+    it->it_seq = (PyByteArrayObject *)seq;
+    _PyObject_GC_TRACK(it);
+    return (PyObject *)it;
+}
diff --git a/Python-2.7.5/Objects/bytes_methods.c b/Python-2.7.5/Objects/bytes_methods.c
new file mode 100644
index 0000000..1406ac1
--- /dev/null
+++ b/Python-2.7.5/Objects/bytes_methods.c
@@ -0,0 +1,398 @@
+#include "Python.h"
+#include "bytes_methods.h"
+
+PyDoc_STRVAR_shared(_Py_isspace__doc__,
+"B.isspace() -> bool\n\
+\n\
+Return True if all characters in B are whitespace\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isspace(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (len == 1 && Py_ISSPACE(*p))
+        Py_RETURN_TRUE;
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    for (; p < e; p++) {
+        if (!Py_ISSPACE(*p))
+            Py_RETURN_FALSE;
+    }
+    Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_isalpha__doc__,
+"B.isalpha() -> bool\n\
+\n\
+Return True if all characters in B are alphabetic\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isalpha(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (len == 1 && Py_ISALPHA(*p))
+        Py_RETURN_TRUE;
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    for (; p < e; p++) {
+        if (!Py_ISALPHA(*p))
+            Py_RETURN_FALSE;
+    }
+    Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_isalnum__doc__,
+"B.isalnum() -> bool\n\
+\n\
+Return True if all characters in B are alphanumeric\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (len == 1 && Py_ISALNUM(*p))
+        Py_RETURN_TRUE;
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    for (; p < e; p++) {
+        if (!Py_ISALNUM(*p))
+            Py_RETURN_FALSE;
+    }
+    Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_isdigit__doc__,
+"B.isdigit() -> bool\n\
+\n\
+Return True if all characters in B are digits\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isdigit(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (len == 1 && Py_ISDIGIT(*p))
+        Py_RETURN_TRUE;
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    for (; p < e; p++) {
+        if (!Py_ISDIGIT(*p))
+            Py_RETURN_FALSE;
+    }
+    Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_islower__doc__,
+"B.islower() -> bool\n\
+\n\
+Return True if all cased characters in B are lowercase and there is\n\
+at least one cased character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_islower(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (len == 1)
+        return PyBool_FromLong(Py_ISLOWER(*p));
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    cased = 0;
+    for (; p < e; p++) {
+        if (Py_ISUPPER(*p))
+            Py_RETURN_FALSE;
+        else if (!cased && Py_ISLOWER(*p))
+            cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR_shared(_Py_isupper__doc__,
+"B.isupper() -> bool\n\
+\n\
+Return True if all cased characters in B are uppercase and there is\n\
+at least one cased character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isupper(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (len == 1)
+        return PyBool_FromLong(Py_ISUPPER(*p));
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    cased = 0;
+    for (; p < e; p++) {
+        if (Py_ISLOWER(*p))
+            Py_RETURN_FALSE;
+        else if (!cased && Py_ISUPPER(*p))
+            cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR_shared(_Py_istitle__doc__,
+"B.istitle() -> bool\n\
+\n\
+Return True if B is a titlecased string and there is at least one\n\
+character in B, i.e. uppercase characters may only follow uncased\n\
+characters and lowercase characters only cased ones. Return False\n\
+otherwise.");
+
+PyObject*
+_Py_bytes_istitle(const char *cptr, Py_ssize_t len)
+{
+    register const unsigned char *p
+        = (unsigned char *) cptr;
+    register const unsigned char *e;
+    int cased, previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (len == 1)
+        return PyBool_FromLong(Py_ISUPPER(*p));
+
+    /* Special case for empty strings */
+    if (len == 0)
+        Py_RETURN_FALSE;
+
+    e = p + len;
+    cased = 0;
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+        register const unsigned char ch = *p;
+
+        if (Py_ISUPPER(ch)) {
+            if (previous_is_cased)
+                Py_RETURN_FALSE;
+            previous_is_cased = 1;
+            cased = 1;
+        }
+        else if (Py_ISLOWER(ch)) {
+            if (!previous_is_cased)
+                Py_RETURN_FALSE;
+            previous_is_cased = 1;
+            cased = 1;
+        }
+        else
+            previous_is_cased = 0;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR_shared(_Py_lower__doc__,
+"B.lower() -> copy of B\n\
+\n\
+Return a copy of B with all ASCII characters converted to lowercase.");
+
+void
+_Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len)
+{
+        Py_ssize_t i;
+
+        /*
+        newobj = PyString_FromStringAndSize(NULL, len);
+        if (!newobj)
+                return NULL;
+
+        s = PyString_AS_STRING(newobj);
+        */
+
+        Py_MEMCPY(result, cptr, len);
+
+        for (i = 0; i < len; i++) {
+                int c = Py_CHARMASK(result[i]);
+                if (Py_ISUPPER(c))
+                        result[i] = Py_TOLOWER(c);
+        }
+}
+
+
+PyDoc_STRVAR_shared(_Py_upper__doc__,
+"B.upper() -> copy of B\n\
+\n\
+Return a copy of B with all ASCII characters converted to uppercase.");
+
+void
+_Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
+{
+        Py_ssize_t i;
+
+        /*
+        newobj = PyString_FromStringAndSize(NULL, len);
+        if (!newobj)
+                return NULL;
+
+        s = PyString_AS_STRING(newobj);
+        */
+
+        Py_MEMCPY(result, cptr, len);
+
+        for (i = 0; i < len; i++) {
+                int c = Py_CHARMASK(result[i]);
+                if (Py_ISLOWER(c))
+                        result[i] = Py_TOUPPER(c);
+        }
+}
+
+
+PyDoc_STRVAR_shared(_Py_title__doc__,
+"B.title() -> copy of B\n\
+\n\
+Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
+characters, all remaining cased characters have lowercase.");
+
+void
+_Py_bytes_title(char *result, char *s, Py_ssize_t len)
+{
+        Py_ssize_t i;
+        int previous_is_cased = 0;
+
+        /*
+        newobj = PyString_FromStringAndSize(NULL, len);
+        if (newobj == NULL)
+                return NULL;
+        s_new = PyString_AsString(newobj);
+        */
+        for (i = 0; i < len; i++) {
+                int c = Py_CHARMASK(*s++);
+                if (Py_ISLOWER(c)) {
+                        if (!previous_is_cased)
+                            c = Py_TOUPPER(c);
+                        previous_is_cased = 1;
+                } else if (Py_ISUPPER(c)) {
+                        if (previous_is_cased)
+                            c = Py_TOLOWER(c);
+                        previous_is_cased = 1;
+                } else
+                        previous_is_cased = 0;
+                *result++ = c;
+        }
+}
+
+
+PyDoc_STRVAR_shared(_Py_capitalize__doc__,
+"B.capitalize() -> copy of B\n\
+\n\
+Return a copy of B with only its first character capitalized (ASCII)\n\
+and the rest lower-cased.");
+
+void
+_Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
+{
+        Py_ssize_t i;
+
+        /*
+        newobj = PyString_FromStringAndSize(NULL, len);
+        if (newobj == NULL)
+                return NULL;
+        s_new = PyString_AsString(newobj);
+        */
+        if (0 < len) {
+                int c = Py_CHARMASK(*s++);
+                if (Py_ISLOWER(c))
+                        *result = Py_TOUPPER(c);
+                else
+                        *result = c;
+                result++;
+        }
+        for (i = 1; i < len; i++) {
+                int c = Py_CHARMASK(*s++);
+                if (Py_ISUPPER(c))
+                        *result = Py_TOLOWER(c);
+                else
+                        *result = c;
+                result++;
+        }
+}
+
+
+PyDoc_STRVAR_shared(_Py_swapcase__doc__,
+"B.swapcase() -> copy of B\n\
+\n\
+Return a copy of B with uppercase ASCII characters converted\n\
+to lowercase ASCII and vice versa.");
+
+void
+_Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
+{
+        Py_ssize_t i;
+
+        /*
+        newobj = PyString_FromStringAndSize(NULL, len);
+        if (newobj == NULL)
+                return NULL;
+        s_new = PyString_AsString(newobj);
+        */
+        for (i = 0; i < len; i++) {
+                int c = Py_CHARMASK(*s++);
+                if (Py_ISLOWER(c)) {
+                        *result = Py_TOUPPER(c);
+                }
+                else if (Py_ISUPPER(c)) {
+                        *result = Py_TOLOWER(c);
+                }
+                else
+                        *result = c;
+                result++;
+        }
+}
+
diff --git a/Python-2.7.5/Objects/capsule.c b/Python-2.7.5/Objects/capsule.c
new file mode 100644
index 0000000..ea20f82
--- /dev/null
+++ b/Python-2.7.5/Objects/capsule.c
@@ -0,0 +1,324 @@
+/* Wrap void * pointers to be passed between C modules */
+
+#include "Python.h"
+
+/* Internal structure of PyCapsule */
+typedef struct {
+    PyObject_HEAD
+    void *pointer;
+    const char *name;
+    void *context;
+    PyCapsule_Destructor destructor;
+} PyCapsule;
+
+
+
+static int
+_is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
+{
+    if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
+        PyErr_SetString(PyExc_ValueError, invalid_capsule);
+        return 0;
+    }
+    return 1;
+}
+
+#define is_legal_capsule(capsule, name) \
+    (_is_legal_capsule(capsule, \
+     name " called with invalid PyCapsule object"))
+
+
+static int
+name_matches(const char *name1, const char *name2) {
+    /* if either is NULL, */
+    if (!name1 || !name2) {
+        /* they're only the same if they're both NULL. */
+        return name1 == name2;
+    }
+    return !strcmp(name1, name2);
+}
+
+
+
+PyObject *
+PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
+{
+    PyCapsule *capsule;
+
+    if (!pointer) {
+        PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
+        return NULL;
+    }
+
+    capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
+    if (capsule == NULL) {
+        return NULL;
+    }
+
+    capsule->pointer = pointer;
+    capsule->name = name;
+    capsule->context = NULL;
+    capsule->destructor = destructor;
+
+    return (PyObject *)capsule;
+}
+
+
+int
+PyCapsule_IsValid(PyObject *o, const char *name)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    return (capsule != NULL &&
+            PyCapsule_CheckExact(capsule) &&
+            capsule->pointer != NULL &&
+            name_matches(capsule->name, name));
+}
+
+
+void *
+PyCapsule_GetPointer(PyObject *o, const char *name)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
+        return NULL;
+    }
+
+    if (!name_matches(name, capsule->name)) {
+        PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
+        return NULL;
+    }
+
+    return capsule->pointer;
+}
+
+
+const char *
+PyCapsule_GetName(PyObject *o)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
+        return NULL;
+    }
+    return capsule->name;
+}
+
+
+PyCapsule_Destructor
+PyCapsule_GetDestructor(PyObject *o)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
+        return NULL;
+    }
+    return capsule->destructor;
+}
+
+
+void *
+PyCapsule_GetContext(PyObject *o)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
+        return NULL;
+    }
+    return capsule->context;
+}
+
+
+int
+PyCapsule_SetPointer(PyObject *o, void *pointer)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!pointer) {
+        PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
+        return -1;
+    }
+
+    if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
+        return -1;
+    }
+
+    capsule->pointer = pointer;
+    return 0;
+}
+
+
+int
+PyCapsule_SetName(PyObject *o, const char *name)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
+        return -1;
+    }
+
+    capsule->name = name;
+    return 0;
+}
+
+
+int
+PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
+        return -1;
+    }
+
+    capsule->destructor = destructor;
+    return 0;
+}
+
+
+int
+PyCapsule_SetContext(PyObject *o, void *context)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+
+    if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
+        return -1;
+    }
+
+    capsule->context = context;
+    return 0;
+}
+
+
+void *
+PyCapsule_Import(const char *name, int no_block)
+{
+    PyObject *object = NULL;
+    void *return_value = NULL;
+    char *trace;
+    size_t name_length = (strlen(name) + 1) * sizeof(char);
+    char *name_dup = (char *)PyMem_MALLOC(name_length);
+
+    if (!name_dup) {
+        return NULL;
+    }
+
+    memcpy(name_dup, name, name_length);
+
+    trace = name_dup;
+    while (trace) {
+        char *dot = strchr(trace, '.');
+        if (dot) {
+            *dot++ = '\0';
+        }
+
+        if (object == NULL) {
+            if (no_block) {
+                object = PyImport_ImportModuleNoBlock(trace);
+            } else {
+                object = PyImport_ImportModule(trace);
+                if (!object) {
+                    PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
+                }
+            }
+        } else {
+            PyObject *object2 = PyObject_GetAttrString(object, trace);
+            Py_DECREF(object);
+            object = object2;
+        }
+        if (!object) {
+            goto EXIT;
+        }
+
+        trace = dot;
+    }
+
+    /* compare attribute name to module.name by hand */
+    if (PyCapsule_IsValid(object, name)) {
+        PyCapsule *capsule = (PyCapsule *)object;
+        return_value = capsule->pointer;
+    } else {
+        PyErr_Format(PyExc_AttributeError,
+            "PyCapsule_Import \"%s\" is not valid",
+            name);
+    }
+
+EXIT:
+    Py_XDECREF(object);
+    if (name_dup) {
+        PyMem_FREE(name_dup);
+    }
+    return return_value;
+}
+
+
+static void
+capsule_dealloc(PyObject *o)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+    if (capsule->destructor) {
+        capsule->destructor(o);
+    }
+    PyObject_DEL(o);
+}
+
+
+static PyObject *
+capsule_repr(PyObject *o)
+{
+    PyCapsule *capsule = (PyCapsule *)o;
+    const char *name;
+    const char *quote;
+
+    if (capsule->name) {
+        quote = "\"";
+        name = capsule->name;
+    } else {
+        quote = "";
+        name = "NULL";
+    }
+
+    return PyString_FromFormat("<capsule object %s%s%s at %p>",
+        quote, name, quote, capsule);
+}
+
+
+
+PyDoc_STRVAR(PyCapsule_Type__doc__,
+"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
+object.  They're a way of passing data through the Python interpreter\n\
+without creating your own custom type.\n\
+\n\
+Capsules are used for communication between extension modules.\n\
+They provide a way for an extension module to export a C interface\n\
+to other extension modules, so that extension modules can use the\n\
+Python import mechanism to link to one another.\n\
+");
+
+PyTypeObject PyCapsule_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "PyCapsule",		/*tp_name*/
+    sizeof(PyCapsule),		/*tp_basicsize*/
+    0,				/*tp_itemsize*/
+    /* methods */
+    capsule_dealloc, /*tp_dealloc*/
+    0,				/*tp_print*/
+    0,				/*tp_getattr*/
+    0,				/*tp_setattr*/
+    0,				/*tp_reserved*/
+    capsule_repr, /*tp_repr*/
+    0,				/*tp_as_number*/
+    0,				/*tp_as_sequence*/
+    0,				/*tp_as_mapping*/
+    0,				/*tp_hash*/
+    0,				/*tp_call*/
+    0,				/*tp_str*/
+    0,				/*tp_getattro*/
+    0,				/*tp_setattro*/
+    0,				/*tp_as_buffer*/
+    0,				/*tp_flags*/
+    PyCapsule_Type__doc__	/*tp_doc*/
+};
+
+
diff --git a/Python-2.7.5/Objects/cellobject.c b/Python-2.7.5/Objects/cellobject.c
new file mode 100644
index 0000000..d0f6cda
--- /dev/null
+++ b/Python-2.7.5/Objects/cellobject.c
@@ -0,0 +1,145 @@
+/* Cell object implementation */
+
+#include "Python.h"
+
+PyObject *
+PyCell_New(PyObject *obj)
+{
+    PyCellObject *op;
+
+    op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
+    if (op == NULL)
+        return NULL;
+    op->ob_ref = obj;
+    Py_XINCREF(obj);
+
+    _PyObject_GC_TRACK(op);
+    return (PyObject *)op;
+}
+
+PyObject *
+PyCell_Get(PyObject *op)
+{
+    if (!PyCell_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    Py_XINCREF(((PyCellObject*)op)->ob_ref);
+    return PyCell_GET(op);
+}
+
+int
+PyCell_Set(PyObject *op, PyObject *obj)
+{
+    PyObject* oldobj;
+    if (!PyCell_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    oldobj = PyCell_GET(op);
+    Py_XINCREF(obj);
+    PyCell_SET(op, obj);
+    Py_XDECREF(oldobj);
+    return 0;
+}
+
+static void
+cell_dealloc(PyCellObject *op)
+{
+    _PyObject_GC_UNTRACK(op);
+    Py_XDECREF(op->ob_ref);
+    PyObject_GC_Del(op);
+}
+
+static int
+cell_compare(PyCellObject *a, PyCellObject *b)
+{
+    /* Py3K warning for comparisons  */
+    if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
+                       1) < 0) {
+        return -2;
+    }
+
+    if (a->ob_ref == NULL) {
+        if (b->ob_ref == NULL)
+            return 0;
+        return -1;
+    } else if (b->ob_ref == NULL)
+        return 1;
+    return PyObject_Compare(a->ob_ref, b->ob_ref);
+}
+
+static PyObject *
+cell_repr(PyCellObject *op)
+{
+    if (op->ob_ref == NULL)
+        return PyString_FromFormat("<cell at %p: empty>", op);
+
+    return PyString_FromFormat("<cell at %p: %.80s object at %p>",
+                               op, op->ob_ref->ob_type->tp_name,
+                               op->ob_ref);
+}
+
+static int
+cell_traverse(PyCellObject *op, visitproc visit, void *arg)
+{
+    Py_VISIT(op->ob_ref);
+    return 0;
+}
+
+static int
+cell_clear(PyCellObject *op)
+{
+    Py_CLEAR(op->ob_ref);
+    return 0;
+}
+
+static PyObject *
+cell_get_contents(PyCellObject *op, void *closure)
+{
+    if (op->ob_ref == NULL)
+    {
+        PyErr_SetString(PyExc_ValueError, "Cell is empty");
+        return NULL;
+    }
+    Py_INCREF(op->ob_ref);
+    return op->ob_ref;
+}
+
+static PyGetSetDef cell_getsetlist[] = {
+    {"cell_contents", (getter)cell_get_contents, NULL},
+    {NULL} /* sentinel */
+};
+
+PyTypeObject PyCell_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "cell",
+    sizeof(PyCellObject),
+    0,
+    (destructor)cell_dealloc,               /* tp_dealloc */
+    0,                                      /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)cell_compare,                      /* tp_compare */
+    (reprfunc)cell_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)cell_traverse,                /* tp_traverse */
+    (inquiry)cell_clear,                        /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+    cell_getsetlist,                            /* tp_getset */
+};
diff --git a/Python-2.7.5/Objects/classobject.c b/Python-2.7.5/Objects/classobject.c
new file mode 100644
index 0000000..2c9c216
--- /dev/null
+++ b/Python-2.7.5/Objects/classobject.c
@@ -0,0 +1,2696 @@
+
+/* Class object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Free list for method objects to safe malloc/free overhead
+ * The im_self element is used to chain the elements.
+ */
+static PyMethodObject *free_list;
+static int numfree = 0;
+#ifndef PyMethod_MAXFREELIST
+#define PyMethod_MAXFREELIST 256
+#endif
+
+#define TP_DESCR_GET(t) \
+    (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
+
+/* Forward */
+static PyObject *class_lookup(PyClassObject *, PyObject *,
+                              PyClassObject **);
+static PyObject *instance_getattr1(PyInstanceObject *, PyObject *);
+static PyObject *instance_getattr2(PyInstanceObject *, PyObject *);
+
+static PyObject *getattrstr, *setattrstr, *delattrstr;
+
+
+PyObject *
+PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
+     /* bases is NULL or tuple of classobjects! */
+{
+    PyClassObject *op, *dummy;
+    static PyObject *docstr, *modstr, *namestr;
+    if (docstr == NULL) {
+        docstr= PyString_InternFromString("__doc__");
+        if (docstr == NULL)
+            return NULL;
+    }
+    if (modstr == NULL) {
+        modstr= PyString_InternFromString("__module__");
+        if (modstr == NULL)
+            return NULL;
+    }
+    if (namestr == NULL) {
+        namestr= PyString_InternFromString("__name__");
+        if (namestr == NULL)
+            return NULL;
+    }
+    if (name == NULL || !PyString_Check(name)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "PyClass_New: name must be a string");
+        return NULL;
+    }
+    if (dict == NULL || !PyDict_Check(dict)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "PyClass_New: dict must be a dictionary");
+        return NULL;
+    }
+    if (PyDict_GetItem(dict, docstr) == NULL) {
+        if (PyDict_SetItem(dict, docstr, Py_None) < 0)
+            return NULL;
+    }
+    if (PyDict_GetItem(dict, modstr) == NULL) {
+        PyObject *globals = PyEval_GetGlobals();
+        if (globals != NULL) {
+            PyObject *modname = PyDict_GetItem(globals, namestr);
+            if (modname != NULL) {
+                if (PyDict_SetItem(dict, modstr, modname) < 0)
+                    return NULL;
+            }
+        }
+    }
+    if (bases == NULL) {
+        bases = PyTuple_New(0);
+        if (bases == NULL)
+            return NULL;
+    }
+    else {
+        Py_ssize_t i, n;
+        PyObject *base;
+        if (!PyTuple_Check(bases)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "PyClass_New: bases must be a tuple");
+            return NULL;
+        }
+        n = PyTuple_Size(bases);
+        for (i = 0; i < n; i++) {
+            base = PyTuple_GET_ITEM(bases, i);
+            if (!PyClass_Check(base)) {
+                if (PyCallable_Check(
+                    (PyObject *) base->ob_type))
+                    return PyObject_CallFunctionObjArgs(
+                        (PyObject *) base->ob_type,
+                        name, bases, dict, NULL);
+                PyErr_SetString(PyExc_TypeError,
+                    "PyClass_New: base must be a class");
+                return NULL;
+            }
+        }
+        Py_INCREF(bases);
+    }
+
+    if (getattrstr == NULL) {
+        getattrstr = PyString_InternFromString("__getattr__");
+        if (getattrstr == NULL)
+            goto alloc_error;
+        setattrstr = PyString_InternFromString("__setattr__");
+        if (setattrstr == NULL)
+            goto alloc_error;
+        delattrstr = PyString_InternFromString("__delattr__");
+        if (delattrstr == NULL)
+            goto alloc_error;
+    }
+
+    op = PyObject_GC_New(PyClassObject, &PyClass_Type);
+    if (op == NULL) {
+alloc_error:
+        Py_DECREF(bases);
+        return NULL;
+    }
+    op->cl_bases = bases;
+    Py_INCREF(dict);
+    op->cl_dict = dict;
+    Py_XINCREF(name);
+    op->cl_name = name;
+    op->cl_weakreflist = NULL;
+
+    op->cl_getattr = class_lookup(op, getattrstr, &dummy);
+    op->cl_setattr = class_lookup(op, setattrstr, &dummy);
+    op->cl_delattr = class_lookup(op, delattrstr, &dummy);
+    Py_XINCREF(op->cl_getattr);
+    Py_XINCREF(op->cl_setattr);
+    Py_XINCREF(op->cl_delattr);
+    _PyObject_GC_TRACK(op);
+    return (PyObject *) op;
+}
+
+PyObject *
+PyMethod_Function(PyObject *im)
+{
+    if (!PyMethod_Check(im)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyMethodObject *)im)->im_func;
+}
+
+PyObject *
+PyMethod_Self(PyObject *im)
+{
+    if (!PyMethod_Check(im)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyMethodObject *)im)->im_self;
+}
+
+PyObject *
+PyMethod_Class(PyObject *im)
+{
+    if (!PyMethod_Check(im)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyMethodObject *)im)->im_class;
+}
+
+PyDoc_STRVAR(class_doc,
+"classobj(name, bases, dict)\n\
+\n\
+Create a class object.  The name must be a string; the second argument\n\
+a tuple of classes, and the third a dictionary.");
+
+static PyObject *
+class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *name, *bases, *dict;
+    static char *kwlist[] = {"name", "bases", "dict", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
+                                     &name, &bases, &dict))
+        return NULL;
+    return PyClass_New(bases, dict, name);
+}
+
+/* Class methods */
+
+static void
+class_dealloc(PyClassObject *op)
+{
+    _PyObject_GC_UNTRACK(op);
+    if (op->cl_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) op);
+    Py_DECREF(op->cl_bases);
+    Py_DECREF(op->cl_dict);
+    Py_XDECREF(op->cl_name);
+    Py_XDECREF(op->cl_getattr);
+    Py_XDECREF(op->cl_setattr);
+    Py_XDECREF(op->cl_delattr);
+    PyObject_GC_Del(op);
+}
+
+static PyObject *
+class_lookup(PyClassObject *cp, PyObject *name, PyClassObject **pclass)
+{
+    Py_ssize_t i, n;
+    PyObject *value = PyDict_GetItem(cp->cl_dict, name);
+    if (value != NULL) {
+        *pclass = cp;
+        return value;
+    }
+    n = PyTuple_Size(cp->cl_bases);
+    for (i = 0; i < n; i++) {
+        /* XXX What if one of the bases is not a class? */
+        PyObject *v = class_lookup(
+            (PyClassObject *)
+            PyTuple_GetItem(cp->cl_bases, i), name, pclass);
+        if (v != NULL)
+            return v;
+    }
+    return NULL;
+}
+
+static PyObject *
+class_getattr(register PyClassObject *op, PyObject *name)
+{
+    register PyObject *v;
+    register char *sname;
+    PyClassObject *klass;
+    descrgetfunc f;
+
+    if (!PyString_Check(name)) {
+        PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+        return NULL;
+    }
+
+    sname = PyString_AsString(name);
+    if (sname[0] == '_' && sname[1] == '_') {
+        if (strcmp(sname, "__dict__") == 0) {
+            if (PyEval_GetRestricted()) {
+                PyErr_SetString(PyExc_RuntimeError,
+               "class.__dict__ not accessible in restricted mode");
+                return NULL;
+            }
+            Py_INCREF(op->cl_dict);
+            return op->cl_dict;
+        }
+        if (strcmp(sname, "__bases__") == 0) {
+            Py_INCREF(op->cl_bases);
+            return op->cl_bases;
+        }
+        if (strcmp(sname, "__name__") == 0) {
+            if (op->cl_name == NULL)
+                v = Py_None;
+            else
+                v = op->cl_name;
+            Py_INCREF(v);
+            return v;
+        }
+    }
+    v = class_lookup(op, name, &klass);
+    if (v == NULL) {
+        PyErr_Format(PyExc_AttributeError,
+                     "class %.50s has no attribute '%.400s'",
+                     PyString_AS_STRING(op->cl_name), sname);
+        return NULL;
+    }
+    f = TP_DESCR_GET(v->ob_type);
+    if (f == NULL)
+        Py_INCREF(v);
+    else
+        v = f(v, (PyObject *)NULL, (PyObject *)op);
+    return v;
+}
+
+static void
+set_slot(PyObject **slot, PyObject *v)
+{
+    PyObject *temp = *slot;
+    Py_XINCREF(v);
+    *slot = v;
+    Py_XDECREF(temp);
+}
+
+static void
+set_attr_slots(PyClassObject *c)
+{
+    PyClassObject *dummy;
+
+    set_slot(&c->cl_getattr, class_lookup(c, getattrstr, &dummy));
+    set_slot(&c->cl_setattr, class_lookup(c, setattrstr, &dummy));
+    set_slot(&c->cl_delattr, class_lookup(c, delattrstr, &dummy));
+}
+
+static char *
+set_dict(PyClassObject *c, PyObject *v)
+{
+    if (v == NULL || !PyDict_Check(v))
+        return "__dict__ must be a dictionary object";
+    set_slot(&c->cl_dict, v);
+    set_attr_slots(c);
+    return "";
+}
+
+static char *
+set_bases(PyClassObject *c, PyObject *v)
+{
+    Py_ssize_t i, n;
+
+    if (v == NULL || !PyTuple_Check(v))
+        return "__bases__ must be a tuple object";
+    n = PyTuple_Size(v);
+    for (i = 0; i < n; i++) {
+        PyObject *x = PyTuple_GET_ITEM(v, i);
+        if (!PyClass_Check(x))
+            return "__bases__ items must be classes";
+        if (PyClass_IsSubclass(x, (PyObject *)c))
+            return "a __bases__ item causes an inheritance cycle";
+    }
+    set_slot(&c->cl_bases, v);
+    set_attr_slots(c);
+    return "";
+}
+
+static char *
+set_name(PyClassObject *c, PyObject *v)
+{
+    if (v == NULL || !PyString_Check(v))
+        return "__name__ must be a string object";
+    if (strlen(PyString_AS_STRING(v)) != (size_t)PyString_GET_SIZE(v))
+        return "__name__ must not contain null bytes";
+    set_slot(&c->cl_name, v);
+    return "";
+}
+
+static int
+class_setattr(PyClassObject *op, PyObject *name, PyObject *v)
+{
+    char *sname;
+    if (PyEval_GetRestricted()) {
+        PyErr_SetString(PyExc_RuntimeError,
+                   "classes are read-only in restricted mode");
+        return -1;
+    }
+    if (!PyString_Check(name)) {
+        PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+        return -1;
+    }
+    sname = PyString_AsString(name);
+    if (sname[0] == '_' && sname[1] == '_') {
+        Py_ssize_t n = PyString_Size(name);
+        if (sname[n-1] == '_' && sname[n-2] == '_') {
+            char *err = NULL;
+            if (strcmp(sname, "__dict__") == 0)
+                err = set_dict(op, v);
+            else if (strcmp(sname, "__bases__") == 0)
+                err = set_bases(op, v);
+            else if (strcmp(sname, "__name__") == 0)
+                err = set_name(op, v);
+            else if (strcmp(sname, "__getattr__") == 0)
+                set_slot(&op->cl_getattr, v);
+            else if (strcmp(sname, "__setattr__") == 0)
+                set_slot(&op->cl_setattr, v);
+            else if (strcmp(sname, "__delattr__") == 0)
+                set_slot(&op->cl_delattr, v);
+            /* For the last three, we fall through to update the
+               dictionary as well. */
+            if (err != NULL) {
+                if (*err == '\0')
+                    return 0;
+                PyErr_SetString(PyExc_TypeError, err);
+                return -1;
+            }
+        }
+    }
+    if (v == NULL) {
+        int rv = PyDict_DelItem(op->cl_dict, name);
+        if (rv < 0)
+            PyErr_Format(PyExc_AttributeError,
+                         "class %.50s has no attribute '%.400s'",
+                         PyString_AS_STRING(op->cl_name), sname);
+        return rv;
+    }
+    else
+        return PyDict_SetItem(op->cl_dict, name, v);
+}
+
+static PyObject *
+class_repr(PyClassObject *op)
+{
+    PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");
+    char *name;
+    if (op->cl_name == NULL || !PyString_Check(op->cl_name))
+        name = "?";
+    else
+        name = PyString_AsString(op->cl_name);
+    if (mod == NULL || !PyString_Check(mod))
+        return PyString_FromFormat("<class ?.%s at %p>", name, op);
+    else
+        return PyString_FromFormat("<class %s.%s at %p>",
+                                   PyString_AsString(mod),
+                                   name, op);
+}
+
+static PyObject *
+class_str(PyClassObject *op)
+{
+    PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");
+    PyObject *name = op->cl_name;
+    PyObject *res;
+    Py_ssize_t m, n;
+
+    if (name == NULL || !PyString_Check(name))
+        return class_repr(op);
+    if (mod == NULL || !PyString_Check(mod)) {
+        Py_INCREF(name);
+        return name;
+    }
+    m = PyString_GET_SIZE(mod);
+    n = PyString_GET_SIZE(name);
+    res = PyString_FromStringAndSize((char *)NULL, m+1+n);
+    if (res != NULL) {
+        char *s = PyString_AS_STRING(res);
+        memcpy(s, PyString_AS_STRING(mod), m);
+        s += m;
+        *s++ = '.';
+        memcpy(s, PyString_AS_STRING(name), n);
+    }
+    return res;
+}
+
+static int
+class_traverse(PyClassObject *o, visitproc visit, void *arg)
+{
+    Py_VISIT(o->cl_bases);
+    Py_VISIT(o->cl_dict);
+    Py_VISIT(o->cl_name);
+    Py_VISIT(o->cl_getattr);
+    Py_VISIT(o->cl_setattr);
+    Py_VISIT(o->cl_delattr);
+    return 0;
+}
+
+PyTypeObject PyClass_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "classobj",
+    sizeof(PyClassObject),
+    0,
+    (destructor)class_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)class_repr,                       /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    PyInstance_New,                             /* tp_call */
+    (reprfunc)class_str,                        /* tp_str */
+    (getattrofunc)class_getattr,                /* tp_getattro */
+    (setattrofunc)class_setattr,                /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    class_doc,                                  /* tp_doc */
+    (traverseproc)class_traverse,               /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(PyClassObject, cl_weakreflist), /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    class_new,                                  /* tp_new */
+};
+
+int
+PyClass_IsSubclass(PyObject *klass, PyObject *base)
+{
+    Py_ssize_t i, n;
+    PyClassObject *cp;
+    if (klass == base)
+        return 1;
+    if (PyTuple_Check(base)) {
+        n = PyTuple_GET_SIZE(base);
+        for (i = 0; i < n; i++) {
+            if (PyClass_IsSubclass(klass, PyTuple_GET_ITEM(base, i)))
+                return 1;
+        }
+        return 0;
+    }
+    if (klass == NULL || !PyClass_Check(klass))
+        return 0;
+    cp = (PyClassObject *)klass;
+    n = PyTuple_Size(cp->cl_bases);
+    for (i = 0; i < n; i++) {
+        if (PyClass_IsSubclass(PyTuple_GetItem(cp->cl_bases, i), base))
+            return 1;
+    }
+    return 0;
+}
+
+
+/* Instance objects */
+
+PyObject *
+PyInstance_NewRaw(PyObject *klass, PyObject *dict)
+{
+    PyInstanceObject *inst;
+
+    if (!PyClass_Check(klass)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    if (dict == NULL) {
+        dict = PyDict_New();
+        if (dict == NULL)
+            return NULL;
+    }
+    else {
+        if (!PyDict_Check(dict)) {
+            PyErr_BadInternalCall();
+            return NULL;
+        }
+        Py_INCREF(dict);
+    }
+    inst = PyObject_GC_New(PyInstanceObject, &PyInstance_Type);
+    if (inst == NULL) {
+        Py_DECREF(dict);
+        return NULL;
+    }
+    inst->in_weakreflist = NULL;
+    Py_INCREF(klass);
+    inst->in_class = (PyClassObject *)klass;
+    inst->in_dict = dict;
+    _PyObject_GC_TRACK(inst);
+    return (PyObject *)inst;
+}
+
+PyObject *
+PyInstance_New(PyObject *klass, PyObject *arg, PyObject *kw)
+{
+    register PyInstanceObject *inst;
+    PyObject *init;
+    static PyObject *initstr;
+
+    if (initstr == NULL) {
+        initstr = PyString_InternFromString("__init__");
+        if (initstr == NULL)
+            return NULL;
+    }
+    inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL);
+    if (inst == NULL)
+        return NULL;
+    init = instance_getattr2(inst, initstr);
+    if (init == NULL) {
+        if (PyErr_Occurred()) {
+            Py_DECREF(inst);
+            return NULL;
+        }
+        if ((arg != NULL && (!PyTuple_Check(arg) ||
+                             PyTuple_Size(arg) != 0))
+            || (kw != NULL && (!PyDict_Check(kw) ||
+                              PyDict_Size(kw) != 0))) {
+            PyErr_SetString(PyExc_TypeError,
+                       "this constructor takes no arguments");
+            Py_DECREF(inst);
+            inst = NULL;
+        }
+    }
+    else {
+        PyObject *res = PyEval_CallObjectWithKeywords(init, arg, kw);
+        Py_DECREF(init);
+        if (res == NULL) {
+            Py_DECREF(inst);
+            inst = NULL;
+        }
+        else {
+            if (res != Py_None) {
+                PyErr_SetString(PyExc_TypeError,
+                           "__init__() should return None");
+                Py_DECREF(inst);
+                inst = NULL;
+            }
+            Py_DECREF(res);
+        }
+    }
+    return (PyObject *)inst;
+}
+
+/* Instance methods */
+
+PyDoc_STRVAR(instance_doc,
+"instance(class[, dict])\n\
+\n\
+Create an instance without calling its __init__() method.\n\
+The class must be a classic class.\n\
+If present, dict must be a dictionary or None.");
+
+static PyObject *
+instance_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+    PyObject *klass;
+    PyObject *dict = Py_None;
+
+    if (!PyArg_ParseTuple(args, "O!|O:instance",
+                          &PyClass_Type, &klass, &dict))
+        return NULL;
+
+    if (dict == Py_None)
+        dict = NULL;
+    else if (!PyDict_Check(dict)) {
+        PyErr_SetString(PyExc_TypeError,
+              "instance() second arg must be dictionary or None");
+        return NULL;
+    }
+    return PyInstance_NewRaw(klass, dict);
+}
+
+
+static void
+instance_dealloc(register PyInstanceObject *inst)
+{
+    PyObject *error_type, *error_value, *error_traceback;
+    PyObject *del;
+    static PyObject *delstr;
+
+    _PyObject_GC_UNTRACK(inst);
+    if (inst->in_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) inst);
+
+    /* Temporarily resurrect the object. */
+    assert(inst->ob_type == &PyInstance_Type);
+    assert(inst->ob_refcnt == 0);
+    inst->ob_refcnt = 1;
+
+    /* Save the current exception, if any. */
+    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    /* Execute __del__ method, if any. */
+    if (delstr == NULL) {
+        delstr = PyString_InternFromString("__del__");
+        if (delstr == NULL)
+            PyErr_WriteUnraisable((PyObject*)inst);
+    }
+    if (delstr && (del = instance_getattr2(inst, delstr)) != NULL) {
+        PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);
+        if (res == NULL)
+            PyErr_WriteUnraisable(del);
+        else
+            Py_DECREF(res);
+        Py_DECREF(del);
+    }
+    /* Restore the saved exception. */
+    PyErr_Restore(error_type, error_value, error_traceback);
+
+    /* Undo the temporary resurrection; can't use DECREF here, it would
+     * cause a recursive call.
+     */
+    assert(inst->ob_refcnt > 0);
+    if (--inst->ob_refcnt == 0) {
+
+        /* New weakrefs could be created during the finalizer call.
+            If this occurs, clear them out without calling their
+            finalizers since they might rely on part of the object
+            being finalized that has already been destroyed. */
+        while (inst->in_weakreflist != NULL) {
+            _PyWeakref_ClearRef((PyWeakReference *)
+                                (inst->in_weakreflist));
+        }
+
+        Py_DECREF(inst->in_class);
+        Py_XDECREF(inst->in_dict);
+        PyObject_GC_Del(inst);
+    }
+    else {
+        Py_ssize_t refcnt = inst->ob_refcnt;
+        /* __del__ resurrected it!  Make it look like the original
+         * Py_DECREF never happened.
+         */
+        _Py_NewReference((PyObject *)inst);
+        inst->ob_refcnt = refcnt;
+        _PyObject_GC_TRACK(inst);
+        /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+         * we need to undo that. */
+        _Py_DEC_REFTOTAL;
+        /* If Py_TRACE_REFS, _Py_NewReference re-added self to the
+         * object chain, so no more to do there.
+         * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+         * _Py_NewReference bumped tp_allocs: both of those need to be
+         * undone.
+         */
+#ifdef COUNT_ALLOCS
+        --inst->ob_type->tp_frees;
+        --inst->ob_type->tp_allocs;
+#endif
+    }
+}
+
+static PyObject *
+instance_getattr1(register PyInstanceObject *inst, PyObject *name)
+{
+    register PyObject *v;
+    register char *sname;
+
+    if (!PyString_Check(name)) {
+        PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+        return NULL;
+    }
+
+    sname = PyString_AsString(name);
+    if (sname[0] == '_' && sname[1] == '_') {
+        if (strcmp(sname, "__dict__") == 0) {
+            if (PyEval_GetRestricted()) {
+                PyErr_SetString(PyExc_RuntimeError,
+            "instance.__dict__ not accessible in restricted mode");
+                return NULL;
+            }
+            Py_INCREF(inst->in_dict);
+            return inst->in_dict;
+        }
+        if (strcmp(sname, "__class__") == 0) {
+            Py_INCREF(inst->in_class);
+            return (PyObject *)inst->in_class;
+        }
+    }
+    v = instance_getattr2(inst, name);
+    if (v == NULL && !PyErr_Occurred()) {
+        PyErr_Format(PyExc_AttributeError,
+                     "%.50s instance has no attribute '%.400s'",
+                     PyString_AS_STRING(inst->in_class->cl_name), sname);
+    }
+    return v;
+}
+
+static PyObject *
+instance_getattr2(register PyInstanceObject *inst, PyObject *name)
+{
+    register PyObject *v;
+    PyClassObject *klass;
+    descrgetfunc f;
+
+    v = PyDict_GetItem(inst->in_dict, name);
+    if (v != NULL) {
+        Py_INCREF(v);
+        return v;
+    }
+    v = class_lookup(inst->in_class, name, &klass);
+    if (v != NULL) {
+        Py_INCREF(v);
+        f = TP_DESCR_GET(v->ob_type);
+        if (f != NULL) {
+            PyObject *w = f(v, (PyObject *)inst,
+                            (PyObject *)(inst->in_class));
+            Py_DECREF(v);
+            v = w;
+        }
+    }
+    return v;
+}
+
+static PyObject *
+instance_getattr(register PyInstanceObject *inst, PyObject *name)
+{
+    register PyObject *func, *res;
+    res = instance_getattr1(inst, name);
+    if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) {
+        PyObject *args;
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        args = PyTuple_Pack(2, inst, name);
+        if (args == NULL)
+            return NULL;
+        res = PyEval_CallObject(func, args);
+        Py_DECREF(args);
+    }
+    return res;
+}
+
+/* See classobject.h comments:  this only does dict lookups, and is always
+ * safe to call.
+ */
+PyObject *
+_PyInstance_Lookup(PyObject *pinst, PyObject *name)
+{
+    PyObject *v;
+    PyClassObject *klass;
+    PyInstanceObject *inst;     /* pinst cast to the right type */
+
+    assert(PyInstance_Check(pinst));
+    inst = (PyInstanceObject *)pinst;
+
+    assert(PyString_Check(name));
+
+    v = PyDict_GetItem(inst->in_dict, name);
+    if (v == NULL)
+        v = class_lookup(inst->in_class, name, &klass);
+    return v;
+}
+
+static int
+instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v)
+{
+    if (v == NULL) {
+        int rv = PyDict_DelItem(inst->in_dict, name);
+        if (rv < 0)
+            PyErr_Format(PyExc_AttributeError,
+                         "%.50s instance has no attribute '%.400s'",
+                         PyString_AS_STRING(inst->in_class->cl_name),
+                         PyString_AS_STRING(name));
+        return rv;
+    }
+    else
+        return PyDict_SetItem(inst->in_dict, name, v);
+}
+
+static int
+instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
+{
+    PyObject *func, *args, *res, *tmp;
+    char *sname;
+
+    if (!PyString_Check(name)) {
+        PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+        return -1;
+    }
+
+    sname = PyString_AsString(name);
+    if (sname[0] == '_' && sname[1] == '_') {
+        Py_ssize_t n = PyString_Size(name);
+        if (sname[n-1] == '_' && sname[n-2] == '_') {
+            if (strcmp(sname, "__dict__") == 0) {
+                if (PyEval_GetRestricted()) {
+                    PyErr_SetString(PyExc_RuntimeError,
+                 "__dict__ not accessible in restricted mode");
+                    return -1;
+                }
+                if (v == NULL || !PyDict_Check(v)) {
+                    PyErr_SetString(PyExc_TypeError,
+                       "__dict__ must be set to a dictionary");
+                    return -1;
+                }
+                tmp = inst->in_dict;
+                Py_INCREF(v);
+                inst->in_dict = v;
+                Py_DECREF(tmp);
+                return 0;
+            }
+            if (strcmp(sname, "__class__") == 0) {
+                if (PyEval_GetRestricted()) {
+                    PyErr_SetString(PyExc_RuntimeError,
+                "__class__ not accessible in restricted mode");
+                    return -1;
+                }
+                if (v == NULL || !PyClass_Check(v)) {
+                    PyErr_SetString(PyExc_TypeError,
+                       "__class__ must be set to a class");
+                    return -1;
+                }
+                tmp = (PyObject *)(inst->in_class);
+                Py_INCREF(v);
+                inst->in_class = (PyClassObject *)v;
+                Py_DECREF(tmp);
+                return 0;
+            }
+        }
+    }
+    if (v == NULL)
+        func = inst->in_class->cl_delattr;
+    else
+        func = inst->in_class->cl_setattr;
+    if (func == NULL)
+        return instance_setattr1(inst, name, v);
+    if (v == NULL)
+        args = PyTuple_Pack(2, inst, name);
+    else
+        args = PyTuple_Pack(3, inst, name, v);
+    if (args == NULL)
+        return -1;
+    res = PyEval_CallObject(func, args);
+    Py_DECREF(args);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static PyObject *
+instance_repr(PyInstanceObject *inst)
+{
+    PyObject *func;
+    PyObject *res;
+    static PyObject *reprstr;
+
+    if (reprstr == NULL) {
+        reprstr = PyString_InternFromString("__repr__");
+        if (reprstr == NULL)
+            return NULL;
+    }
+    func = instance_getattr(inst, reprstr);
+    if (func == NULL) {
+        PyObject *classname, *mod;
+        char *cname;
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        classname = inst->in_class->cl_name;
+        mod = PyDict_GetItemString(inst->in_class->cl_dict,
+                                   "__module__");
+        if (classname != NULL && PyString_Check(classname))
+            cname = PyString_AsString(classname);
+        else
+            cname = "?";
+        if (mod == NULL || !PyString_Check(mod))
+            return PyString_FromFormat("<?.%s instance at %p>",
+                                       cname, inst);
+        else
+            return PyString_FromFormat("<%s.%s instance at %p>",
+                                       PyString_AsString(mod),
+                                       cname, inst);
+    }
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    return res;
+}
+
+static PyObject *
+instance_str(PyInstanceObject *inst)
+{
+    PyObject *func;
+    PyObject *res;
+    static PyObject *strstr;
+
+    if (strstr == NULL) {
+        strstr = PyString_InternFromString("__str__");
+        if (strstr == NULL)
+            return NULL;
+    }
+    func = instance_getattr(inst, strstr);
+    if (func == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        return instance_repr(inst);
+    }
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    return res;
+}
+
+static long
+instance_hash(PyInstanceObject *inst)
+{
+    PyObject *func;
+    PyObject *res;
+    long outcome;
+    static PyObject *hashstr, *eqstr, *cmpstr;
+
+    if (hashstr == NULL) {
+        hashstr = PyString_InternFromString("__hash__");
+        if (hashstr == NULL)
+            return -1;
+    }
+    func = instance_getattr(inst, hashstr);
+    if (func == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return -1;
+        PyErr_Clear();
+        /* If there is no __eq__ and no __cmp__ method, we hash on the
+           address.  If an __eq__ or __cmp__ method exists, there must
+           be a __hash__. */
+        if (eqstr == NULL) {
+            eqstr = PyString_InternFromString("__eq__");
+            if (eqstr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, eqstr);
+        if (func == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return -1;
+            PyErr_Clear();
+            if (cmpstr == NULL) {
+                cmpstr = PyString_InternFromString("__cmp__");
+                if (cmpstr == NULL)
+                    return -1;
+            }
+            func = instance_getattr(inst, cmpstr);
+            if (func == NULL) {
+                if (!PyErr_ExceptionMatches(
+                    PyExc_AttributeError))
+                    return -1;
+                PyErr_Clear();
+                return _Py_HashPointer(inst);
+            }
+        }
+        Py_XDECREF(func);
+        PyErr_SetString(PyExc_TypeError, "unhashable instance");
+        return -1;
+    }
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    if (res == NULL)
+        return -1;
+    if (PyInt_Check(res) || PyLong_Check(res))
+        /* This already converts a -1 result to -2. */
+        outcome = res->ob_type->tp_hash(res);
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "__hash__() should return an int");
+        outcome = -1;
+    }
+    Py_DECREF(res);
+    return outcome;
+}
+
+static int
+instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)
+{
+    Py_VISIT(o->in_class);
+    Py_VISIT(o->in_dict);
+    return 0;
+}
+
+static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;
+static PyObject *iterstr, *nextstr;
+
+static Py_ssize_t
+instance_length(PyInstanceObject *inst)
+{
+    PyObject *func;
+    PyObject *res;
+    Py_ssize_t outcome;
+
+    if (lenstr == NULL) {
+        lenstr = PyString_InternFromString("__len__");
+        if (lenstr == NULL)
+            return -1;
+    }
+    func = instance_getattr(inst, lenstr);
+    if (func == NULL)
+        return -1;
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    if (res == NULL)
+        return -1;
+    if (PyInt_Check(res)) {
+        outcome = PyInt_AsSsize_t(res);
+        if (outcome == -1 && PyErr_Occurred()) {
+            Py_DECREF(res);
+            return -1;
+        }
+#if SIZEOF_SIZE_T < SIZEOF_INT
+        /* Overflow check -- range of PyInt is more than C int */
+        if (outcome != (int)outcome) {
+            PyErr_SetString(PyExc_OverflowError,
+             "__len__() should return 0 <= outcome < 2**31");
+            outcome = -1;
+        }
+        else
+#endif
+        if (outcome < 0) {
+            PyErr_SetString(PyExc_ValueError,
+                            "__len__() should return >= 0");
+            outcome = -1;
+        }
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "__len__() should return an int");
+        outcome = -1;
+    }
+    Py_DECREF(res);
+    return outcome;
+}
+
+static PyObject *
+instance_subscript(PyInstanceObject *inst, PyObject *key)
+{
+    PyObject *func;
+    PyObject *arg;
+    PyObject *res;
+
+    if (getitemstr == NULL) {
+        getitemstr = PyString_InternFromString("__getitem__");
+        if (getitemstr == NULL)
+            return NULL;
+    }
+    func = instance_getattr(inst, getitemstr);
+    if (func == NULL)
+        return NULL;
+    arg = PyTuple_Pack(1, key);
+    if (arg == NULL) {
+        Py_DECREF(func);
+        return NULL;
+    }
+    res = PyEval_CallObject(func, arg);
+    Py_DECREF(func);
+    Py_DECREF(arg);
+    return res;
+}
+
+static int
+instance_ass_subscript(PyInstanceObject *inst, PyObject *key, PyObject *value)
+{
+    PyObject *func;
+    PyObject *arg;
+    PyObject *res;
+
+    if (value == NULL) {
+        if (delitemstr == NULL) {
+            delitemstr = PyString_InternFromString("__delitem__");
+            if (delitemstr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, delitemstr);
+    }
+    else {
+        if (setitemstr == NULL) {
+            setitemstr = PyString_InternFromString("__setitem__");
+            if (setitemstr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, setitemstr);
+    }
+    if (func == NULL)
+        return -1;
+    if (value == NULL)
+        arg = PyTuple_Pack(1, key);
+    else
+        arg = PyTuple_Pack(2, key, value);
+    if (arg == NULL) {
+        Py_DECREF(func);
+        return -1;
+    }
+    res = PyEval_CallObject(func, arg);
+    Py_DECREF(func);
+    Py_DECREF(arg);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static PyMappingMethods instance_as_mapping = {
+    (lenfunc)instance_length,                   /* mp_length */
+    (binaryfunc)instance_subscript,             /* mp_subscript */
+    (objobjargproc)instance_ass_subscript,      /* mp_ass_subscript */
+};
+
+static PyObject *
+instance_item(PyInstanceObject *inst, Py_ssize_t i)
+{
+    PyObject *func, *res;
+
+    if (getitemstr == NULL) {
+        getitemstr = PyString_InternFromString("__getitem__");
+        if (getitemstr == NULL)
+            return NULL;
+    }
+    func = instance_getattr(inst, getitemstr);
+    if (func == NULL)
+        return NULL;
+    res = PyObject_CallFunction(func, "n", i);
+    Py_DECREF(func);
+    return res;
+}
+
+static PyObject *
+instance_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j)
+{
+    PyObject *func, *arg, *res;
+    static PyObject *getslicestr;
+
+    if (getslicestr == NULL) {
+        getslicestr = PyString_InternFromString("__getslice__");
+        if (getslicestr == NULL)
+            return NULL;
+    }
+    func = instance_getattr(inst, getslicestr);
+
+    if (func == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+
+        if (getitemstr == NULL) {
+            getitemstr = PyString_InternFromString("__getitem__");
+            if (getitemstr == NULL)
+                return NULL;
+        }
+        func = instance_getattr(inst, getitemstr);
+        if (func == NULL)
+            return NULL;
+        arg = Py_BuildValue("(N)", _PySlice_FromIndices(i, j));
+    }
+    else {
+        if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "
+                           "use __getitem__", 1) < 0) {
+            Py_DECREF(func);
+            return NULL;
+        }
+        arg = Py_BuildValue("(nn)", i, j);
+    }
+
+    if (arg == NULL) {
+        Py_DECREF(func);
+        return NULL;
+    }
+    res = PyEval_CallObject(func, arg);
+    Py_DECREF(func);
+    Py_DECREF(arg);
+    return res;
+}
+
+static int
+instance_ass_item(PyInstanceObject *inst, Py_ssize_t i, PyObject *item)
+{
+    PyObject *func, *arg, *res;
+
+    if (item == NULL) {
+        if (delitemstr == NULL) {
+            delitemstr = PyString_InternFromString("__delitem__");
+            if (delitemstr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, delitemstr);
+    }
+    else {
+        if (setitemstr == NULL) {
+            setitemstr = PyString_InternFromString("__setitem__");
+            if (setitemstr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, setitemstr);
+    }
+    if (func == NULL)
+        return -1;
+    if (item == NULL)
+        arg = Py_BuildValue("(n)", i);
+    else
+        arg = Py_BuildValue("(nO)", i, item);
+    if (arg == NULL) {
+        Py_DECREF(func);
+        return -1;
+    }
+    res = PyEval_CallObject(func, arg);
+    Py_DECREF(func);
+    Py_DECREF(arg);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static int
+instance_ass_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+    PyObject *func, *arg, *res;
+    static PyObject *setslicestr, *delslicestr;
+
+    if (value == NULL) {
+        if (delslicestr == NULL) {
+            delslicestr =
+                PyString_InternFromString("__delslice__");
+            if (delslicestr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, delslicestr);
+        if (func == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return -1;
+            PyErr_Clear();
+            if (delitemstr == NULL) {
+                delitemstr =
+                    PyString_InternFromString("__delitem__");
+                if (delitemstr == NULL)
+                    return -1;
+            }
+            func = instance_getattr(inst, delitemstr);
+            if (func == NULL)
+                return -1;
+
+            arg = Py_BuildValue("(N)",
+                                _PySlice_FromIndices(i, j));
+        }
+        else {
+            if (PyErr_WarnPy3k("in 3.x, __delslice__ has been "
+                                "removed; use __delitem__", 1) < 0) {
+                Py_DECREF(func);
+                return -1;
+            }
+            arg = Py_BuildValue("(nn)", i, j);
+        }
+    }
+    else {
+        if (setslicestr == NULL) {
+            setslicestr =
+                PyString_InternFromString("__setslice__");
+            if (setslicestr == NULL)
+                return -1;
+        }
+        func = instance_getattr(inst, setslicestr);
+        if (func == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return -1;
+            PyErr_Clear();
+            if (setitemstr == NULL) {
+                setitemstr =
+                    PyString_InternFromString("__setitem__");
+                if (setitemstr == NULL)
+                    return -1;
+            }
+            func = instance_getattr(inst, setitemstr);
+            if (func == NULL)
+                return -1;
+
+            arg = Py_BuildValue("(NO)",
+                                _PySlice_FromIndices(i, j), value);
+        }
+        else {
+            if (PyErr_WarnPy3k("in 3.x, __setslice__ has been "
+                               "removed; use __setitem__", 1) < 0) {
+                Py_DECREF(func);
+                return -1;
+            }
+            arg = Py_BuildValue("(nnO)", i, j, value);
+        }
+    }
+    if (arg == NULL) {
+        Py_DECREF(func);
+        return -1;
+    }
+    res = PyEval_CallObject(func, arg);
+    Py_DECREF(func);
+    Py_DECREF(arg);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static int
+instance_contains(PyInstanceObject *inst, PyObject *member)
+{
+    static PyObject *__contains__;
+    PyObject *func;
+
+    /* Try __contains__ first.
+     * If that can't be done, try iterator-based searching.
+     */
+
+    if(__contains__ == NULL) {
+        __contains__ = PyString_InternFromString("__contains__");
+        if(__contains__ == NULL)
+            return -1;
+    }
+    func = instance_getattr(inst, __contains__);
+    if (func) {
+        PyObject *res;
+        int ret;
+        PyObject *arg = PyTuple_Pack(1, member);
+        if(arg == NULL) {
+            Py_DECREF(func);
+            return -1;
+        }
+        res = PyEval_CallObject(func, arg);
+        Py_DECREF(func);
+        Py_DECREF(arg);
+        if(res == NULL)
+            return -1;
+        ret = PyObject_IsTrue(res);
+        Py_DECREF(res);
+        return ret;
+    }
+
+    /* Couldn't find __contains__. */
+    if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        Py_ssize_t rc;
+        /* Assume the failure was simply due to that there is no
+         * __contains__ attribute, and try iterating instead.
+         */
+        PyErr_Clear();
+        rc = _PySequence_IterSearch((PyObject *)inst, member,
+                                    PY_ITERSEARCH_CONTAINS);
+        if (rc >= 0)
+            return rc > 0;
+    }
+    return -1;
+}
+
+static PySequenceMethods
+instance_as_sequence = {
+    (lenfunc)instance_length,                   /* sq_length */
+    0,                                          /* sq_concat */
+    0,                                          /* sq_repeat */
+    (ssizeargfunc)instance_item,                /* sq_item */
+    (ssizessizeargfunc)instance_slice,          /* sq_slice */
+    (ssizeobjargproc)instance_ass_item,         /* sq_ass_item */
+    (ssizessizeobjargproc)instance_ass_slice,/* sq_ass_slice */
+    (objobjproc)instance_contains,              /* sq_contains */
+};
+
+static PyObject *
+generic_unary_op(PyInstanceObject *self, PyObject *methodname)
+{
+    PyObject *func, *res;
+
+    if ((func = instance_getattr(self, methodname)) == NULL)
+        return NULL;
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    return res;
+}
+
+static PyObject *
+generic_binary_op(PyObject *v, PyObject *w, char *opname)
+{
+    PyObject *result;
+    PyObject *args;
+    PyObject *func = PyObject_GetAttrString(v, opname);
+    if (func == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    args = PyTuple_Pack(1, w);
+    if (args == NULL) {
+        Py_DECREF(func);
+        return NULL;
+    }
+    result = PyEval_CallObject(func, args);
+    Py_DECREF(args);
+    Py_DECREF(func);
+    return result;
+}
+
+
+static PyObject *coerce_obj;
+
+/* Try one half of a binary operator involving a class instance. */
+static PyObject *
+half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc,
+                int swapped)
+{
+    PyObject *args;
+    PyObject *coercefunc;
+    PyObject *coerced = NULL;
+    PyObject *v1;
+    PyObject *result;
+
+    if (!PyInstance_Check(v)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    if (coerce_obj == NULL) {
+        coerce_obj = PyString_InternFromString("__coerce__");
+        if (coerce_obj == NULL)
+            return NULL;
+    }
+    coercefunc = PyObject_GetAttr(v, coerce_obj);
+    if (coercefunc == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        return generic_binary_op(v, w, opname);
+    }
+
+    args = PyTuple_Pack(1, w);
+    if (args == NULL) {
+        Py_DECREF(coercefunc);
+        return NULL;
+    }
+    coerced = PyEval_CallObject(coercefunc, args);
+    Py_DECREF(args);
+    Py_DECREF(coercefunc);
+    if (coerced == NULL) {
+        return NULL;
+    }
+    if (coerced == Py_None || coerced == Py_NotImplemented) {
+        Py_DECREF(coerced);
+        return generic_binary_op(v, w, opname);
+    }
+    if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {
+        Py_DECREF(coerced);
+        PyErr_SetString(PyExc_TypeError,
+                        "coercion should return None or 2-tuple");
+        return NULL;
+    }
+    v1 = PyTuple_GetItem(coerced, 0);
+    w = PyTuple_GetItem(coerced, 1);
+    if (v1->ob_type == v->ob_type && PyInstance_Check(v)) {
+        /* prevent recursion if __coerce__ returns self as the first
+         * argument */
+        result = generic_binary_op(v1, w, opname);
+    } else {
+        if (Py_EnterRecursiveCall(" after coercion"))
+            return NULL;
+        if (swapped)
+            result = (thisfunc)(w, v1);
+        else
+            result = (thisfunc)(v1, w);
+        Py_LeaveRecursiveCall();
+    }
+    Py_DECREF(coerced);
+    return result;
+}
+
+/* Implement a binary operator involving at least one class instance. */
+static PyObject *
+do_binop(PyObject *v, PyObject *w, char *opname, char *ropname,
+                   binaryfunc thisfunc)
+{
+    PyObject *result = half_binop(v, w, opname, thisfunc, 0);
+    if (result == Py_NotImplemented) {
+        Py_DECREF(result);
+        result = half_binop(w, v, ropname, thisfunc, 1);
+    }
+    return result;
+}
+
+static PyObject *
+do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname,
+                        char *ropname, binaryfunc thisfunc)
+{
+    PyObject *result = half_binop(v, w, iopname, thisfunc, 0);
+    if (result == Py_NotImplemented) {
+        Py_DECREF(result);
+        result = do_binop(v, w, opname, ropname, thisfunc);
+    }
+    return result;
+}
+
+static int
+instance_coerce(PyObject **pv, PyObject **pw)
+{
+    PyObject *v = *pv;
+    PyObject *w = *pw;
+    PyObject *coercefunc;
+    PyObject *args;
+    PyObject *coerced;
+
+    if (coerce_obj == NULL) {
+        coerce_obj = PyString_InternFromString("__coerce__");
+        if (coerce_obj == NULL)
+            return -1;
+    }
+    coercefunc = PyObject_GetAttr(v, coerce_obj);
+    if (coercefunc == NULL) {
+        /* No __coerce__ method */
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return -1;
+        PyErr_Clear();
+        return 1;
+    }
+    /* Has __coerce__ method: call it */
+    args = PyTuple_Pack(1, w);
+    if (args == NULL) {
+        return -1;
+    }
+    coerced = PyEval_CallObject(coercefunc, args);
+    Py_DECREF(args);
+    Py_DECREF(coercefunc);
+    if (coerced == NULL) {
+        /* __coerce__ call raised an exception */
+        return -1;
+    }
+    if (coerced == Py_None || coerced == Py_NotImplemented) {
+        /* __coerce__ says "I can't do it" */
+        Py_DECREF(coerced);
+        return 1;
+    }
+    if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {
+        /* __coerce__ return value is malformed */
+        Py_DECREF(coerced);
+        PyErr_SetString(PyExc_TypeError,
+                   "coercion should return None or 2-tuple");
+        return -1;
+    }
+    /* __coerce__ returned two new values */
+    *pv = PyTuple_GetItem(coerced, 0);
+    *pw = PyTuple_GetItem(coerced, 1);
+    Py_INCREF(*pv);
+    Py_INCREF(*pw);
+    Py_DECREF(coerced);
+    return 0;
+}
+
+#define UNARY(funcname, methodname) \
+static PyObject *funcname(PyInstanceObject *self) { \
+    static PyObject *o; \
+    if (o == NULL) { o = PyString_InternFromString(methodname); \
+                     if (o == NULL) return NULL; } \
+    return generic_unary_op(self, o); \
+}
+
+/* unary function with a fallback */
+#define UNARY_FB(funcname, methodname, funcname_fb) \
+static PyObject *funcname(PyInstanceObject *self) { \
+    static PyObject *o; \
+    if (o == NULL) { o = PyString_InternFromString(methodname); \
+                     if (o == NULL) return NULL; } \
+    if (PyObject_HasAttr((PyObject*)self, o)) \
+        return generic_unary_op(self, o); \
+    else \
+        return funcname_fb(self); \
+}
+
+#define BINARY(f, m, n) \
+static PyObject *f(PyObject *v, PyObject *w) { \
+    return do_binop(v, w, "__" m "__", "__r" m "__", n); \
+}
+
+#define BINARY_INPLACE(f, m, n) \
+static PyObject *f(PyObject *v, PyObject *w) { \
+    return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \
+                    "__r" m "__", n); \
+}
+
+UNARY(instance_neg, "__neg__")
+UNARY(instance_pos, "__pos__")
+UNARY(instance_abs, "__abs__")
+
+BINARY(instance_or, "or", PyNumber_Or)
+BINARY(instance_and, "and", PyNumber_And)
+BINARY(instance_xor, "xor", PyNumber_Xor)
+BINARY(instance_lshift, "lshift", PyNumber_Lshift)
+BINARY(instance_rshift, "rshift", PyNumber_Rshift)
+BINARY(instance_add, "add", PyNumber_Add)
+BINARY(instance_sub, "sub", PyNumber_Subtract)
+BINARY(instance_mul, "mul", PyNumber_Multiply)
+BINARY(instance_div, "div", PyNumber_Divide)
+BINARY(instance_mod, "mod", PyNumber_Remainder)
+BINARY(instance_divmod, "divmod", PyNumber_Divmod)
+BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide)
+BINARY(instance_truediv, "truediv", PyNumber_TrueDivide)
+
+BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr)
+BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor)
+BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd)
+BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift)
+BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift)
+BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd)
+BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract)
+BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply)
+BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide)
+BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder)
+BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide)
+BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide)
+
+/* Try a 3-way comparison, returning an int; v is an instance.  Return:
+   -2 for an exception;
+   -1 if v < w;
+   0 if v == w;
+   1 if v > w;
+   2 if this particular 3-way comparison is not implemented or undefined.
+*/
+static int
+half_cmp(PyObject *v, PyObject *w)
+{
+    static PyObject *cmp_obj;
+    PyObject *args;
+    PyObject *cmp_func;
+    PyObject *result;
+    long l;
+
+    assert(PyInstance_Check(v));
+
+    if (cmp_obj == NULL) {
+        cmp_obj = PyString_InternFromString("__cmp__");
+        if (cmp_obj == NULL)
+            return -2;
+    }
+
+    cmp_func = PyObject_GetAttr(v, cmp_obj);
+    if (cmp_func == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return -2;
+        PyErr_Clear();
+        return 2;
+    }
+
+    args = PyTuple_Pack(1, w);
+    if (args == NULL) {
+        Py_DECREF(cmp_func);
+        return -2;
+    }
+
+    result = PyEval_CallObject(cmp_func, args);
+    Py_DECREF(args);
+    Py_DECREF(cmp_func);
+
+    if (result == NULL)
+        return -2;
+
+    if (result == Py_NotImplemented) {
+        Py_DECREF(result);
+        return 2;
+    }
+
+    l = PyInt_AsLong(result);
+    Py_DECREF(result);
+    if (l == -1 && PyErr_Occurred()) {
+        PyErr_SetString(PyExc_TypeError,
+                     "comparison did not return an int");
+        return -2;
+    }
+
+    return l < 0 ? -1 : l > 0 ? 1 : 0;
+}
+
+/* Try a 3-way comparison, returning an int; either v or w is an instance.
+   We first try a coercion.  Return:
+   -2 for an exception;
+   -1 if v < w;
+   0 if v == w;
+   1 if v > w;
+   2 if this particular 3-way comparison is not implemented or undefined.
+   THIS IS ONLY CALLED FROM object.c!
+*/
+static int
+instance_compare(PyObject *v, PyObject *w)
+{
+    int c;
+
+    c = PyNumber_CoerceEx(&v, &w);
+    if (c < 0)
+        return -2;
+    if (c == 0) {
+        /* If neither is now an instance, use regular comparison */
+        if (!PyInstance_Check(v) && !PyInstance_Check(w)) {
+            c = PyObject_Compare(v, w);
+            Py_DECREF(v);
+            Py_DECREF(w);
+            if (PyErr_Occurred())
+                return -2;
+            return c < 0 ? -1 : c > 0 ? 1 : 0;
+        }
+    }
+    else {
+        /* The coercion didn't do anything.
+           Treat this the same as returning v and w unchanged. */
+        Py_INCREF(v);
+        Py_INCREF(w);
+    }
+
+    if (PyInstance_Check(v)) {
+        c = half_cmp(v, w);
+        if (c <= 1) {
+            Py_DECREF(v);
+            Py_DECREF(w);
+            return c;
+        }
+    }
+    if (PyInstance_Check(w)) {
+        c = half_cmp(w, v);
+        if (c <= 1) {
+            Py_DECREF(v);
+            Py_DECREF(w);
+            if (c >= -1)
+                c = -c;
+            return c;
+        }
+    }
+    Py_DECREF(v);
+    Py_DECREF(w);
+    return 2;
+}
+
+static int
+instance_nonzero(PyInstanceObject *self)
+{
+    PyObject *func, *res;
+    long outcome;
+    static PyObject *nonzerostr;
+
+    if (nonzerostr == NULL) {
+        nonzerostr = PyString_InternFromString("__nonzero__");
+        if (nonzerostr == NULL)
+            return -1;
+    }
+    if ((func = instance_getattr(self, nonzerostr)) == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return -1;
+        PyErr_Clear();
+        if (lenstr == NULL) {
+            lenstr = PyString_InternFromString("__len__");
+            if (lenstr == NULL)
+                return -1;
+        }
+        if ((func = instance_getattr(self, lenstr)) == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return -1;
+            PyErr_Clear();
+            /* Fall back to the default behavior:
+               all instances are nonzero */
+            return 1;
+        }
+    }
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    if (res == NULL)
+        return -1;
+    if (!PyInt_Check(res)) {
+        Py_DECREF(res);
+        PyErr_SetString(PyExc_TypeError,
+                        "__nonzero__ should return an int");
+        return -1;
+    }
+    outcome = PyInt_AsLong(res);
+    Py_DECREF(res);
+    if (outcome < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "__nonzero__ should return >= 0");
+        return -1;
+    }
+    return outcome > 0;
+}
+
+static PyObject *
+instance_index(PyInstanceObject *self)
+{
+    PyObject *func, *res;
+    static PyObject *indexstr = NULL;
+
+    if (indexstr == NULL) {
+        indexstr = PyString_InternFromString("__index__");
+        if (indexstr == NULL)
+            return NULL;
+    }
+    if ((func = instance_getattr(self, indexstr)) == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "object cannot be interpreted as an index");
+        return NULL;
+    }
+    res = PyEval_CallObject(func, (PyObject *)NULL);
+    Py_DECREF(func);
+    return res;
+}
+
+
+UNARY(instance_invert, "__invert__")
+UNARY(_instance_trunc, "__trunc__")
+
+static PyObject *
+instance_int(PyInstanceObject *self)
+{
+    PyObject *truncated;
+    static PyObject *int_name;
+    if (int_name == NULL) {
+        int_name = PyString_InternFromString("__int__");
+        if (int_name == NULL)
+            return NULL;
+    }
+    if (PyObject_HasAttr((PyObject*)self, int_name))
+        return generic_unary_op(self, int_name);
+
+    truncated = _instance_trunc(self);
+    /* __trunc__ is specified to return an Integral type, but
+       int() needs to return an int. */
+    return _PyNumber_ConvertIntegralToInt(
+        truncated,
+        "__trunc__ returned non-Integral (type %.200s)");
+}
+
+UNARY_FB(instance_long, "__long__", instance_int)
+UNARY(instance_float, "__float__")
+UNARY(instance_oct, "__oct__")
+UNARY(instance_hex, "__hex__")
+
+static PyObject *
+bin_power(PyObject *v, PyObject *w)
+{
+    return PyNumber_Power(v, w, Py_None);
+}
+
+/* This version is for ternary calls only (z != None) */
+static PyObject *
+instance_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+    if (z == Py_None) {
+        return do_binop(v, w, "__pow__", "__rpow__", bin_power);
+    }
+    else {
+        PyObject *func;
+        PyObject *args;
+        PyObject *result;
+
+        /* XXX Doesn't do coercions... */
+        func = PyObject_GetAttrString(v, "__pow__");
+        if (func == NULL)
+            return NULL;
+        args = PyTuple_Pack(2, w, z);
+        if (args == NULL) {
+            Py_DECREF(func);
+            return NULL;
+        }
+        result = PyEval_CallObject(func, args);
+        Py_DECREF(func);
+        Py_DECREF(args);
+        return result;
+    }
+}
+
+static PyObject *
+bin_inplace_power(PyObject *v, PyObject *w)
+{
+    return PyNumber_InPlacePower(v, w, Py_None);
+}
+
+
+static PyObject *
+instance_ipow(PyObject *v, PyObject *w, PyObject *z)
+{
+    if (z == Py_None) {
+        return do_binop_inplace(v, w, "__ipow__", "__pow__",
+            "__rpow__", bin_inplace_power);
+    }
+    else {
+        /* XXX Doesn't do coercions... */
+        PyObject *func;
+        PyObject *args;
+        PyObject *result;
+
+        func = PyObject_GetAttrString(v, "__ipow__");
+        if (func == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return NULL;
+            PyErr_Clear();
+            return instance_pow(v, w, z);
+        }
+        args = PyTuple_Pack(2, w, z);
+        if (args == NULL) {
+            Py_DECREF(func);
+            return NULL;
+        }
+        result = PyEval_CallObject(func, args);
+        Py_DECREF(func);
+        Py_DECREF(args);
+        return result;
+    }
+}
+
+
+/* Map rich comparison operators to their __xx__ namesakes */
+#define NAME_OPS 6
+static PyObject **name_op = NULL;
+
+static int
+init_name_op(void)
+{
+    int i;
+    char *_name_op[] = {
+        "__lt__",
+        "__le__",
+        "__eq__",
+        "__ne__",
+        "__gt__",
+        "__ge__",
+    };
+
+    name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS);
+    if (name_op == NULL)
+        return -1;
+    for (i = 0; i < NAME_OPS; ++i) {
+        name_op[i] = PyString_InternFromString(_name_op[i]);
+        if (name_op[i] == NULL)
+            return -1;
+    }
+    return 0;
+}
+
+static PyObject *
+half_richcompare(PyObject *v, PyObject *w, int op)
+{
+    PyObject *method;
+    PyObject *args;
+    PyObject *res;
+
+    assert(PyInstance_Check(v));
+
+    if (name_op == NULL) {
+        if (init_name_op() < 0)
+            return NULL;
+    }
+    /* If the instance doesn't define an __getattr__ method, use
+       instance_getattr2 directly because it will not set an
+       exception on failure. */
+    if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL)
+        method = instance_getattr2((PyInstanceObject *)v,
+                                   name_op[op]);
+    else
+        method = PyObject_GetAttr(v, name_op[op]);
+    if (method == NULL) {
+        if (PyErr_Occurred()) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return NULL;
+            PyErr_Clear();
+        }
+        res = Py_NotImplemented;
+        Py_INCREF(res);
+        return res;
+    }
+
+    args = PyTuple_Pack(1, w);
+    if (args == NULL) {
+        Py_DECREF(method);
+        return NULL;
+    }
+
+    res = PyEval_CallObject(method, args);
+    Py_DECREF(args);
+    Py_DECREF(method);
+
+    return res;
+}
+
+static PyObject *
+instance_richcompare(PyObject *v, PyObject *w, int op)
+{
+    PyObject *res;
+
+    if (PyInstance_Check(v)) {
+        res = half_richcompare(v, w, op);
+        if (res != Py_NotImplemented)
+            return res;
+        Py_DECREF(res);
+    }
+
+    if (PyInstance_Check(w)) {
+        res = half_richcompare(w, v, _Py_SwappedOp[op]);
+        if (res != Py_NotImplemented)
+            return res;
+        Py_DECREF(res);
+    }
+
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+
+/* Get the iterator */
+static PyObject *
+instance_getiter(PyInstanceObject *self)
+{
+    PyObject *func;
+
+    if (iterstr == NULL) {
+        iterstr = PyString_InternFromString("__iter__");
+        if (iterstr == NULL)
+            return NULL;
+    }
+    if (getitemstr == NULL) {
+        getitemstr = PyString_InternFromString("__getitem__");
+        if (getitemstr == NULL)
+            return NULL;
+    }
+
+    if ((func = instance_getattr(self, iterstr)) != NULL) {
+        PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+        Py_DECREF(func);
+        if (res != NULL && !PyIter_Check(res)) {
+            PyErr_Format(PyExc_TypeError,
+                         "__iter__ returned non-iterator "
+                         "of type '%.100s'",
+                         res->ob_type->tp_name);
+            Py_DECREF(res);
+            res = NULL;
+        }
+        return res;
+    }
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+        return NULL;
+    PyErr_Clear();
+    if ((func = instance_getattr(self, getitemstr)) == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "iteration over non-sequence");
+        return NULL;
+    }
+    Py_DECREF(func);
+    return PySeqIter_New((PyObject *)self);
+}
+
+
+/* Call the iterator's next */
+static PyObject *
+instance_iternext(PyInstanceObject *self)
+{
+    PyObject *func;
+
+    if (nextstr == NULL) {
+        nextstr = PyString_InternFromString("next");
+        if (nextstr == NULL)
+            return NULL;
+    }
+
+    if ((func = instance_getattr(self, nextstr)) != NULL) {
+        PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+        Py_DECREF(func);
+        if (res != NULL) {
+            return res;
+        }
+        if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+            PyErr_Clear();
+            return NULL;
+        }
+        return NULL;
+    }
+    PyErr_SetString(PyExc_TypeError, "instance has no next() method");
+    return NULL;
+}
+
+static PyObject *
+instance_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+    PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
+    if (call == NULL) {
+        PyInstanceObject *inst = (PyInstanceObject*) func;
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+        PyErr_Format(PyExc_AttributeError,
+                     "%.200s instance has no __call__ method",
+                     PyString_AsString(inst->in_class->cl_name));
+        return NULL;
+    }
+    /* We must check and increment the recursion depth here. Scenario:
+           class A:
+           pass
+           A.__call__ = A() # that's right
+           a = A() # ok
+           a() # infinite recursion
+       This bounces between instance_call() and PyObject_Call() without
+       ever hitting eval_frame() (which has the main recursion check). */
+    if (Py_EnterRecursiveCall(" in __call__")) {
+        res = NULL;
+    }
+    else {
+        res = PyObject_Call(call, arg, kw);
+        Py_LeaveRecursiveCall();
+    }
+    Py_DECREF(call);
+    return res;
+}
+
+
+static PyNumberMethods instance_as_number = {
+    instance_add,                       /* nb_add */
+    instance_sub,                       /* nb_subtract */
+    instance_mul,                       /* nb_multiply */
+    instance_div,                       /* nb_divide */
+    instance_mod,                       /* nb_remainder */
+    instance_divmod,                    /* nb_divmod */
+    instance_pow,                       /* nb_power */
+    (unaryfunc)instance_neg,            /* nb_negative */
+    (unaryfunc)instance_pos,            /* nb_positive */
+    (unaryfunc)instance_abs,            /* nb_absolute */
+    (inquiry)instance_nonzero,          /* nb_nonzero */
+    (unaryfunc)instance_invert,         /* nb_invert */
+    instance_lshift,                    /* nb_lshift */
+    instance_rshift,                    /* nb_rshift */
+    instance_and,                       /* nb_and */
+    instance_xor,                       /* nb_xor */
+    instance_or,                        /* nb_or */
+    instance_coerce,                    /* nb_coerce */
+    (unaryfunc)instance_int,            /* nb_int */
+    (unaryfunc)instance_long,           /* nb_long */
+    (unaryfunc)instance_float,          /* nb_float */
+    (unaryfunc)instance_oct,            /* nb_oct */
+    (unaryfunc)instance_hex,            /* nb_hex */
+    instance_iadd,                      /* nb_inplace_add */
+    instance_isub,                      /* nb_inplace_subtract */
+    instance_imul,                      /* nb_inplace_multiply */
+    instance_idiv,                      /* nb_inplace_divide */
+    instance_imod,                      /* nb_inplace_remainder */
+    instance_ipow,                      /* nb_inplace_power */
+    instance_ilshift,                   /* nb_inplace_lshift */
+    instance_irshift,                   /* nb_inplace_rshift */
+    instance_iand,                      /* nb_inplace_and */
+    instance_ixor,                      /* nb_inplace_xor */
+    instance_ior,                       /* nb_inplace_or */
+    instance_floordiv,                  /* nb_floor_divide */
+    instance_truediv,                   /* nb_true_divide */
+    instance_ifloordiv,                 /* nb_inplace_floor_divide */
+    instance_itruediv,                  /* nb_inplace_true_divide */
+    (unaryfunc)instance_index,          /* nb_index */
+};
+
+PyTypeObject PyInstance_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "instance",
+    sizeof(PyInstanceObject),
+    0,
+    (destructor)instance_dealloc,               /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    instance_compare,                           /* tp_compare */
+    (reprfunc)instance_repr,                    /* tp_repr */
+    &instance_as_number,                        /* tp_as_number */
+    &instance_as_sequence,                      /* tp_as_sequence */
+    &instance_as_mapping,                       /* tp_as_mapping */
+    (hashfunc)instance_hash,                    /* tp_hash */
+    instance_call,                              /* tp_call */
+    (reprfunc)instance_str,                     /* tp_str */
+    (getattrofunc)instance_getattr,             /* tp_getattro */
+    (setattrofunc)instance_setattr,             /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/
+    instance_doc,                               /* tp_doc */
+    (traverseproc)instance_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    instance_richcompare,                       /* tp_richcompare */
+    offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
+    (getiterfunc)instance_getiter,              /* tp_iter */
+    (iternextfunc)instance_iternext,            /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    instance_new,                               /* tp_new */
+};
+
+
+/* Instance method objects are used for two purposes:
+   (a) as bound instance methods (returned by instancename.methodname)
+   (b) as unbound methods (returned by ClassName.methodname)
+   In case (b), im_self is NULL
+*/
+
+PyObject *
+PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
+{
+    register PyMethodObject *im;
+    im = free_list;
+    if (im != NULL) {
+        free_list = (PyMethodObject *)(im->im_self);
+        PyObject_INIT(im, &PyMethod_Type);
+        numfree--;
+    }
+    else {
+        im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
+        if (im == NULL)
+            return NULL;
+    }
+    im->im_weakreflist = NULL;
+    Py_INCREF(func);
+    im->im_func = func;
+    Py_XINCREF(self);
+    im->im_self = self;
+    Py_XINCREF(klass);
+    im->im_class = klass;
+    _PyObject_GC_TRACK(im);
+    return (PyObject *)im;
+}
+
+/* Descriptors for PyMethod attributes */
+
+/* im_class, im_func and im_self are stored in the PyMethod object */
+
+#define OFF(x) offsetof(PyMethodObject, x)
+
+static PyMemberDef instancemethod_memberlist[] = {
+    {"im_class",        T_OBJECT,       OFF(im_class),  READONLY|RESTRICTED,
+     "the class associated with a method"},
+    {"im_func",         T_OBJECT,       OFF(im_func),   READONLY|RESTRICTED,
+     "the function (or other callable) implementing a method"},
+    {"__func__",        T_OBJECT,       OFF(im_func),   READONLY|RESTRICTED,
+     "the function (or other callable) implementing a method"},
+    {"im_self",         T_OBJECT,       OFF(im_self),   READONLY|RESTRICTED,
+     "the instance to which a method is bound; None for unbound methods"},
+    {"__self__",        T_OBJECT,       OFF(im_self),   READONLY|RESTRICTED,
+     "the instance to which a method is bound; None for unbound methods"},
+    {NULL}      /* Sentinel */
+};
+
+/* Christian Tismer argued convincingly that method attributes should
+   (nearly) always override function attributes.
+   The one exception is __doc__; there's a default __doc__ which
+   should only be used for the class, not for instances */
+
+static PyObject *
+instancemethod_get_doc(PyMethodObject *im, void *context)
+{
+    static PyObject *docstr;
+    if (docstr == NULL) {
+        docstr= PyString_InternFromString("__doc__");
+        if (docstr == NULL)
+            return NULL;
+    }
+    return PyObject_GetAttr(im->im_func, docstr);
+}
+
+static PyGetSetDef instancemethod_getset[] = {
+    {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
+    {0}
+};
+
+static PyObject *
+instancemethod_getattro(PyObject *obj, PyObject *name)
+{
+    PyMethodObject *im = (PyMethodObject *)obj;
+    PyTypeObject *tp = obj->ob_type;
+    PyObject *descr = NULL;
+
+    if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {
+        if (tp->tp_dict == NULL) {
+            if (PyType_Ready(tp) < 0)
+                return NULL;
+        }
+        descr = _PyType_Lookup(tp, name);
+    }
+
+    if (descr != NULL) {
+        descrgetfunc f = TP_DESCR_GET(descr->ob_type);
+        if (f != NULL)
+            return f(descr, obj, (PyObject *)obj->ob_type);
+        else {
+            Py_INCREF(descr);
+            return descr;
+        }
+    }
+
+    return PyObject_GetAttr(im->im_func, name);
+}
+
+PyDoc_STRVAR(instancemethod_doc,
+"instancemethod(function, instance, class)\n\
+\n\
+Create an instance method object.");
+
+static PyObject *
+instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+    PyObject *func;
+    PyObject *self;
+    PyObject *classObj = NULL;
+
+    if (!_PyArg_NoKeywords("instancemethod", kw))
+        return NULL;
+    if (!PyArg_UnpackTuple(args, "instancemethod", 2, 3,
+                          &func, &self, &classObj))
+        return NULL;
+    if (!PyCallable_Check(func)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "first argument must be callable");
+        return NULL;
+    }
+    if (self == Py_None)
+        self = NULL;
+    if (self == NULL && classObj == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+            "unbound methods must have non-NULL im_class");
+        return NULL;
+    }
+
+    return PyMethod_New(func, self, classObj);
+}
+
+static void
+instancemethod_dealloc(register PyMethodObject *im)
+{
+    _PyObject_GC_UNTRACK(im);
+    if (im->im_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *)im);
+    Py_DECREF(im->im_func);
+    Py_XDECREF(im->im_self);
+    Py_XDECREF(im->im_class);
+    if (numfree < PyMethod_MAXFREELIST) {
+        im->im_self = (PyObject *)free_list;
+        free_list = im;
+        numfree++;
+    }
+    else {
+        PyObject_GC_Del(im);
+    }
+}
+
+static int
+instancemethod_compare(PyMethodObject *a, PyMethodObject *b)
+{
+    int cmp;
+    cmp = PyObject_Compare(a->im_func, b->im_func);
+    if (cmp)
+        return cmp;
+
+    if (a->im_self == b->im_self)
+        return 0;
+    if (a->im_self == NULL || b->im_self == NULL)
+        return (a->im_self < b->im_self) ? -1 : 1;
+    else
+        return PyObject_Compare(a->im_self, b->im_self);
+}
+
+static PyObject *
+instancemethod_repr(PyMethodObject *a)
+{
+    PyObject *self = a->im_self;
+    PyObject *func = a->im_func;
+    PyObject *klass = a->im_class;
+    PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
+    char *sfuncname = "?", *sklassname = "?";
+
+    funcname = PyObject_GetAttrString(func, "__name__");
+    if (funcname == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            return NULL;
+        PyErr_Clear();
+    }
+    else if (!PyString_Check(funcname)) {
+        Py_DECREF(funcname);
+        funcname = NULL;
+    }
+    else
+        sfuncname = PyString_AS_STRING(funcname);
+    if (klass == NULL)
+        klassname = NULL;
+    else {
+        klassname = PyObject_GetAttrString(klass, "__name__");
+        if (klassname == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+                return NULL;
+            PyErr_Clear();
+        }
+        else if (!PyString_Check(klassname)) {
+            Py_DECREF(klassname);
+            klassname = NULL;
+        }
+        else
+            sklassname = PyString_AS_STRING(klassname);
+    }
+    if (self == NULL)
+        result = PyString_FromFormat("<unbound method %s.%s>",
+                                     sklassname, sfuncname);
+    else {
+        /* XXX Shouldn't use repr() here! */
+        PyObject *selfrepr = PyObject_Repr(self);
+        if (selfrepr == NULL)
+            goto fail;
+        if (!PyString_Check(selfrepr)) {
+            Py_DECREF(selfrepr);
+            goto fail;
+        }
+        result = PyString_FromFormat("<bound method %s.%s of %s>",
+                                     sklassname, sfuncname,
+                                     PyString_AS_STRING(selfrepr));
+        Py_DECREF(selfrepr);
+    }
+  fail:
+    Py_XDECREF(funcname);
+    Py_XDECREF(klassname);
+    return result;
+}
+
+static long
+instancemethod_hash(PyMethodObject *a)
+{
+    long x, y;
+    if (a->im_self == NULL)
+        x = PyObject_Hash(Py_None);
+    else
+        x = PyObject_Hash(a->im_self);
+    if (x == -1)
+        return -1;
+    y = PyObject_Hash(a->im_func);
+    if (y == -1)
+        return -1;
+    x = x ^ y;
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+static int
+instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
+{
+    Py_VISIT(im->im_func);
+    Py_VISIT(im->im_self);
+    Py_VISIT(im->im_class);
+    return 0;
+}
+
+static void
+getclassname(PyObject *klass, char *buf, int bufsize)
+{
+    PyObject *name;
+
+    assert(bufsize > 1);
+    strcpy(buf, "?"); /* Default outcome */
+    if (klass == NULL)
+        return;
+    name = PyObject_GetAttrString(klass, "__name__");
+    if (name == NULL) {
+        /* This function cannot return an exception */
+        PyErr_Clear();
+        return;
+    }
+    if (PyString_Check(name)) {
+        strncpy(buf, PyString_AS_STRING(name), bufsize);
+        buf[bufsize-1] = '\0';
+    }
+    Py_DECREF(name);
+}
+
+static void
+getinstclassname(PyObject *inst, char *buf, int bufsize)
+{
+    PyObject *klass;
+
+    if (inst == NULL) {
+        assert(bufsize > 0 && (size_t)bufsize > strlen("nothing"));
+        strcpy(buf, "nothing");
+        return;
+    }
+
+    klass = PyObject_GetAttrString(inst, "__class__");
+    if (klass == NULL) {
+        /* This function cannot return an exception */
+        PyErr_Clear();
+        klass = (PyObject *)(inst->ob_type);
+        Py_INCREF(klass);
+    }
+    getclassname(klass, buf, bufsize);
+    Py_XDECREF(klass);
+}
+
+static PyObject *
+instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+    PyObject *self = PyMethod_GET_SELF(func);
+    PyObject *klass = PyMethod_GET_CLASS(func);
+    PyObject *result;
+
+    func = PyMethod_GET_FUNCTION(func);
+    if (self == NULL) {
+        /* Unbound methods must be called with an instance of
+           the class (or a derived class) as first argument */
+        int ok;
+        if (PyTuple_Size(arg) >= 1)
+            self = PyTuple_GET_ITEM(arg, 0);
+        if (self == NULL)
+            ok = 0;
+        else {
+            ok = PyObject_IsInstance(self, klass);
+            if (ok < 0)
+                return NULL;
+        }
+        if (!ok) {
+            char clsbuf[256];
+            char instbuf[256];
+            getclassname(klass, clsbuf, sizeof(clsbuf));
+            getinstclassname(self, instbuf, sizeof(instbuf));
+            PyErr_Format(PyExc_TypeError,
+                         "unbound method %s%s must be called with "
+                         "%s instance as first argument "
+                         "(got %s%s instead)",
+                         PyEval_GetFuncName(func),
+                         PyEval_GetFuncDesc(func),
+                         clsbuf,
+                         instbuf,
+                         self == NULL ? "" : " instance");
+            return NULL;
+        }
+        Py_INCREF(arg);
+    }
+    else {
+        Py_ssize_t argcount = PyTuple_Size(arg);
+        PyObject *newarg = PyTuple_New(argcount + 1);
+        int i;
+        if (newarg == NULL)
+            return NULL;
+        Py_INCREF(self);
+        PyTuple_SET_ITEM(newarg, 0, self);
+        for (i = 0; i < argcount; i++) {
+            PyObject *v = PyTuple_GET_ITEM(arg, i);
+            Py_XINCREF(v);
+            PyTuple_SET_ITEM(newarg, i+1, v);
+        }
+        arg = newarg;
+    }
+    result = PyObject_Call((PyObject *)func, arg, kw);
+    Py_DECREF(arg);
+    return result;
+}
+
+static PyObject *
+instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
+{
+    /* Don't rebind an already bound method, or an unbound method
+       of a class that's not a base class of cls. */
+
+    if (PyMethod_GET_SELF(meth) != NULL) {
+        /* Already bound */
+        Py_INCREF(meth);
+        return meth;
+    }
+    /* No, it is an unbound method */
+    if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) {
+        /* Do subclass test.  If it fails, return meth unchanged. */
+        int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth));
+        if (ok < 0)
+            return NULL;
+        if (!ok) {
+            Py_INCREF(meth);
+            return meth;
+        }
+    }
+    /* Bind it to obj */
+    return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls);
+}
+
+PyTypeObject PyMethod_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,
+    "instancemethod",
+    sizeof(PyMethodObject),
+    0,
+    (destructor)instancemethod_dealloc,         /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)instancemethod_compare,            /* tp_compare */
+    (reprfunc)instancemethod_repr,              /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)instancemethod_hash,              /* tp_hash */
+    instancemethod_call,                        /* tp_call */
+    0,                                          /* tp_str */
+    instancemethod_getattro,                    /* tp_getattro */
+    PyObject_GenericSetAttr,                    /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC  | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+    instancemethod_doc,                         /* tp_doc */
+    (traverseproc)instancemethod_traverse,      /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    instancemethod_memberlist,                  /* tp_members */
+    instancemethod_getset,                      /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    instancemethod_descr_get,                   /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    instancemethod_new,                         /* tp_new */
+};
+
+/* Clear out the free list */
+
+int
+PyMethod_ClearFreeList(void)
+{
+    int freelist_size = numfree;
+
+    while (free_list) {
+        PyMethodObject *im = free_list;
+        free_list = (PyMethodObject *)(im->im_self);
+        PyObject_GC_Del(im);
+        numfree--;
+    }
+    assert(numfree == 0);
+    return freelist_size;
+}
+
+void
+PyMethod_Fini(void)
+{
+    (void)PyMethod_ClearFreeList();
+}
diff --git a/Python-2.7.5/Objects/cobject.c b/Python-2.7.5/Objects/cobject.c
new file mode 100644
index 0000000..355421e
--- /dev/null
+++ b/Python-2.7.5/Objects/cobject.c
@@ -0,0 +1,172 @@
+
+/* Wrap void* pointers to be passed between C modules */
+
+#include "Python.h"
+
+
+/* Declarations for objects of type PyCObject */
+
+typedef void (*destructor1)(void *);
+typedef void (*destructor2)(void *, void*);
+
+static int cobject_deprecation_warning(void)
+{
+    return PyErr_WarnPy3k("CObject type is not supported in 3.x. "
+        "Please use capsule objects instead.", 1);
+}
+
+
+PyObject *
+PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
+{
+    PyCObject *self;
+
+    if (cobject_deprecation_warning()) {
+        return NULL;
+    }
+
+    self = PyObject_NEW(PyCObject, &PyCObject_Type);
+    if (self == NULL)
+        return NULL;
+    self->cobject=cobj;
+    self->destructor=destr;
+    self->desc=NULL;
+
+    return (PyObject *)self;
+}
+
+PyObject *
+PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
+                             void (*destr)(void *, void *))
+{
+    PyCObject *self;
+
+    if (cobject_deprecation_warning()) {
+        return NULL;
+    }
+
+    if (!desc) {
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_FromVoidPtrAndDesc called with null"
+                        " description");
+        return NULL;
+    }
+    self = PyObject_NEW(PyCObject, &PyCObject_Type);
+    if (self == NULL)
+        return NULL;
+    self->cobject = cobj;
+    self->destructor = (destructor1)destr;
+    self->desc = desc;
+
+    return (PyObject *)self;
+}
+
+void *
+PyCObject_AsVoidPtr(PyObject *self)
+{
+    if (self) {
+        if (PyCapsule_CheckExact(self)) {
+            const char *name = PyCapsule_GetName(self);
+            return (void *)PyCapsule_GetPointer(self, name);
+        }
+        if (self->ob_type == &PyCObject_Type)
+            return ((PyCObject *)self)->cobject;
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_AsVoidPtr with non-C-object");
+    }
+    if (!PyErr_Occurred())
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_AsVoidPtr called with null pointer");
+    return NULL;
+}
+
+void *
+PyCObject_GetDesc(PyObject *self)
+{
+    if (self) {
+        if (self->ob_type == &PyCObject_Type)
+            return ((PyCObject *)self)->desc;
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_GetDesc with non-C-object");
+    }
+    if (!PyErr_Occurred())
+        PyErr_SetString(PyExc_TypeError,
+                        "PyCObject_GetDesc called with null pointer");
+    return NULL;
+}
+
+void *
+PyCObject_Import(char *module_name, char *name)
+{
+    PyObject *m, *c;
+    void *r = NULL;
+
+    if ((m = PyImport_ImportModule(module_name))) {
+        if ((c = PyObject_GetAttrString(m,name))) {
+            r = PyCObject_AsVoidPtr(c);
+            Py_DECREF(c);
+	}
+        Py_DECREF(m);
+    }
+    return r;
+}
+
+int
+PyCObject_SetVoidPtr(PyObject *self, void *cobj)
+{
+    PyCObject* cself = (PyCObject*)self;
+    if (cself == NULL || !PyCObject_Check(cself) ||
+	cself->destructor != NULL) {
+	PyErr_SetString(PyExc_TypeError, 
+			"Invalid call to PyCObject_SetVoidPtr");
+	return 0;
+    }
+    cself->cobject = cobj;
+    return 1;
+}
+
+static void
+PyCObject_dealloc(PyCObject *self)
+{
+    if (self->destructor) {
+        if(self->desc)
+            ((destructor2)(self->destructor))(self->cobject, self->desc);
+        else
+            (self->destructor)(self->cobject);
+    }
+    PyObject_DEL(self);
+}
+
+
+PyDoc_STRVAR(PyCObject_Type__doc__,
+"C objects to be exported from one extension module to another\n\
+\n\
+C objects are used for communication between extension modules.  They\n\
+provide a way for an extension module to export a C interface to other\n\
+extension modules, so that extension modules can use the Python import\n\
+mechanism to link to one another.");
+
+PyTypeObject PyCObject_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "PyCObject",		/*tp_name*/
+    sizeof(PyCObject),		/*tp_basicsize*/
+    0,				/*tp_itemsize*/
+    /* methods */
+    (destructor)PyCObject_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*/
+    0,				/*tp_str*/
+    0,				/*tp_getattro*/
+    0,				/*tp_setattro*/
+    0,				/*tp_as_buffer*/
+    0,				/*tp_flags*/
+    PyCObject_Type__doc__	/*tp_doc*/
+};
diff --git a/Python-2.7.5/Objects/codeobject.c b/Python-2.7.5/Objects/codeobject.c
new file mode 100644
index 0000000..9879df5
--- /dev/null
+++ b/Python-2.7.5/Objects/codeobject.c
@@ -0,0 +1,581 @@
+#include "Python.h"
+#include "code.h"
+#include "structmember.h"
+
+#define NAME_CHARS \
+    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+
+/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
+
+static int
+all_name_chars(unsigned char *s)
+{
+    static char ok_name_char[256];
+    static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
+
+    if (ok_name_char[*name_chars] == 0) {
+        unsigned char *p;
+        for (p = name_chars; *p; p++)
+            ok_name_char[*p] = 1;
+    }
+    while (*s) {
+        if (ok_name_char[*s++] == 0)
+            return 0;
+    }
+    return 1;
+}
+
+static void
+intern_strings(PyObject *tuple)
+{
+    Py_ssize_t i;
+
+    for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
+        PyObject *v = PyTuple_GET_ITEM(tuple, i);
+        if (v == NULL || !PyString_CheckExact(v)) {
+            Py_FatalError("non-string found in code slot");
+        }
+        PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
+    }
+}
+
+
+PyCodeObject *
+PyCode_New(int argcount, int nlocals, int stacksize, int flags,
+           PyObject *code, PyObject *consts, PyObject *names,
+           PyObject *varnames, PyObject *freevars, PyObject *cellvars,
+           PyObject *filename, PyObject *name, int firstlineno,
+           PyObject *lnotab)
+{
+    PyCodeObject *co;
+    Py_ssize_t i;
+    /* Check argument types */
+    if (argcount < 0 || nlocals < 0 ||
+        code == NULL ||
+        consts == NULL || !PyTuple_Check(consts) ||
+        names == NULL || !PyTuple_Check(names) ||
+        varnames == NULL || !PyTuple_Check(varnames) ||
+        freevars == NULL || !PyTuple_Check(freevars) ||
+        cellvars == NULL || !PyTuple_Check(cellvars) ||
+        name == NULL || !PyString_Check(name) ||
+        filename == NULL || !PyString_Check(filename) ||
+        lnotab == NULL || !PyString_Check(lnotab) ||
+        !PyObject_CheckReadBuffer(code)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    intern_strings(names);
+    intern_strings(varnames);
+    intern_strings(freevars);
+    intern_strings(cellvars);
+    /* Intern selected string constants */
+    for (i = PyTuple_Size(consts); --i >= 0; ) {
+        PyObject *v = PyTuple_GetItem(consts, i);
+        if (!PyString_Check(v))
+            continue;
+        if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
+            continue;
+        PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
+    }
+    co = PyObject_NEW(PyCodeObject, &PyCode_Type);
+    if (co != NULL) {
+        co->co_argcount = argcount;
+        co->co_nlocals = nlocals;
+        co->co_stacksize = stacksize;
+        co->co_flags = flags;
+        Py_INCREF(code);
+        co->co_code = code;
+        Py_INCREF(consts);
+        co->co_consts = consts;
+        Py_INCREF(names);
+        co->co_names = names;
+        Py_INCREF(varnames);
+        co->co_varnames = varnames;
+        Py_INCREF(freevars);
+        co->co_freevars = freevars;
+        Py_INCREF(cellvars);
+        co->co_cellvars = cellvars;
+        Py_INCREF(filename);
+        co->co_filename = filename;
+        Py_INCREF(name);
+        co->co_name = name;
+        co->co_firstlineno = firstlineno;
+        Py_INCREF(lnotab);
+        co->co_lnotab = lnotab;
+        co->co_zombieframe = NULL;
+        co->co_weakreflist = NULL;
+    }
+    return co;
+}
+
+PyCodeObject *
+PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
+{
+    static PyObject *emptystring = NULL;
+    static PyObject *nulltuple = NULL;
+    PyObject *filename_ob = NULL;
+    PyObject *funcname_ob = NULL;
+    PyCodeObject *result = NULL;
+    if (emptystring == NULL) {
+        emptystring = PyString_FromString("");
+        if (emptystring == NULL)
+            goto failed;
+    }
+    if (nulltuple == NULL) {
+        nulltuple = PyTuple_New(0);
+        if (nulltuple == NULL)
+            goto failed;
+    }
+    funcname_ob = PyString_FromString(funcname);
+    if (funcname_ob == NULL)
+        goto failed;
+    filename_ob = PyString_FromString(filename);
+    if (filename_ob == NULL)
+        goto failed;
+
+    result = PyCode_New(0,                      /* argcount */
+                0,                              /* nlocals */
+                0,                              /* stacksize */
+                0,                              /* flags */
+                emptystring,                    /* code */
+                nulltuple,                      /* consts */
+                nulltuple,                      /* names */
+                nulltuple,                      /* varnames */
+                nulltuple,                      /* freevars */
+                nulltuple,                      /* cellvars */
+                filename_ob,                    /* filename */
+                funcname_ob,                    /* name */
+                firstlineno,                    /* firstlineno */
+                emptystring                     /* lnotab */
+                );
+
+failed:
+    Py_XDECREF(funcname_ob);
+    Py_XDECREF(filename_ob);
+    return result;
+}
+
+#define OFF(x) offsetof(PyCodeObject, x)
+
+static PyMemberDef code_memberlist[] = {
+    {"co_argcount",     T_INT,          OFF(co_argcount),       READONLY},
+    {"co_nlocals",      T_INT,          OFF(co_nlocals),        READONLY},
+    {"co_stacksize",T_INT,              OFF(co_stacksize),      READONLY},
+    {"co_flags",        T_INT,          OFF(co_flags),          READONLY},
+    {"co_code",         T_OBJECT,       OFF(co_code),           READONLY},
+    {"co_consts",       T_OBJECT,       OFF(co_consts),         READONLY},
+    {"co_names",        T_OBJECT,       OFF(co_names),          READONLY},
+    {"co_varnames",     T_OBJECT,       OFF(co_varnames),       READONLY},
+    {"co_freevars",     T_OBJECT,       OFF(co_freevars),       READONLY},
+    {"co_cellvars",     T_OBJECT,       OFF(co_cellvars),       READONLY},
+    {"co_filename",     T_OBJECT,       OFF(co_filename),       READONLY},
+    {"co_name",         T_OBJECT,       OFF(co_name),           READONLY},
+    {"co_firstlineno", T_INT,           OFF(co_firstlineno),    READONLY},
+    {"co_lnotab",       T_OBJECT,       OFF(co_lnotab),         READONLY},
+    {NULL}      /* Sentinel */
+};
+
+/* Helper for code_new: return a shallow copy of a tuple that is
+   guaranteed to contain exact strings, by converting string subclasses
+   to exact strings and complaining if a non-string is found. */
+static PyObject*
+validate_and_copy_tuple(PyObject *tup)
+{
+    PyObject *newtuple;
+    PyObject *item;
+    Py_ssize_t i, len;
+
+    len = PyTuple_GET_SIZE(tup);
+    newtuple = PyTuple_New(len);
+    if (newtuple == NULL)
+        return NULL;
+
+    for (i = 0; i < len; i++) {
+        item = PyTuple_GET_ITEM(tup, i);
+        if (PyString_CheckExact(item)) {
+            Py_INCREF(item);
+        }
+        else if (!PyString_Check(item)) {
+            PyErr_Format(
+                PyExc_TypeError,
+                "name tuples must contain only "
+                "strings, not '%.500s'",
+                item->ob_type->tp_name);
+            Py_DECREF(newtuple);
+            return NULL;
+        }
+        else {
+            item = PyString_FromStringAndSize(
+                PyString_AS_STRING(item),
+                PyString_GET_SIZE(item));
+            if (item == NULL) {
+                Py_DECREF(newtuple);
+                return NULL;
+            }
+        }
+        PyTuple_SET_ITEM(newtuple, i, item);
+    }
+
+    return newtuple;
+}
+
+PyDoc_STRVAR(code_doc,
+"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
+      varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
+\n\
+Create a code object.  Not for the faint of heart.");
+
+static PyObject *
+code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+    int argcount;
+    int nlocals;
+    int stacksize;
+    int flags;
+    PyObject *co = NULL;
+    PyObject *code;
+    PyObject *consts;
+    PyObject *names, *ournames = NULL;
+    PyObject *varnames, *ourvarnames = NULL;
+    PyObject *freevars = NULL, *ourfreevars = NULL;
+    PyObject *cellvars = NULL, *ourcellvars = NULL;
+    PyObject *filename;
+    PyObject *name;
+    int firstlineno;
+    PyObject *lnotab;
+
+    if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
+                          &argcount, &nlocals, &stacksize, &flags,
+                          &code,
+                          &PyTuple_Type, &consts,
+                          &PyTuple_Type, &names,
+                          &PyTuple_Type, &varnames,
+                          &filename, &name,
+                          &firstlineno, &lnotab,
+                          &PyTuple_Type, &freevars,
+                          &PyTuple_Type, &cellvars))
+        return NULL;
+
+    if (argcount < 0) {
+        PyErr_SetString(
+            PyExc_ValueError,
+            "code: argcount must not be negative");
+        goto cleanup;
+    }
+
+    if (nlocals < 0) {
+        PyErr_SetString(
+            PyExc_ValueError,
+            "code: nlocals must not be negative");
+        goto cleanup;
+    }
+
+    ournames = validate_and_copy_tuple(names);
+    if (ournames == NULL)
+        goto cleanup;
+    ourvarnames = validate_and_copy_tuple(varnames);
+    if (ourvarnames == NULL)
+        goto cleanup;
+    if (freevars)
+        ourfreevars = validate_and_copy_tuple(freevars);
+    else
+        ourfreevars = PyTuple_New(0);
+    if (ourfreevars == NULL)
+        goto cleanup;
+    if (cellvars)
+        ourcellvars = validate_and_copy_tuple(cellvars);
+    else
+        ourcellvars = PyTuple_New(0);
+    if (ourcellvars == NULL)
+        goto cleanup;
+
+    co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
+                                code, consts, ournames, ourvarnames,
+                                ourfreevars, ourcellvars, filename,
+                                name, firstlineno, lnotab);
+  cleanup:
+    Py_XDECREF(ournames);
+    Py_XDECREF(ourvarnames);
+    Py_XDECREF(ourfreevars);
+    Py_XDECREF(ourcellvars);
+    return co;
+}
+
+static void
+code_dealloc(PyCodeObject *co)
+{
+    Py_XDECREF(co->co_code);
+    Py_XDECREF(co->co_consts);
+    Py_XDECREF(co->co_names);
+    Py_XDECREF(co->co_varnames);
+    Py_XDECREF(co->co_freevars);
+    Py_XDECREF(co->co_cellvars);
+    Py_XDECREF(co->co_filename);
+    Py_XDECREF(co->co_name);
+    Py_XDECREF(co->co_lnotab);
+    if (co->co_zombieframe != NULL)
+        PyObject_GC_Del(co->co_zombieframe);
+    if (co->co_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject*)co);
+    PyObject_DEL(co);
+}
+
+static PyObject *
+code_repr(PyCodeObject *co)
+{
+    char buf[500];
+    int lineno = -1;
+    char *filename = "???";
+    char *name = "???";
+
+    if (co->co_firstlineno != 0)
+        lineno = co->co_firstlineno;
+    if (co->co_filename && PyString_Check(co->co_filename))
+        filename = PyString_AS_STRING(co->co_filename);
+    if (co->co_name && PyString_Check(co->co_name))
+        name = PyString_AS_STRING(co->co_name);
+    PyOS_snprintf(buf, sizeof(buf),
+                  "<code object %.100s at %p, file \"%.300s\", line %d>",
+                  name, co, filename, lineno);
+    return PyString_FromString(buf);
+}
+
+static int
+code_compare(PyCodeObject *co, PyCodeObject *cp)
+{
+    int cmp;
+    cmp = PyObject_Compare(co->co_name, cp->co_name);
+    if (cmp) return cmp;
+    cmp = co->co_argcount - cp->co_argcount;
+    if (cmp) goto normalize;
+    cmp = co->co_nlocals - cp->co_nlocals;
+    if (cmp) goto normalize;
+    cmp = co->co_flags - cp->co_flags;
+    if (cmp) goto normalize;
+    cmp = co->co_firstlineno - cp->co_firstlineno;
+    if (cmp) goto normalize;
+    cmp = PyObject_Compare(co->co_code, cp->co_code);
+    if (cmp) return cmp;
+    cmp = PyObject_Compare(co->co_consts, cp->co_consts);
+    if (cmp) return cmp;
+    cmp = PyObject_Compare(co->co_names, cp->co_names);
+    if (cmp) return cmp;
+    cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
+    if (cmp) return cmp;
+    cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
+    if (cmp) return cmp;
+    cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
+    return cmp;
+
+ normalize:
+    if (cmp > 0)
+        return 1;
+    else if (cmp < 0)
+        return -1;
+    else
+        return 0;
+}
+
+static PyObject *
+code_richcompare(PyObject *self, PyObject *other, int op)
+{
+    PyCodeObject *co, *cp;
+    int eq;
+    PyObject *res;
+
+    if ((op != Py_EQ && op != Py_NE) ||
+        !PyCode_Check(self) ||
+        !PyCode_Check(other)) {
+
+        /* Py3K warning if types are not equal and comparison
+        isn't == or !=  */
+        if (PyErr_WarnPy3k("code inequality comparisons not supported "
+                           "in 3.x", 1) < 0) {
+            return NULL;
+        }
+
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    co = (PyCodeObject *)self;
+    cp = (PyCodeObject *)other;
+
+    eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
+    if (eq <= 0) goto unequal;
+    eq = co->co_argcount == cp->co_argcount;
+    if (!eq) goto unequal;
+    eq = co->co_nlocals == cp->co_nlocals;
+    if (!eq) goto unequal;
+    eq = co->co_flags == cp->co_flags;
+    if (!eq) goto unequal;
+    eq = co->co_firstlineno == cp->co_firstlineno;
+    if (!eq) goto unequal;
+    eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
+    if (eq <= 0) goto unequal;
+    eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
+    if (eq <= 0) goto unequal;
+    eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
+    if (eq <= 0) goto unequal;
+    eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
+    if (eq <= 0) goto unequal;
+    eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
+    if (eq <= 0) goto unequal;
+    eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
+    if (eq <= 0) goto unequal;
+
+    if (op == Py_EQ)
+        res = Py_True;
+    else
+        res = Py_False;
+    goto done;
+
+  unequal:
+    if (eq < 0)
+        return NULL;
+    if (op == Py_NE)
+        res = Py_True;
+    else
+        res = Py_False;
+
+  done:
+    Py_INCREF(res);
+    return res;
+}
+
+static long
+code_hash(PyCodeObject *co)
+{
+    long h, h0, h1, h2, h3, h4, h5, h6;
+    h0 = PyObject_Hash(co->co_name);
+    if (h0 == -1) return -1;
+    h1 = PyObject_Hash(co->co_code);
+    if (h1 == -1) return -1;
+    h2 = PyObject_Hash(co->co_consts);
+    if (h2 == -1) return -1;
+    h3 = PyObject_Hash(co->co_names);
+    if (h3 == -1) return -1;
+    h4 = PyObject_Hash(co->co_varnames);
+    if (h4 == -1) return -1;
+    h5 = PyObject_Hash(co->co_freevars);
+    if (h5 == -1) return -1;
+    h6 = PyObject_Hash(co->co_cellvars);
+    if (h6 == -1) return -1;
+    h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
+        co->co_argcount ^ co->co_nlocals ^ co->co_flags;
+    if (h == -1) h = -2;
+    return h;
+}
+
+/* XXX code objects need to participate in GC? */
+
+PyTypeObject PyCode_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "code",
+    sizeof(PyCodeObject),
+    0,
+    (destructor)code_dealloc,           /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    (cmpfunc)code_compare,              /* tp_compare */
+    (reprfunc)code_repr,                /* tp_repr */
+    0,                                  /* tp_as_number */
+    0,                                  /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    (hashfunc)code_hash,                /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+    code_doc,                           /* tp_doc */
+    0,                                  /* tp_traverse */
+    0,                                  /* tp_clear */
+    code_richcompare,                   /* tp_richcompare */
+    offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
+    0,                                  /* tp_iter */
+    0,                                  /* tp_iternext */
+    0,                                  /* tp_methods */
+    code_memberlist,                    /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
+    0,                                  /* tp_dictoffset */
+    0,                                  /* tp_init */
+    0,                                  /* tp_alloc */
+    code_new,                           /* tp_new */
+};
+
+/* Use co_lnotab to compute the line number from a bytecode index, addrq.  See
+   lnotab_notes.txt for the details of the lnotab representation.
+*/
+
+int
+PyCode_Addr2Line(PyCodeObject *co, int addrq)
+{
+    int size = PyString_Size(co->co_lnotab) / 2;
+    unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
+    int line = co->co_firstlineno;
+    int addr = 0;
+    while (--size >= 0) {
+        addr += *p++;
+        if (addr > addrq)
+            break;
+        line += *p++;
+    }
+    return line;
+}
+
+/* Update *bounds to describe the first and one-past-the-last instructions in
+   the same line as lasti.  Return the number of that line. */
+int
+_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
+{
+    int size, addr, line;
+    unsigned char* p;
+
+    p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
+    size = PyString_GET_SIZE(co->co_lnotab) / 2;
+
+    addr = 0;
+    line = co->co_firstlineno;
+    assert(line > 0);
+
+    /* possible optimization: if f->f_lasti == instr_ub
+       (likely to be a common case) then we already know
+       instr_lb -- if we stored the matching value of p
+       somwhere we could skip the first while loop. */
+
+    /* See lnotab_notes.txt for the description of
+       co_lnotab.  A point to remember: increments to p
+       come in (addr, line) pairs. */
+
+    bounds->ap_lower = 0;
+    while (size > 0) {
+        if (addr + *p > lasti)
+            break;
+        addr += *p++;
+        if (*p)
+            bounds->ap_lower = addr;
+        line += *p++;
+        --size;
+    }
+
+    if (size > 0) {
+        while (--size >= 0) {
+            addr += *p++;
+            if (*p++)
+                break;
+        }
+        bounds->ap_upper = addr;
+    }
+    else {
+        bounds->ap_upper = INT_MAX;
+    }
+
+    return line;
+}
diff --git a/Python-2.7.5/Objects/complexobject.c b/Python-2.7.5/Objects/complexobject.c
new file mode 100644
index 0000000..677ac0e
--- /dev/null
+++ b/Python-2.7.5/Objects/complexobject.c
@@ -0,0 +1,1353 @@
+
+/* Complex object implementation */
+
+/* Borrows heavily from floatobject.c */
+
+/* Submitted by Jim Hugunin */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifndef WITHOUT_COMPLEX
+
+/* Precisions used by repr() and str(), respectively.
+
+   The repr() precision (17 significant decimal digits) is the minimal number
+   that is guaranteed to have enough precision so that if the number is read
+   back in the exact same binary value is recreated.  This is true for IEEE
+   floating point by design, and also happens to work for all other modern
+   hardware.
+
+   The str() precision is chosen so that in most cases, the rounding noise
+   created by various operations is suppressed, while giving plenty of
+   precision for practical use.
+*/
+
+#define PREC_REPR       17
+#define PREC_STR        12
+
+/* elementary operations on complex numbers */
+
+static Py_complex c_1 = {1., 0.};
+
+Py_complex
+c_sum(Py_complex a, Py_complex b)
+{
+    Py_complex r;
+    r.real = a.real + b.real;
+    r.imag = a.imag + b.imag;
+    return r;
+}
+
+Py_complex
+c_diff(Py_complex a, Py_complex b)
+{
+    Py_complex r;
+    r.real = a.real - b.real;
+    r.imag = a.imag - b.imag;
+    return r;
+}
+
+Py_complex
+c_neg(Py_complex a)
+{
+    Py_complex r;
+    r.real = -a.real;
+    r.imag = -a.imag;
+    return r;
+}
+
+Py_complex
+c_prod(Py_complex a, Py_complex b)
+{
+    Py_complex r;
+    r.real = a.real*b.real - a.imag*b.imag;
+    r.imag = a.real*b.imag + a.imag*b.real;
+    return r;
+}
+
+Py_complex
+c_quot(Py_complex a, Py_complex b)
+{
+    /******************************************************************
+    This was the original algorithm.  It's grossly prone to spurious
+    overflow and underflow errors.  It also merrily divides by 0 despite
+    checking for that(!).  The code still serves a doc purpose here, as
+    the algorithm following is a simple by-cases transformation of this
+    one:
+
+    Py_complex r;
+    double d = b.real*b.real + b.imag*b.imag;
+    if (d == 0.)
+        errno = EDOM;
+    r.real = (a.real*b.real + a.imag*b.imag)/d;
+    r.imag = (a.imag*b.real - a.real*b.imag)/d;
+    return r;
+    ******************************************************************/
+
+    /* This algorithm is better, and is pretty obvious:  first divide the
+     * numerators and denominator by whichever of {b.real, b.imag} has
+     * larger magnitude.  The earliest reference I found was to CACM
+     * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
+     * University).  As usual, though, we're still ignoring all IEEE
+     * endcases.
+     */
+     Py_complex r;      /* the result */
+     const double abs_breal = b.real < 0 ? -b.real : b.real;
+     const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
+
+     if (abs_breal >= abs_bimag) {
+        /* divide tops and bottom by b.real */
+        if (abs_breal == 0.0) {
+            errno = EDOM;
+            r.real = r.imag = 0.0;
+        }
+        else {
+            const double ratio = b.imag / b.real;
+            const double denom = b.real + b.imag * ratio;
+            r.real = (a.real + a.imag * ratio) / denom;
+            r.imag = (a.imag - a.real * ratio) / denom;
+        }
+    }
+    else {
+        /* divide tops and bottom by b.imag */
+        const double ratio = b.real / b.imag;
+        const double denom = b.real * ratio + b.imag;
+        assert(b.imag != 0.0);
+        r.real = (a.real * ratio + a.imag) / denom;
+        r.imag = (a.imag * ratio - a.real) / denom;
+    }
+    return r;
+}
+
+Py_complex
+c_pow(Py_complex a, Py_complex b)
+{
+    Py_complex r;
+    double vabs,len,at,phase;
+    if (b.real == 0. && b.imag == 0.) {
+        r.real = 1.;
+        r.imag = 0.;
+    }
+    else if (a.real == 0. && a.imag == 0.) {
+        if (b.imag != 0. || b.real < 0.)
+            errno = EDOM;
+        r.real = 0.;
+        r.imag = 0.;
+    }
+    else {
+        vabs = hypot(a.real,a.imag);
+        len = pow(vabs,b.real);
+        at = atan2(a.imag, a.real);
+        phase = at*b.real;
+        if (b.imag != 0.0) {
+            len /= exp(at*b.imag);
+            phase += b.imag*log(vabs);
+        }
+        r.real = len*cos(phase);
+        r.imag = len*sin(phase);
+    }
+    return r;
+}
+
+static Py_complex
+c_powu(Py_complex x, long n)
+{
+    Py_complex r, p;
+    long mask = 1;
+    r = c_1;
+    p = x;
+    while (mask > 0 && n >= mask) {
+        if (n & mask)
+            r = c_prod(r,p);
+        mask <<= 1;
+        p = c_prod(p,p);
+    }
+    return r;
+}
+
+static Py_complex
+c_powi(Py_complex x, long n)
+{
+    Py_complex cn;
+
+    if (n > 100 || n < -100) {
+        cn.real = (double) n;
+        cn.imag = 0.;
+        return c_pow(x,cn);
+    }
+    else if (n > 0)
+        return c_powu(x,n);
+    else
+        return c_quot(c_1,c_powu(x,-n));
+
+}
+
+double
+c_abs(Py_complex z)
+{
+    /* sets errno = ERANGE on overflow;  otherwise errno = 0 */
+    double result;
+
+    if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+        /* C99 rules: if either the real or the imaginary part is an
+           infinity, return infinity, even if the other part is a
+           NaN. */
+        if (Py_IS_INFINITY(z.real)) {
+            result = fabs(z.real);
+            errno = 0;
+            return result;
+        }
+        if (Py_IS_INFINITY(z.imag)) {
+            result = fabs(z.imag);
+            errno = 0;
+            return result;
+        }
+        /* either the real or imaginary part is a NaN,
+           and neither is infinite. Result should be NaN. */
+        return Py_NAN;
+    }
+    result = hypot(z.real, z.imag);
+    if (!Py_IS_FINITE(result))
+        errno = ERANGE;
+    else
+        errno = 0;
+    return result;
+}
+
+static PyObject *
+complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
+{
+    PyObject *op;
+
+    op = type->tp_alloc(type, 0);
+    if (op != NULL)
+        ((PyComplexObject *)op)->cval = cval;
+    return op;
+}
+
+PyObject *
+PyComplex_FromCComplex(Py_complex cval)
+{
+    register PyComplexObject *op;
+
+    /* Inline PyObject_New */
+    op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
+    if (op == NULL)
+        return PyErr_NoMemory();
+    PyObject_INIT(op, &PyComplex_Type);
+    op->cval = cval;
+    return (PyObject *) op;
+}
+
+static PyObject *
+complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
+{
+    Py_complex c;
+    c.real = real;
+    c.imag = imag;
+    return complex_subtype_from_c_complex(type, c);
+}
+
+PyObject *
+PyComplex_FromDoubles(double real, double imag)
+{
+    Py_complex c;
+    c.real = real;
+    c.imag = imag;
+    return PyComplex_FromCComplex(c);
+}
+
+double
+PyComplex_RealAsDouble(PyObject *op)
+{
+    if (PyComplex_Check(op)) {
+        return ((PyComplexObject *)op)->cval.real;
+    }
+    else {
+        return PyFloat_AsDouble(op);
+    }
+}
+
+double
+PyComplex_ImagAsDouble(PyObject *op)
+{
+    if (PyComplex_Check(op)) {
+        return ((PyComplexObject *)op)->cval.imag;
+    }
+    else {
+        return 0.0;
+    }
+}
+
+static PyObject *
+try_complex_special_method(PyObject *op) {
+    PyObject *f;
+    static PyObject *complexstr;
+
+    if (complexstr == NULL) {
+        complexstr = PyString_InternFromString("__complex__");
+        if (complexstr == NULL)
+            return NULL;
+    }
+    if (PyInstance_Check(op)) {
+        f = PyObject_GetAttr(op, complexstr);
+        if (f == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                PyErr_Clear();
+            else
+                return NULL;
+        }
+    }
+    else {
+        f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
+        if (f == NULL && PyErr_Occurred())
+            return NULL;
+    }
+    if (f != NULL) {
+        PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
+        Py_DECREF(f);
+        return res;
+    }
+    return NULL;
+}
+
+Py_complex
+PyComplex_AsCComplex(PyObject *op)
+{
+    Py_complex cv;
+    PyObject *newop = NULL;
+
+    assert(op);
+    /* If op is already of type PyComplex_Type, return its value */
+    if (PyComplex_Check(op)) {
+        return ((PyComplexObject *)op)->cval;
+    }
+    /* If not, use op's __complex__  method, if it exists */
+
+    /* return -1 on failure */
+    cv.real = -1.;
+    cv.imag = 0.;
+
+    newop = try_complex_special_method(op);
+
+    if (newop) {
+        if (!PyComplex_Check(newop)) {
+            PyErr_SetString(PyExc_TypeError,
+                "__complex__ should return a complex object");
+            Py_DECREF(newop);
+            return cv;
+        }
+        cv = ((PyComplexObject *)newop)->cval;
+        Py_DECREF(newop);
+        return cv;
+    }
+    else if (PyErr_Occurred()) {
+        return cv;
+    }
+    /* If neither of the above works, interpret op as a float giving the
+       real part of the result, and fill in the imaginary part as 0. */
+    else {
+        /* PyFloat_AsDouble will return -1 on failure */
+        cv.real = PyFloat_AsDouble(op);
+        return cv;
+    }
+}
+
+static void
+complex_dealloc(PyObject *op)
+{
+    op->ob_type->tp_free(op);
+}
+
+
+static PyObject *
+complex_format(PyComplexObject *v, int precision, char format_code)
+{
+    PyObject *result = NULL;
+    Py_ssize_t len;
+
+    /* If these are non-NULL, they'll need to be freed. */
+    char *pre = NULL;
+    char *im = NULL;
+    char *buf = NULL;
+
+    /* These do not need to be freed. re is either an alias
+       for pre or a pointer to a constant.  lead and tail
+       are pointers to constants. */
+    char *re = NULL;
+    char *lead = "";
+    char *tail = "";
+
+    if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
+        re = "";
+        im = PyOS_double_to_string(v->cval.imag, format_code,
+                                   precision, 0, NULL);
+        if (!im) {
+            PyErr_NoMemory();
+            goto done;
+        }
+    } else {
+        /* Format imaginary part with sign, real part without */
+        pre = PyOS_double_to_string(v->cval.real, format_code,
+                                    precision, 0, NULL);
+        if (!pre) {
+            PyErr_NoMemory();
+            goto done;
+        }
+        re = pre;
+
+        im = PyOS_double_to_string(v->cval.imag, format_code,
+                                   precision, Py_DTSF_SIGN, NULL);
+        if (!im) {
+            PyErr_NoMemory();
+            goto done;
+        }
+        lead = "(";
+        tail = ")";
+    }
+    /* Alloc the final buffer. Add one for the "j" in the format string,
+       and one for the trailing zero. */
+    len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
+    buf = PyMem_Malloc(len);
+    if (!buf) {
+        PyErr_NoMemory();
+        goto done;
+    }
+    PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail);
+    result = PyString_FromString(buf);
+  done:
+    PyMem_Free(im);
+    PyMem_Free(pre);
+    PyMem_Free(buf);
+
+    return result;
+}
+
+static int
+complex_print(PyComplexObject *v, FILE *fp, int flags)
+{
+    PyObject *formatv;
+    char *buf;
+    if (flags & Py_PRINT_RAW)
+        formatv = complex_format(v, PyFloat_STR_PRECISION, 'g');
+    else
+        formatv = complex_format(v, 0, 'r');
+    if (formatv == NULL)
+        return -1;
+    buf = PyString_AS_STRING(formatv);
+    Py_BEGIN_ALLOW_THREADS
+    fputs(buf, fp);
+    Py_END_ALLOW_THREADS
+    Py_DECREF(formatv);
+    return 0;
+}
+
+static PyObject *
+complex_repr(PyComplexObject *v)
+{
+    return complex_format(v, 0, 'r');
+}
+
+static PyObject *
+complex_str(PyComplexObject *v)
+{
+    return complex_format(v, PyFloat_STR_PRECISION, 'g');
+}
+
+static long
+complex_hash(PyComplexObject *v)
+{
+    long hashreal, hashimag, combined;
+    hashreal = _Py_HashDouble(v->cval.real);
+    if (hashreal == -1)
+        return -1;
+    hashimag = _Py_HashDouble(v->cval.imag);
+    if (hashimag == -1)
+        return -1;
+    /* Note:  if the imaginary part is 0, hashimag is 0 now,
+     * so the following returns hashreal unchanged.  This is
+     * important because numbers of different types that
+     * compare equal must have the same hash value, so that
+     * hash(x + 0*j) must equal hash(x).
+     */
+    combined = hashreal + 1000003 * hashimag;
+    if (combined == -1)
+        combined = -2;
+    return combined;
+}
+
+/* This macro may return! */
+#define TO_COMPLEX(obj, c) \
+    if (PyComplex_Check(obj)) \
+        c = ((PyComplexObject *)(obj))->cval; \
+    else if (to_complex(&(obj), &(c)) < 0) \
+        return (obj)
+
+static int
+to_complex(PyObject **pobj, Py_complex *pc)
+{
+    PyObject *obj = *pobj;
+
+    pc->real = pc->imag = 0.0;
+    if (PyInt_Check(obj)) {
+    pc->real = PyInt_AS_LONG(obj);
+    return 0;
+    }
+    if (PyLong_Check(obj)) {
+    pc->real = PyLong_AsDouble(obj);
+    if (pc->real == -1.0 && PyErr_Occurred()) {
+        *pobj = NULL;
+        return -1;
+    }
+    return 0;
+    }
+    if (PyFloat_Check(obj)) {
+    pc->real = PyFloat_AsDouble(obj);
+    return 0;
+    }
+    Py_INCREF(Py_NotImplemented);
+    *pobj = Py_NotImplemented;
+    return -1;
+}
+
+
+static PyObject *
+complex_add(PyObject *v, PyObject *w)
+{
+    Py_complex result;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    PyFPE_START_PROTECT("complex_add", return 0)
+    result = c_sum(a, b);
+    PyFPE_END_PROTECT(result)
+    return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_sub(PyObject *v, PyObject *w)
+{
+    Py_complex result;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);;
+    PyFPE_START_PROTECT("complex_sub", return 0)
+    result = c_diff(a, b);
+    PyFPE_END_PROTECT(result)
+    return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_mul(PyObject *v, PyObject *w)
+{
+    Py_complex result;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    PyFPE_START_PROTECT("complex_mul", return 0)
+    result = c_prod(a, b);
+    PyFPE_END_PROTECT(result)
+    return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_div(PyObject *v, PyObject *w)
+{
+    Py_complex quot;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    PyFPE_START_PROTECT("complex_div", return 0)
+    errno = 0;
+    quot = c_quot(a, b);
+    PyFPE_END_PROTECT(quot)
+    if (errno == EDOM) {
+        PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
+        return NULL;
+    }
+    return PyComplex_FromCComplex(quot);
+}
+
+static PyObject *
+complex_classic_div(PyObject *v, PyObject *w)
+{
+    Py_complex quot;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    if (Py_DivisionWarningFlag >= 2 &&
+        PyErr_Warn(PyExc_DeprecationWarning,
+                   "classic complex division") < 0)
+        return NULL;
+
+    PyFPE_START_PROTECT("complex_classic_div", return 0)
+    errno = 0;
+    quot = c_quot(a, b);
+    PyFPE_END_PROTECT(quot)
+    if (errno == EDOM) {
+        PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
+        return NULL;
+    }
+    return PyComplex_FromCComplex(quot);
+}
+
+static PyObject *
+complex_remainder(PyObject *v, PyObject *w)
+{
+    Py_complex div, mod;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    if (PyErr_Warn(PyExc_DeprecationWarning,
+                   "complex divmod(), // and % are deprecated") < 0)
+        return NULL;
+
+    errno = 0;
+    div = c_quot(a, b); /* The raw divisor value. */
+    if (errno == EDOM) {
+        PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
+        return NULL;
+    }
+    div.real = floor(div.real); /* Use the floor of the real part. */
+    div.imag = 0.0;
+    mod = c_diff(a, c_prod(b, div));
+
+    return PyComplex_FromCComplex(mod);
+}
+
+
+static PyObject *
+complex_divmod(PyObject *v, PyObject *w)
+{
+    Py_complex div, mod;
+    PyObject *d, *m, *z;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    if (PyErr_Warn(PyExc_DeprecationWarning,
+                   "complex divmod(), // and % are deprecated") < 0)
+        return NULL;
+
+    errno = 0;
+    div = c_quot(a, b); /* The raw divisor value. */
+    if (errno == EDOM) {
+        PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
+        return NULL;
+    }
+    div.real = floor(div.real); /* Use the floor of the real part. */
+    div.imag = 0.0;
+    mod = c_diff(a, c_prod(b, div));
+    d = PyComplex_FromCComplex(div);
+    m = PyComplex_FromCComplex(mod);
+    z = PyTuple_Pack(2, d, m);
+    Py_XDECREF(d);
+    Py_XDECREF(m);
+    return z;
+}
+
+static PyObject *
+complex_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+    Py_complex p;
+    Py_complex exponent;
+    long int_exponent;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    if (z!=Py_None) {
+        PyErr_SetString(PyExc_ValueError, "complex modulo");
+        return NULL;
+    }
+    PyFPE_START_PROTECT("complex_pow", return 0)
+    errno = 0;
+    exponent = b;
+    int_exponent = (long)exponent.real;
+    if (exponent.imag == 0. && exponent.real == int_exponent)
+        p = c_powi(a,int_exponent);
+    else
+        p = c_pow(a,exponent);
+
+    PyFPE_END_PROTECT(p)
+    Py_ADJUST_ERANGE2(p.real, p.imag);
+    if (errno == EDOM) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "0.0 to a negative or complex power");
+        return NULL;
+    }
+    else if (errno == ERANGE) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "complex exponentiation");
+        return NULL;
+    }
+    return PyComplex_FromCComplex(p);
+}
+
+static PyObject *
+complex_int_div(PyObject *v, PyObject *w)
+{
+    PyObject *t, *r;
+    Py_complex a, b;
+    TO_COMPLEX(v, a);
+    TO_COMPLEX(w, b);
+    if (PyErr_Warn(PyExc_DeprecationWarning,
+                   "complex divmod(), // and % are deprecated") < 0)
+        return NULL;
+
+    t = complex_divmod(v, w);
+    if (t != NULL) {
+        r = PyTuple_GET_ITEM(t, 0);
+        Py_INCREF(r);
+        Py_DECREF(t);
+        return r;
+    }
+    return NULL;
+}
+
+static PyObject *
+complex_neg(PyComplexObject *v)
+{
+    Py_complex neg;
+    neg.real = -v->cval.real;
+    neg.imag = -v->cval.imag;
+    return PyComplex_FromCComplex(neg);
+}
+
+static PyObject *
+complex_pos(PyComplexObject *v)
+{
+    if (PyComplex_CheckExact(v)) {
+        Py_INCREF(v);
+        return (PyObject *)v;
+    }
+    else
+        return PyComplex_FromCComplex(v->cval);
+}
+
+static PyObject *
+complex_abs(PyComplexObject *v)
+{
+    double result;
+
+    PyFPE_START_PROTECT("complex_abs", return 0)
+    result = c_abs(v->cval);
+    PyFPE_END_PROTECT(result)
+
+    if (errno == ERANGE) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "absolute value too large");
+        return NULL;
+    }
+    return PyFloat_FromDouble(result);
+}
+
+static int
+complex_nonzero(PyComplexObject *v)
+{
+    return v->cval.real != 0.0 || v->cval.imag != 0.0;
+}
+
+static int
+complex_coerce(PyObject **pv, PyObject **pw)
+{
+    Py_complex cval;
+    cval.imag = 0.;
+    if (PyInt_Check(*pw)) {
+        cval.real = (double)PyInt_AsLong(*pw);
+        *pw = PyComplex_FromCComplex(cval);
+        Py_INCREF(*pv);
+        return 0;
+    }
+    else if (PyLong_Check(*pw)) {
+        cval.real = PyLong_AsDouble(*pw);
+        if (cval.real == -1.0 && PyErr_Occurred())
+            return -1;
+        *pw = PyComplex_FromCComplex(cval);
+        Py_INCREF(*pv);
+        return 0;
+    }
+    else if (PyFloat_Check(*pw)) {
+        cval.real = PyFloat_AsDouble(*pw);
+        *pw = PyComplex_FromCComplex(cval);
+        Py_INCREF(*pv);
+        return 0;
+    }
+    else if (PyComplex_Check(*pw)) {
+        Py_INCREF(*pv);
+        Py_INCREF(*pw);
+        return 0;
+    }
+    return 1; /* Can't do it */
+}
+
+static PyObject *
+complex_richcompare(PyObject *v, PyObject *w, int op)
+{
+    PyObject *res;
+    Py_complex i;
+    int equal;
+
+    if (op != Py_EQ && op != Py_NE) {
+        /* for backwards compatibility, comparisons with non-numbers return
+         * NotImplemented.  Only comparisons with core numeric types raise
+         * TypeError.
+         */
+        if (PyInt_Check(w) || PyLong_Check(w) ||
+            PyFloat_Check(w) || PyComplex_Check(w)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "no ordering relation is defined "
+                            "for complex numbers");
+            return NULL;
+        }
+        goto Unimplemented;
+    }
+
+    assert(PyComplex_Check(v));
+    TO_COMPLEX(v, i);
+
+    if (PyInt_Check(w) || PyLong_Check(w)) {
+        /* Check for 0.0 imaginary part first to avoid the rich
+         * comparison when possible.
+         */
+        if (i.imag == 0.0) {
+            PyObject *j, *sub_res;
+            j = PyFloat_FromDouble(i.real);
+            if (j == NULL)
+                return NULL;
+
+            sub_res = PyObject_RichCompare(j, w, op);
+            Py_DECREF(j);
+            return sub_res;
+        }
+        else {
+            equal = 0;
+        }
+    }
+    else if (PyFloat_Check(w)) {
+        equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0);
+    }
+    else if (PyComplex_Check(w)) {
+        Py_complex j;
+
+        TO_COMPLEX(w, j);
+        equal = (i.real == j.real && i.imag == j.imag);
+    }
+    else {
+        goto Unimplemented;
+    }
+
+    if (equal == (op == Py_EQ))
+         res = Py_True;
+    else
+         res = Py_False;
+
+    Py_INCREF(res);
+    return res;
+
+  Unimplemented:
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+static PyObject *
+complex_int(PyObject *v)
+{
+    PyErr_SetString(PyExc_TypeError,
+               "can't convert complex to int");
+    return NULL;
+}
+
+static PyObject *
+complex_long(PyObject *v)
+{
+    PyErr_SetString(PyExc_TypeError,
+               "can't convert complex to long");
+    return NULL;
+}
+
+static PyObject *
+complex_float(PyObject *v)
+{
+    PyErr_SetString(PyExc_TypeError,
+               "can't convert complex to float");
+    return NULL;
+}
+
+static PyObject *
+complex_conjugate(PyObject *self)
+{
+    Py_complex c;
+    c = ((PyComplexObject *)self)->cval;
+    c.imag = -c.imag;
+    return PyComplex_FromCComplex(c);
+}
+
+PyDoc_STRVAR(complex_conjugate_doc,
+"complex.conjugate() -> complex\n"
+"\n"
+"Returns the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.");
+
+static PyObject *
+complex_getnewargs(PyComplexObject *v)
+{
+    Py_complex c = v->cval;
+    return Py_BuildValue("(dd)", c.real, c.imag);
+}
+
+PyDoc_STRVAR(complex__format__doc,
+"complex.__format__() -> str\n"
+"\n"
+"Converts to a string according to format_spec.");
+
+static PyObject *
+complex__format__(PyObject* self, PyObject* args)
+{
+    PyObject *format_spec;
+
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+    return NULL;
+    if (PyBytes_Check(format_spec))
+    return _PyComplex_FormatAdvanced(self,
+                                     PyBytes_AS_STRING(format_spec),
+                                     PyBytes_GET_SIZE(format_spec));
+    if (PyUnicode_Check(format_spec)) {
+    /* Convert format_spec to a str */
+    PyObject *result;
+    PyObject *str_spec = PyObject_Str(format_spec);
+
+    if (str_spec == NULL)
+        return NULL;
+
+    result = _PyComplex_FormatAdvanced(self,
+                                       PyBytes_AS_STRING(str_spec),
+                                       PyBytes_GET_SIZE(str_spec));
+
+    Py_DECREF(str_spec);
+    return result;
+    }
+    PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+    return NULL;
+}
+
+#if 0
+static PyObject *
+complex_is_finite(PyObject *self)
+{
+    Py_complex c;
+    c = ((PyComplexObject *)self)->cval;
+    return PyBool_FromLong((long)(Py_IS_FINITE(c.real) &&
+                                  Py_IS_FINITE(c.imag)));
+}
+
+PyDoc_STRVAR(complex_is_finite_doc,
+"complex.is_finite() -> bool\n"
+"\n"
+"Returns True if the real and the imaginary part is finite.");
+#endif
+
+static PyMethodDef complex_methods[] = {
+    {"conjugate",       (PyCFunction)complex_conjugate, METH_NOARGS,
+     complex_conjugate_doc},
+#if 0
+    {"is_finite",       (PyCFunction)complex_is_finite, METH_NOARGS,
+     complex_is_finite_doc},
+#endif
+    {"__getnewargs__",          (PyCFunction)complex_getnewargs,        METH_NOARGS},
+    {"__format__",          (PyCFunction)complex__format__,
+                                       METH_VARARGS, complex__format__doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyMemberDef complex_members[] = {
+    {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY,
+     "the real part of a complex number"},
+    {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY,
+     "the imaginary part of a complex number"},
+    {0},
+};
+
+static PyObject *
+complex_subtype_from_string(PyTypeObject *type, PyObject *v)
+{
+    const char *s, *start;
+    char *end;
+    double x=0.0, y=0.0, z;
+    int got_bracket=0;
+#ifdef Py_USING_UNICODE
+    char *s_buffer = NULL;
+#endif
+    Py_ssize_t len;
+
+    if (PyString_Check(v)) {
+        s = PyString_AS_STRING(v);
+        len = PyString_GET_SIZE(v);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(v)) {
+        s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+        if (s_buffer == NULL)
+            return PyErr_NoMemory();
+        if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
+                                    PyUnicode_GET_SIZE(v),
+                                    s_buffer,
+                                    NULL))
+            goto error;
+        s = s_buffer;
+        len = strlen(s);
+    }
+#endif
+    else if (PyObject_AsCharBuffer(v, &s, &len)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "complex() arg is not a string");
+        return NULL;
+    }
+
+    /* position on first nonblank */
+    start = s;
+    while (Py_ISSPACE(*s))
+        s++;
+    if (*s == '(') {
+        /* Skip over possible bracket from repr(). */
+        got_bracket = 1;
+        s++;
+        while (Py_ISSPACE(*s))
+            s++;
+    }
+
+    /* a valid complex string usually takes one of the three forms:
+
+         <float>                  - real part only
+         <float>j                 - imaginary part only
+         <float><signed-float>j   - real and imaginary parts
+
+       where <float> represents any numeric string that's accepted by the
+       float constructor (including 'nan', 'inf', 'infinity', etc.), and
+       <signed-float> is any string of the form <float> whose first
+       character is '+' or '-'.
+
+       For backwards compatibility, the extra forms
+
+         <float><sign>j
+         <sign>j
+         j
+
+       are also accepted, though support for these forms may be removed from
+       a future version of Python.
+    */
+
+    /* first look for forms starting with <float> */
+    z = PyOS_string_to_double(s, &end, NULL);
+    if (z == -1.0 && PyErr_Occurred()) {
+        if (PyErr_ExceptionMatches(PyExc_ValueError))
+            PyErr_Clear();
+        else
+            goto error;
+    }
+    if (end != s) {
+        /* all 4 forms starting with <float> land here */
+        s = end;
+        if (*s == '+' || *s == '-') {
+            /* <float><signed-float>j | <float><sign>j */
+            x = z;
+            y = PyOS_string_to_double(s, &end, NULL);
+            if (y == -1.0 && PyErr_Occurred()) {
+                if (PyErr_ExceptionMatches(PyExc_ValueError))
+                    PyErr_Clear();
+                else
+                    goto error;
+            }
+            if (end != s)
+                /* <float><signed-float>j */
+                s = end;
+            else {
+                /* <float><sign>j */
+                y = *s == '+' ? 1.0 : -1.0;
+                s++;
+            }
+            if (!(*s == 'j' || *s == 'J'))
+                goto parse_error;
+            s++;
+        }
+        else if (*s == 'j' || *s == 'J') {
+            /* <float>j */
+            s++;
+            y = z;
+        }
+        else
+            /* <float> */
+            x = z;
+    }
+    else {
+        /* not starting with <float>; must be <sign>j or j */
+        if (*s == '+' || *s == '-') {
+            /* <sign>j */
+            y = *s == '+' ? 1.0 : -1.0;
+            s++;
+        }
+        else
+            /* j */
+            y = 1.0;
+        if (!(*s == 'j' || *s == 'J'))
+            goto parse_error;
+        s++;
+    }
+
+    /* trailing whitespace and closing bracket */
+    while (Py_ISSPACE(*s))
+        s++;
+    if (got_bracket) {
+        /* if there was an opening parenthesis, then the corresponding
+           closing parenthesis should be right here */
+        if (*s != ')')
+            goto parse_error;
+        s++;
+        while (Py_ISSPACE(*s))
+            s++;
+    }
+
+    /* we should now be at the end of the string */
+    if (s-start != len)
+        goto parse_error;
+
+
+#ifdef Py_USING_UNICODE
+    if (s_buffer)
+        PyMem_FREE(s_buffer);
+#endif
+    return complex_subtype_from_doubles(type, x, y);
+
+  parse_error:
+    PyErr_SetString(PyExc_ValueError,
+                    "complex() arg is a malformed string");
+  error:
+#ifdef Py_USING_UNICODE
+    if (s_buffer)
+        PyMem_FREE(s_buffer);
+#endif
+    return NULL;
+}
+
+static PyObject *
+complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *r, *i, *tmp;
+    PyNumberMethods *nbr, *nbi = NULL;
+    Py_complex cr, ci;
+    int own_r = 0;
+    int cr_is_complex = 0;
+    int ci_is_complex = 0;
+    static char *kwlist[] = {"real", "imag", 0};
+
+    r = Py_False;
+    i = NULL;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
+                                     &r, &i))
+        return NULL;
+
+    /* Special-case for a single argument when type(arg) is complex. */
+    if (PyComplex_CheckExact(r) && i == NULL &&
+        type == &PyComplex_Type) {
+        /* Note that we can't know whether it's safe to return
+           a complex *subclass* instance as-is, hence the restriction
+           to exact complexes here.  If either the input or the
+           output is a complex subclass, it will be handled below
+           as a non-orthogonal vector.  */
+        Py_INCREF(r);
+        return r;
+    }
+    if (PyString_Check(r) || PyUnicode_Check(r)) {
+        if (i != NULL) {
+            PyErr_SetString(PyExc_TypeError,
+                            "complex() can't take second arg"
+                            " if first is a string");
+            return NULL;
+        }
+        return complex_subtype_from_string(type, r);
+    }
+    if (i != NULL && (PyString_Check(i) || PyUnicode_Check(i))) {
+        PyErr_SetString(PyExc_TypeError,
+                        "complex() second arg can't be a string");
+        return NULL;
+    }
+
+    tmp = try_complex_special_method(r);
+    if (tmp) {
+        r = tmp;
+        own_r = 1;
+    }
+    else if (PyErr_Occurred()) {
+        return NULL;
+    }
+
+    nbr = r->ob_type->tp_as_number;
+    if (i != NULL)
+        nbi = i->ob_type->tp_as_number;
+    if (nbr == NULL || nbr->nb_float == NULL ||
+        ((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) {
+        PyErr_SetString(PyExc_TypeError,
+                   "complex() argument must be a string or a number");
+        if (own_r) {
+            Py_DECREF(r);
+        }
+        return NULL;
+    }
+
+    /* If we get this far, then the "real" and "imag" parts should
+       both be treated as numbers, and the constructor should return a
+       complex number equal to (real + imag*1j).
+
+       Note that we do NOT assume the input to already be in canonical
+       form; the "real" and "imag" parts might themselves be complex
+       numbers, which slightly complicates the code below. */
+    if (PyComplex_Check(r)) {
+        /* Note that if r is of a complex subtype, we're only
+           retaining its real & imag parts here, and the return
+           value is (properly) of the builtin complex type. */
+        cr = ((PyComplexObject*)r)->cval;
+        cr_is_complex = 1;
+        if (own_r) {
+            Py_DECREF(r);
+        }
+    }
+    else {
+        /* The "real" part really is entirely real, and contributes
+           nothing in the imaginary direction.
+           Just treat it as a double. */
+        tmp = PyNumber_Float(r);
+        if (own_r) {
+            /* r was a newly created complex number, rather
+               than the original "real" argument. */
+            Py_DECREF(r);
+        }
+        if (tmp == NULL)
+            return NULL;
+        if (!PyFloat_Check(tmp)) {
+            PyErr_SetString(PyExc_TypeError,
+                            "float(r) didn't return a float");
+            Py_DECREF(tmp);
+            return NULL;
+        }
+        cr.real = PyFloat_AsDouble(tmp);
+        cr.imag = 0.0; /* Shut up compiler warning */
+        Py_DECREF(tmp);
+    }
+    if (i == NULL) {
+        ci.real = 0.0;
+    }
+    else if (PyComplex_Check(i)) {
+        ci = ((PyComplexObject*)i)->cval;
+        ci_is_complex = 1;
+    } else {
+        /* The "imag" part really is entirely imaginary, and
+           contributes nothing in the real direction.
+           Just treat it as a double. */
+        tmp = (*nbi->nb_float)(i);
+        if (tmp == NULL)
+            return NULL;
+        ci.real = PyFloat_AsDouble(tmp);
+        Py_DECREF(tmp);
+    }
+    /*  If the input was in canonical form, then the "real" and "imag"
+        parts are real numbers, so that ci.imag and cr.imag are zero.
+        We need this correction in case they were not real numbers. */
+
+    if (ci_is_complex) {
+        cr.real -= ci.imag;
+    }
+    if (cr_is_complex) {
+        ci.real += cr.imag;
+    }
+    return complex_subtype_from_doubles(type, cr.real, ci.real);
+}
+
+PyDoc_STRVAR(complex_doc,
+"complex(real[, imag]) -> complex number\n"
+"\n"
+"Create a complex number from a real part and an optional imaginary part.\n"
+"This is equivalent to (real + imag*1j) where imag defaults to 0.");
+
+static PyNumberMethods complex_as_number = {
+    (binaryfunc)complex_add,                    /* nb_add */
+    (binaryfunc)complex_sub,                    /* nb_subtract */
+    (binaryfunc)complex_mul,                    /* nb_multiply */
+    (binaryfunc)complex_classic_div,            /* nb_divide */
+    (binaryfunc)complex_remainder,              /* nb_remainder */
+    (binaryfunc)complex_divmod,                 /* nb_divmod */
+    (ternaryfunc)complex_pow,                   /* nb_power */
+    (unaryfunc)complex_neg,                     /* nb_negative */
+    (unaryfunc)complex_pos,                     /* nb_positive */
+    (unaryfunc)complex_abs,                     /* nb_absolute */
+    (inquiry)complex_nonzero,                   /* nb_nonzero */
+    0,                                          /* nb_invert */
+    0,                                          /* nb_lshift */
+    0,                                          /* nb_rshift */
+    0,                                          /* nb_and */
+    0,                                          /* nb_xor */
+    0,                                          /* nb_or */
+    complex_coerce,                             /* nb_coerce */
+    complex_int,                                /* nb_int */
+    complex_long,                               /* nb_long */
+    complex_float,                              /* nb_float */
+    0,                                          /* nb_oct */
+    0,                                          /* nb_hex */
+    0,                                          /* nb_inplace_add */
+    0,                                          /* nb_inplace_subtract */
+    0,                                          /* nb_inplace_multiply*/
+    0,                                          /* nb_inplace_divide */
+    0,                                          /* nb_inplace_remainder */
+    0,                                          /* nb_inplace_power */
+    0,                                          /* nb_inplace_lshift */
+    0,                                          /* nb_inplace_rshift */
+    0,                                          /* nb_inplace_and */
+    0,                                          /* nb_inplace_xor */
+    0,                                          /* nb_inplace_or */
+    (binaryfunc)complex_int_div,                /* nb_floor_divide */
+    (binaryfunc)complex_div,                    /* nb_true_divide */
+    0,                                          /* nb_inplace_floor_divide */
+    0,                                          /* nb_inplace_true_divide */
+};
+
+PyTypeObject PyComplex_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "complex",
+    sizeof(PyComplexObject),
+    0,
+    complex_dealloc,                            /* tp_dealloc */
+    (printfunc)complex_print,                   /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)complex_repr,                     /* tp_repr */
+    &complex_as_number,                         /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)complex_hash,                     /* tp_hash */
+    0,                                          /* tp_call */
+    (reprfunc)complex_str,                      /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    complex_doc,                                /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    complex_richcompare,                        /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    complex_methods,                            /* tp_methods */
+    complex_members,                            /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    complex_new,                                /* tp_new */
+    PyObject_Del,                               /* tp_free */
+};
+
+#endif
diff --git a/Python-2.7.5/Objects/descrobject.c b/Python-2.7.5/Objects/descrobject.c
new file mode 100644
index 0000000..7bf1859
--- /dev/null
+++ b/Python-2.7.5/Objects/descrobject.c
@@ -0,0 +1,1436 @@
+/* Descriptors -- a new, flexible way to describe attributes */
+
+#include "Python.h"
+#include "structmember.h" /* Why is this not included in Python.h? */
+
+static void
+descr_dealloc(PyDescrObject *descr)
+{
+    _PyObject_GC_UNTRACK(descr);
+    Py_XDECREF(descr->d_type);
+    Py_XDECREF(descr->d_name);
+    PyObject_GC_Del(descr);
+}
+
+static char *
+descr_name(PyDescrObject *descr)
+{
+    if (descr->d_name != NULL && PyString_Check(descr->d_name))
+        return PyString_AS_STRING(descr->d_name);
+    else
+        return "?";
+}
+
+static PyObject *
+descr_repr(PyDescrObject *descr, char *format)
+{
+    return PyString_FromFormat(format, descr_name(descr),
+                               descr->d_type->tp_name);
+}
+
+static PyObject *
+method_repr(PyMethodDescrObject *descr)
+{
+    return descr_repr((PyDescrObject *)descr,
+                      "<method '%s' of '%s' objects>");
+}
+
+static PyObject *
+member_repr(PyMemberDescrObject *descr)
+{
+    return descr_repr((PyDescrObject *)descr,
+                      "<member '%s' of '%s' objects>");
+}
+
+static PyObject *
+getset_repr(PyGetSetDescrObject *descr)
+{
+    return descr_repr((PyDescrObject *)descr,
+                      "<attribute '%s' of '%s' objects>");
+}
+
+static PyObject *
+wrapperdescr_repr(PyWrapperDescrObject *descr)
+{
+    return descr_repr((PyDescrObject *)descr,
+                      "<slot wrapper '%s' of '%s' objects>");
+}
+
+static int
+descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
+{
+    if (obj == NULL) {
+        Py_INCREF(descr);
+        *pres = (PyObject *)descr;
+        return 1;
+    }
+    if (!PyObject_TypeCheck(obj, descr->d_type)) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%s' for '%s' objects "
+                     "doesn't apply to '%s' object",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name,
+                     obj->ob_type->tp_name);
+        *pres = NULL;
+        return 1;
+    }
+    return 0;
+}
+
+static PyObject *
+classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
+{
+    /* Ensure a valid type.  Class methods ignore obj. */
+    if (type == NULL) {
+        if (obj != NULL)
+            type = (PyObject *)obj->ob_type;
+        else {
+            /* Wot - no type?! */
+            PyErr_Format(PyExc_TypeError,
+                         "descriptor '%s' for type '%s' "
+                         "needs either an object or a type",
+                         descr_name((PyDescrObject *)descr),
+                         descr->d_type->tp_name);
+            return NULL;
+        }
+    }
+    if (!PyType_Check(type)) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%s' for type '%s' "
+                     "needs a type, not a '%s' as arg 2",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name,
+                     type->ob_type->tp_name);
+        return NULL;
+    }
+    if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%s' for type '%s' "
+                     "doesn't apply to type '%s'",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name,
+                     ((PyTypeObject *)type)->tp_name);
+        return NULL;
+    }
+    return PyCFunction_New(descr->d_method, type);
+}
+
+static PyObject *
+method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
+{
+    PyObject *res;
+
+    if (descr_check((PyDescrObject *)descr, obj, &res))
+        return res;
+    return PyCFunction_New(descr->d_method, obj);
+}
+
+static PyObject *
+member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
+{
+    PyObject *res;
+
+    if (descr_check((PyDescrObject *)descr, obj, &res))
+        return res;
+    return PyMember_GetOne((char *)obj, descr->d_member);
+}
+
+static PyObject *
+getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
+{
+    PyObject *res;
+
+    if (descr_check((PyDescrObject *)descr, obj, &res))
+        return res;
+    if (descr->d_getset->get != NULL)
+        return descr->d_getset->get(obj, descr->d_getset->closure);
+    PyErr_Format(PyExc_AttributeError,
+                 "attribute '%.300s' of '%.100s' objects is not readable",
+                 descr_name((PyDescrObject *)descr),
+                 descr->d_type->tp_name);
+    return NULL;
+}
+
+static PyObject *
+wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
+{
+    PyObject *res;
+
+    if (descr_check((PyDescrObject *)descr, obj, &res))
+        return res;
+    return PyWrapper_New((PyObject *)descr, obj);
+}
+
+static int
+descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
+               int *pres)
+{
+    assert(obj != NULL);
+    if (!PyObject_TypeCheck(obj, descr->d_type)) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%.200s' for '%.100s' objects "
+                     "doesn't apply to '%.100s' object",
+                     descr_name(descr),
+                     descr->d_type->tp_name,
+                     obj->ob_type->tp_name);
+        *pres = -1;
+        return 1;
+    }
+    return 0;
+}
+
+static int
+member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
+{
+    int res;
+
+    if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
+        return res;
+    return PyMember_SetOne((char *)obj, descr->d_member, value);
+}
+
+static int
+getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
+{
+    int res;
+
+    if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
+        return res;
+    if (descr->d_getset->set != NULL)
+        return descr->d_getset->set(obj, value,
+                                    descr->d_getset->closure);
+    PyErr_Format(PyExc_AttributeError,
+                 "attribute '%.300s' of '%.100s' objects is not writable",
+                 descr_name((PyDescrObject *)descr),
+                 descr->d_type->tp_name);
+    return -1;
+}
+
+static PyObject *
+methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
+{
+    Py_ssize_t argc;
+    PyObject *self, *func, *result;
+
+    /* Make sure that the first argument is acceptable as 'self' */
+    assert(PyTuple_Check(args));
+    argc = PyTuple_GET_SIZE(args);
+    if (argc < 1) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%.300s' of '%.100s' "
+                     "object needs an argument",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name);
+        return NULL;
+    }
+    self = PyTuple_GET_ITEM(args, 0);
+    if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+                                  (PyObject *)(descr->d_type))) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%.200s' "
+                     "requires a '%.100s' object "
+                     "but received a '%.100s'",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name,
+                     self->ob_type->tp_name);
+        return NULL;
+    }
+
+    func = PyCFunction_New(descr->d_method, self);
+    if (func == NULL)
+        return NULL;
+    args = PyTuple_GetSlice(args, 1, argc);
+    if (args == NULL) {
+        Py_DECREF(func);
+        return NULL;
+    }
+    result = PyEval_CallObjectWithKeywords(func, args, kwds);
+    Py_DECREF(args);
+    Py_DECREF(func);
+    return result;
+}
+
+static PyObject *
+classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
+                      PyObject *kwds)
+{
+    Py_ssize_t argc;
+    PyObject *self, *func, *result;
+
+    /* Make sure that the first argument is acceptable as 'self' */
+    assert(PyTuple_Check(args));
+    argc = PyTuple_GET_SIZE(args);
+    if (argc < 1) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%s' of '%.100s' "
+                     "object needs an argument",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name);
+        return NULL;
+    }
+    self = PyTuple_GET_ITEM(args, 0);
+    if (!PyType_Check(self)) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%s' requires a type "
+                     "but received a '%.100s'",
+                     descr_name((PyDescrObject *)descr),
+                     self->ob_type->tp_name);
+        return NULL;
+    }
+    if (!PyType_IsSubtype((PyTypeObject *)self, descr->d_type)) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%s' "
+                     "requires a subtype of '%.100s' "
+                     "but received '%.100s",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name,
+                     self->ob_type->tp_name);
+        return NULL;
+    }
+
+    func = PyCFunction_New(descr->d_method, self);
+    if (func == NULL)
+        return NULL;
+    args = PyTuple_GetSlice(args, 1, argc);
+    if (args == NULL) {
+        Py_DECREF(func);
+        return NULL;
+    }
+    result = PyEval_CallObjectWithKeywords(func, args, kwds);
+    Py_DECREF(func);
+    Py_DECREF(args);
+    return result;
+}
+
+static PyObject *
+wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
+{
+    Py_ssize_t argc;
+    PyObject *self, *func, *result;
+
+    /* Make sure that the first argument is acceptable as 'self' */
+    assert(PyTuple_Check(args));
+    argc = PyTuple_GET_SIZE(args);
+    if (argc < 1) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%.300s' of '%.100s' "
+                     "object needs an argument",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name);
+        return NULL;
+    }
+    self = PyTuple_GET_ITEM(args, 0);
+    if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+                                  (PyObject *)(descr->d_type))) {
+        PyErr_Format(PyExc_TypeError,
+                     "descriptor '%.200s' "
+                     "requires a '%.100s' object "
+                     "but received a '%.100s'",
+                     descr_name((PyDescrObject *)descr),
+                     descr->d_type->tp_name,
+                     self->ob_type->tp_name);
+        return NULL;
+    }
+
+    func = PyWrapper_New((PyObject *)descr, self);
+    if (func == NULL)
+        return NULL;
+    args = PyTuple_GetSlice(args, 1, argc);
+    if (args == NULL) {
+        Py_DECREF(func);
+        return NULL;
+    }
+    result = PyEval_CallObjectWithKeywords(func, args, kwds);
+    Py_DECREF(args);
+    Py_DECREF(func);
+    return result;
+}
+
+static PyObject *
+method_get_doc(PyMethodDescrObject *descr, void *closure)
+{
+    if (descr->d_method->ml_doc == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyString_FromString(descr->d_method->ml_doc);
+}
+
+static PyMemberDef descr_members[] = {
+    {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
+    {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
+    {0}
+};
+
+static PyGetSetDef method_getset[] = {
+    {"__doc__", (getter)method_get_doc},
+    {0}
+};
+
+static PyObject *
+member_get_doc(PyMemberDescrObject *descr, void *closure)
+{
+    if (descr->d_member->doc == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyString_FromString(descr->d_member->doc);
+}
+
+static PyGetSetDef member_getset[] = {
+    {"__doc__", (getter)member_get_doc},
+    {0}
+};
+
+static PyObject *
+getset_get_doc(PyGetSetDescrObject *descr, void *closure)
+{
+    if (descr->d_getset->doc == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyString_FromString(descr->d_getset->doc);
+}
+
+static PyGetSetDef getset_getset[] = {
+    {"__doc__", (getter)getset_get_doc},
+    {0}
+};
+
+static PyObject *
+wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
+{
+    if (descr->d_base->doc == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyString_FromString(descr->d_base->doc);
+}
+
+static PyGetSetDef wrapperdescr_getset[] = {
+    {"__doc__", (getter)wrapperdescr_get_doc},
+    {0}
+};
+
+static int
+descr_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    PyDescrObject *descr = (PyDescrObject *)self;
+    Py_VISIT(descr->d_type);
+    return 0;
+}
+
+static PyTypeObject PyMethodDescr_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "method_descriptor",
+    sizeof(PyMethodDescrObject),
+    0,
+    (destructor)descr_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)method_repr,                      /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    (ternaryfunc)methoddescr_call,              /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    descr_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    descr_members,                              /* tp_members */
+    method_getset,                              /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    (descrgetfunc)method_get,                   /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+};
+
+/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
+static PyTypeObject PyClassMethodDescr_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "classmethod_descriptor",
+    sizeof(PyMethodDescrObject),
+    0,
+    (destructor)descr_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)method_repr,                      /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    (ternaryfunc)classmethoddescr_call,         /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    descr_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    descr_members,                              /* tp_members */
+    method_getset,                              /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    (descrgetfunc)classmethod_get,              /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+};
+
+PyTypeObject PyMemberDescr_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "member_descriptor",
+    sizeof(PyMemberDescrObject),
+    0,
+    (destructor)descr_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)member_repr,                      /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    descr_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    descr_members,                              /* tp_members */
+    member_getset,                              /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    (descrgetfunc)member_get,                   /* tp_descr_get */
+    (descrsetfunc)member_set,                   /* tp_descr_set */
+};
+
+PyTypeObject PyGetSetDescr_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "getset_descriptor",
+    sizeof(PyGetSetDescrObject),
+    0,
+    (destructor)descr_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)getset_repr,                      /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    descr_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    descr_members,                              /* tp_members */
+    getset_getset,                              /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    (descrgetfunc)getset_get,                   /* tp_descr_get */
+    (descrsetfunc)getset_set,                   /* tp_descr_set */
+};
+
+PyTypeObject PyWrapperDescr_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "wrapper_descriptor",
+    sizeof(PyWrapperDescrObject),
+    0,
+    (destructor)descr_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)wrapperdescr_repr,                /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    (ternaryfunc)wrapperdescr_call,             /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    descr_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    descr_members,                              /* tp_members */
+    wrapperdescr_getset,                        /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    (descrgetfunc)wrapperdescr_get,             /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+};
+
+static PyDescrObject *
+descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
+{
+    PyDescrObject *descr;
+
+    descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
+    if (descr != NULL) {
+        Py_XINCREF(type);
+        descr->d_type = type;
+        descr->d_name = PyString_InternFromString(name);
+        if (descr->d_name == NULL) {
+            Py_DECREF(descr);
+            descr = NULL;
+        }
+    }
+    return descr;
+}
+
+PyObject *
+PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
+{
+    PyMethodDescrObject *descr;
+
+    descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
+                                             type, method->ml_name);
+    if (descr != NULL)
+        descr->d_method = method;
+    return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
+{
+    PyMethodDescrObject *descr;
+
+    descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
+                                             type, method->ml_name);
+    if (descr != NULL)
+        descr->d_method = method;
+    return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
+{
+    PyMemberDescrObject *descr;
+
+    descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
+                                             type, member->name);
+    if (descr != NULL)
+        descr->d_member = member;
+    return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
+{
+    PyGetSetDescrObject *descr;
+
+    descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
+                                             type, getset->name);
+    if (descr != NULL)
+        descr->d_getset = getset;
+    return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
+{
+    PyWrapperDescrObject *descr;
+
+    descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
+                                             type, base->name);
+    if (descr != NULL) {
+        descr->d_base = base;
+        descr->d_wrapped = wrapped;
+    }
+    return (PyObject *)descr;
+}
+
+
+/* --- Readonly proxy for dictionaries (actually any mapping) --- */
+
+/* This has no reason to be in this file except that adding new files is a
+   bit of a pain */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *dict;
+} proxyobject;
+
+static Py_ssize_t
+proxy_len(proxyobject *pp)
+{
+    return PyObject_Size(pp->dict);
+}
+
+static PyObject *
+proxy_getitem(proxyobject *pp, PyObject *key)
+{
+    return PyObject_GetItem(pp->dict, key);
+}
+
+static PyMappingMethods proxy_as_mapping = {
+    (lenfunc)proxy_len,                         /* mp_length */
+    (binaryfunc)proxy_getitem,                  /* mp_subscript */
+    0,                                          /* mp_ass_subscript */
+};
+
+static int
+proxy_contains(proxyobject *pp, PyObject *key)
+{
+    return PyDict_Contains(pp->dict, key);
+}
+
+static PySequenceMethods proxy_as_sequence = {
+    0,                                          /* sq_length */
+    0,                                          /* sq_concat */
+    0,                                          /* sq_repeat */
+    0,                                          /* sq_item */
+    0,                                          /* sq_slice */
+    0,                                          /* sq_ass_item */
+    0,                                          /* sq_ass_slice */
+    (objobjproc)proxy_contains,                 /* sq_contains */
+    0,                                          /* sq_inplace_concat */
+    0,                                          /* sq_inplace_repeat */
+};
+
+static PyObject *
+proxy_has_key(proxyobject *pp, PyObject *key)
+{
+    int res = PyDict_Contains(pp->dict, key);
+    if (res < 0)
+        return NULL;
+    return PyBool_FromLong(res);
+}
+
+static PyObject *
+proxy_get(proxyobject *pp, PyObject *args)
+{
+    PyObject *key, *def = Py_None;
+
+    if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
+        return NULL;
+    return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
+}
+
+static PyObject *
+proxy_keys(proxyobject *pp)
+{
+    return PyMapping_Keys(pp->dict);
+}
+
+static PyObject *
+proxy_values(proxyobject *pp)
+{
+    return PyMapping_Values(pp->dict);
+}
+
+static PyObject *
+proxy_items(proxyobject *pp)
+{
+    return PyMapping_Items(pp->dict);
+}
+
+static PyObject *
+proxy_iterkeys(proxyobject *pp)
+{
+    return PyObject_CallMethod(pp->dict, "iterkeys", NULL);
+}
+
+static PyObject *
+proxy_itervalues(proxyobject *pp)
+{
+    return PyObject_CallMethod(pp->dict, "itervalues", NULL);
+}
+
+static PyObject *
+proxy_iteritems(proxyobject *pp)
+{
+    return PyObject_CallMethod(pp->dict, "iteritems", NULL);
+}
+static PyObject *
+proxy_copy(proxyobject *pp)
+{
+    return PyObject_CallMethod(pp->dict, "copy", NULL);
+}
+
+static PyMethodDef proxy_methods[] = {
+    {"has_key",   (PyCFunction)proxy_has_key,    METH_O,
+     PyDoc_STR("D.has_key(k) -> True if D has a key k, else False")},
+    {"get",       (PyCFunction)proxy_get,        METH_VARARGS,
+     PyDoc_STR("D.get(k[,d]) -> D[k] if D.has_key(k), else d."
+                                    "  d defaults to None.")},
+    {"keys",      (PyCFunction)proxy_keys,       METH_NOARGS,
+     PyDoc_STR("D.keys() -> list of D's keys")},
+    {"values",    (PyCFunction)proxy_values,     METH_NOARGS,
+     PyDoc_STR("D.values() -> list of D's values")},
+    {"items",     (PyCFunction)proxy_items,      METH_NOARGS,
+     PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
+    {"iterkeys",  (PyCFunction)proxy_iterkeys,   METH_NOARGS,
+     PyDoc_STR("D.iterkeys() -> an iterator over the keys of D")},
+    {"itervalues",(PyCFunction)proxy_itervalues, METH_NOARGS,
+     PyDoc_STR("D.itervalues() -> an iterator over the values of D")},
+    {"iteritems", (PyCFunction)proxy_iteritems,  METH_NOARGS,
+     PyDoc_STR("D.iteritems() ->"
+               " an iterator over the (key, value) items of D")},
+    {"copy",      (PyCFunction)proxy_copy,       METH_NOARGS,
+     PyDoc_STR("D.copy() -> a shallow copy of D")},
+    {0}
+};
+
+static void
+proxy_dealloc(proxyobject *pp)
+{
+    _PyObject_GC_UNTRACK(pp);
+    Py_DECREF(pp->dict);
+    PyObject_GC_Del(pp);
+}
+
+static PyObject *
+proxy_getiter(proxyobject *pp)
+{
+    return PyObject_GetIter(pp->dict);
+}
+
+static PyObject *
+proxy_str(proxyobject *pp)
+{
+    return PyObject_Str(pp->dict);
+}
+
+static PyObject *
+proxy_repr(proxyobject *pp)
+{
+    PyObject *dictrepr;
+    PyObject *result;
+
+    dictrepr = PyObject_Repr(pp->dict);
+    if (dictrepr == NULL)
+        return NULL;
+    result = PyString_FromFormat("dict_proxy(%s)", PyString_AS_STRING(dictrepr));
+    Py_DECREF(dictrepr);
+    return result;
+}
+
+static int
+proxy_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    proxyobject *pp = (proxyobject *)self;
+    Py_VISIT(pp->dict);
+    return 0;
+}
+
+static int
+proxy_compare(proxyobject *v, PyObject *w)
+{
+    return PyObject_Compare(v->dict, w);
+}
+
+static PyObject *
+proxy_richcompare(proxyobject *v, PyObject *w, int op)
+{
+    return PyObject_RichCompare(v->dict, w, op);
+}
+
+PyTypeObject PyDictProxy_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dictproxy",                                /* tp_name */
+    sizeof(proxyobject),                        /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)proxy_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)proxy_compare,                     /* tp_compare */
+    (reprfunc)proxy_repr,                       /* tp_repr */
+    0,                                          /* tp_as_number */
+    &proxy_as_sequence,                         /* tp_as_sequence */
+    &proxy_as_mapping,                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    (reprfunc)proxy_str,                        /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    proxy_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    (richcmpfunc)proxy_richcompare,             /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    (getiterfunc)proxy_getiter,                 /* tp_iter */
+    0,                                          /* tp_iternext */
+    proxy_methods,                              /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+};
+
+PyObject *
+PyDictProxy_New(PyObject *dict)
+{
+    proxyobject *pp;
+
+    pp = PyObject_GC_New(proxyobject, &PyDictProxy_Type);
+    if (pp != NULL) {
+        Py_INCREF(dict);
+        pp->dict = dict;
+        _PyObject_GC_TRACK(pp);
+    }
+    return (PyObject *)pp;
+}
+
+
+/* --- Wrapper object for "slot" methods --- */
+
+/* This has no reason to be in this file except that adding new files is a
+   bit of a pain */
+
+typedef struct {
+    PyObject_HEAD
+    PyWrapperDescrObject *descr;
+    PyObject *self;
+} wrapperobject;
+
+static void
+wrapper_dealloc(wrapperobject *wp)
+{
+    PyObject_GC_UnTrack(wp);
+    Py_TRASHCAN_SAFE_BEGIN(wp)
+    Py_XDECREF(wp->descr);
+    Py_XDECREF(wp->self);
+    PyObject_GC_Del(wp);
+    Py_TRASHCAN_SAFE_END(wp)
+}
+
+static int
+wrapper_compare(wrapperobject *a, wrapperobject *b)
+{
+    if (a->descr == b->descr)
+        return PyObject_Compare(a->self, b->self);
+    else
+        return (a->descr < b->descr) ? -1 : 1;
+}
+
+static long
+wrapper_hash(wrapperobject *wp)
+{
+    int x, y;
+    x = _Py_HashPointer(wp->descr);
+    if (x == -1)
+        return -1;
+    y = PyObject_Hash(wp->self);
+    if (y == -1)
+        return -1;
+    x = x ^ y;
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+static PyObject *
+wrapper_repr(wrapperobject *wp)
+{
+    return PyString_FromFormat("<method-wrapper '%s' of %s object at %p>",
+                               wp->descr->d_base->name,
+                               wp->self->ob_type->tp_name,
+                               wp->self);
+}
+
+static PyMemberDef wrapper_members[] = {
+    {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
+    {0}
+};
+
+static PyObject *
+wrapper_objclass(wrapperobject *wp)
+{
+    PyObject *c = (PyObject *)wp->descr->d_type;
+
+    Py_INCREF(c);
+    return c;
+}
+
+static PyObject *
+wrapper_name(wrapperobject *wp)
+{
+    char *s = wp->descr->d_base->name;
+
+    return PyString_FromString(s);
+}
+
+static PyObject *
+wrapper_doc(wrapperobject *wp)
+{
+    char *s = wp->descr->d_base->doc;
+
+    if (s == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    else {
+        return PyString_FromString(s);
+    }
+}
+
+static PyGetSetDef wrapper_getsets[] = {
+    {"__objclass__", (getter)wrapper_objclass},
+    {"__name__", (getter)wrapper_name},
+    {"__doc__", (getter)wrapper_doc},
+    {0}
+};
+
+static PyObject *
+wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
+{
+    wrapperfunc wrapper = wp->descr->d_base->wrapper;
+    PyObject *self = wp->self;
+
+    if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
+        wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
+        return (*wk)(self, args, wp->descr->d_wrapped, kwds);
+    }
+
+    if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) {
+        PyErr_Format(PyExc_TypeError,
+                     "wrapper %s doesn't take keyword arguments",
+                     wp->descr->d_base->name);
+        return NULL;
+    }
+    return (*wrapper)(self, args, wp->descr->d_wrapped);
+}
+
+static int
+wrapper_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    wrapperobject *wp = (wrapperobject *)self;
+    Py_VISIT(wp->descr);
+    Py_VISIT(wp->self);
+    return 0;
+}
+
+static PyTypeObject wrappertype = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "method-wrapper",                           /* tp_name */
+    sizeof(wrapperobject),                      /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)wrapper_dealloc,                /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)wrapper_compare,                   /* tp_compare */
+    (reprfunc)wrapper_repr,                     /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)wrapper_hash,                     /* tp_hash */
+    (ternaryfunc)wrapper_call,                  /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+    0,                                          /* tp_doc */
+    wrapper_traverse,                           /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    wrapper_members,                            /* tp_members */
+    wrapper_getsets,                            /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+};
+
+PyObject *
+PyWrapper_New(PyObject *d, PyObject *self)
+{
+    wrapperobject *wp;
+    PyWrapperDescrObject *descr;
+
+    assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
+    descr = (PyWrapperDescrObject *)d;
+    assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+                                    (PyObject *)(descr->d_type)));
+
+    wp = PyObject_GC_New(wrapperobject, &wrappertype);
+    if (wp != NULL) {
+        Py_INCREF(descr);
+        wp->descr = descr;
+        Py_INCREF(self);
+        wp->self = self;
+        _PyObject_GC_TRACK(wp);
+    }
+    return (PyObject *)wp;
+}
+
+
+/* A built-in 'property' type */
+
+/*
+    class property(object):
+
+    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
+        if doc is None and fget is not None and hasattr(fget, "__doc__"):
+        doc = fget.__doc__
+        self.__get = fget
+        self.__set = fset
+        self.__del = fdel
+        self.__doc__ = doc
+
+    def __get__(self, inst, type=None):
+        if inst is None:
+        return self
+        if self.__get is None:
+        raise AttributeError, "unreadable attribute"
+        return self.__get(inst)
+
+    def __set__(self, inst, value):
+        if self.__set is None:
+        raise AttributeError, "can't set attribute"
+        return self.__set(inst, value)
+
+    def __delete__(self, inst):
+        if self.__del is None:
+        raise AttributeError, "can't delete attribute"
+        return self.__del(inst)
+
+*/
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *prop_get;
+    PyObject *prop_set;
+    PyObject *prop_del;
+    PyObject *prop_doc;
+    int getter_doc;
+} propertyobject;
+
+static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
+                                  PyObject *);
+
+static PyMemberDef property_members[] = {
+    {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
+    {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
+    {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
+    {"__doc__",  T_OBJECT, offsetof(propertyobject, prop_doc), READONLY},
+    {0}
+};
+
+
+PyDoc_STRVAR(getter_doc,
+             "Descriptor to change the getter on a property.");
+
+static PyObject *
+property_getter(PyObject *self, PyObject *getter)
+{
+    return property_copy(self, getter, NULL, NULL);
+}
+
+
+PyDoc_STRVAR(setter_doc,
+             "Descriptor to change the setter on a property.");
+
+static PyObject *
+property_setter(PyObject *self, PyObject *setter)
+{
+    return property_copy(self, NULL, setter, NULL);
+}
+
+
+PyDoc_STRVAR(deleter_doc,
+             "Descriptor to change the deleter on a property.");
+
+static PyObject *
+property_deleter(PyObject *self, PyObject *deleter)
+{
+    return property_copy(self, NULL, NULL, deleter);
+}
+
+
+static PyMethodDef property_methods[] = {
+    {"getter", property_getter, METH_O, getter_doc},
+    {"setter", property_setter, METH_O, setter_doc},
+    {"deleter", property_deleter, METH_O, deleter_doc},
+    {0}
+};
+
+
+static void
+property_dealloc(PyObject *self)
+{
+    propertyobject *gs = (propertyobject *)self;
+
+    _PyObject_GC_UNTRACK(self);
+    Py_XDECREF(gs->prop_get);
+    Py_XDECREF(gs->prop_set);
+    Py_XDECREF(gs->prop_del);
+    Py_XDECREF(gs->prop_doc);
+    self->ob_type->tp_free(self);
+}
+
+static PyObject *
+property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    propertyobject *gs = (propertyobject *)self;
+
+    if (obj == NULL || obj == Py_None) {
+        Py_INCREF(self);
+        return self;
+    }
+    if (gs->prop_get == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
+        return NULL;
+    }
+    return PyObject_CallFunction(gs->prop_get, "(O)", obj);
+}
+
+static int
+property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
+{
+    propertyobject *gs = (propertyobject *)self;
+    PyObject *func, *res;
+
+    if (value == NULL)
+        func = gs->prop_del;
+    else
+        func = gs->prop_set;
+    if (func == NULL) {
+        PyErr_SetString(PyExc_AttributeError,
+                        value == NULL ?
+                        "can't delete attribute" :
+                "can't set attribute");
+        return -1;
+    }
+    if (value == NULL)
+        res = PyObject_CallFunction(func, "(O)", obj);
+    else
+        res = PyObject_CallFunction(func, "(OO)", obj, value);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static PyObject *
+property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
+{
+    propertyobject *pold = (propertyobject *)old;
+    PyObject *new, *type, *doc;
+
+    type = PyObject_Type(old);
+    if (type == NULL)
+        return NULL;
+
+    if (get == NULL || get == Py_None) {
+        Py_XDECREF(get);
+        get = pold->prop_get ? pold->prop_get : Py_None;
+    }
+    if (set == NULL || set == Py_None) {
+        Py_XDECREF(set);
+        set = pold->prop_set ? pold->prop_set : Py_None;
+    }
+    if (del == NULL || del == Py_None) {
+        Py_XDECREF(del);
+        del = pold->prop_del ? pold->prop_del : Py_None;
+    }
+    if (pold->getter_doc && get != Py_None) {
+        /* make _init use __doc__ from getter */
+        doc = Py_None;
+    }
+    else {
+        doc = pold->prop_doc ? pold->prop_doc : Py_None;
+    }
+
+    new =  PyObject_CallFunction(type, "OOOO", get, set, del, doc);
+    Py_DECREF(type);
+    if (new == NULL)
+        return NULL;
+    return new;
+}
+
+static int
+property_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
+    static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
+    propertyobject *prop = (propertyobject *)self;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
+                                     kwlist, &get, &set, &del, &doc))
+        return -1;
+
+    if (get == Py_None)
+        get = NULL;
+    if (set == Py_None)
+        set = NULL;
+    if (del == Py_None)
+        del = NULL;
+
+    Py_XINCREF(get);
+    Py_XINCREF(set);
+    Py_XINCREF(del);
+    Py_XINCREF(doc);
+
+    prop->prop_get = get;
+    prop->prop_set = set;
+    prop->prop_del = del;
+    prop->prop_doc = doc;
+    prop->getter_doc = 0;
+
+    /* if no docstring given and the getter has one, use that one */
+    if ((doc == NULL || doc == Py_None) && get != NULL) {
+        PyObject *get_doc = PyObject_GetAttrString(get, "__doc__");
+        if (get_doc) {
+            if (Py_TYPE(self) == &PyProperty_Type) {
+                Py_XDECREF(prop->prop_doc);
+                prop->prop_doc = get_doc;
+            }
+            else {
+                /* If this is a property subclass, put __doc__
+                in dict of the subclass instance instead,
+                otherwise it gets shadowed by __doc__ in the
+                class's dict. */
+                int err = PyObject_SetAttrString(self, "__doc__", get_doc);
+                Py_DECREF(get_doc);
+                if (err < 0)
+                    return -1;
+            }
+            prop->getter_doc = 1;
+        }
+        else if (PyErr_ExceptionMatches(PyExc_Exception)) {
+            PyErr_Clear();
+        }
+        else {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+PyDoc_STRVAR(property_doc,
+"property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n"
+"\n"
+"fget is a function to be used for getting an attribute value, and likewise\n"
+"fset is a function for setting, and fdel a function for del'ing, an\n"
+"attribute.  Typical use is to define a managed attribute x:\n"
+"class C(object):\n"
+"    def getx(self): return self._x\n"
+"    def setx(self, value): self._x = value\n"
+"    def delx(self): del self._x\n"
+"    x = property(getx, setx, delx, \"I'm the 'x' property.\")\n"
+"\n"
+"Decorators make defining new properties or modifying existing ones easy:\n"
+"class C(object):\n"
+"    @property\n"
+"    def x(self): return self._x\n"
+"    @x.setter\n"
+"    def x(self, value): self._x = value\n"
+"    @x.deleter\n"
+"    def x(self): del self._x\n"
+);
+
+static int
+property_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    propertyobject *pp = (propertyobject *)self;
+    Py_VISIT(pp->prop_get);
+    Py_VISIT(pp->prop_set);
+    Py_VISIT(pp->prop_del);
+    Py_VISIT(pp->prop_doc);
+    return 0;
+}
+
+PyTypeObject PyProperty_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "property",                                 /* tp_name */
+    sizeof(propertyobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    property_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    property_doc,                               /* tp_doc */
+    property_traverse,                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    property_methods,                           /* tp_methods */
+    property_members,                           /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    property_descr_get,                         /* tp_descr_get */
+    property_descr_set,                         /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    property_init,                              /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    PyType_GenericNew,                          /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
diff --git a/Python-2.7.5/Objects/dictnotes.txt b/Python-2.7.5/Objects/dictnotes.txt
new file mode 100644
index 0000000..d3aa774
--- /dev/null
+++ b/Python-2.7.5/Objects/dictnotes.txt
@@ -0,0 +1,270 @@
+NOTES ON OPTIMIZING DICTIONARIES
+================================
+
+
+Principal Use Cases for Dictionaries
+------------------------------------
+
+Passing keyword arguments
+    Typically, one read and one write for 1 to 3 elements.
+    Occurs frequently in normal python code.
+
+Class method lookup
+    Dictionaries vary in size with 8 to 16 elements being common.
+    Usually written once with many lookups.
+    When base classes are used, there are many failed lookups
+        followed by a lookup in a base class.
+
+Instance attribute lookup and Global variables
+    Dictionaries vary in size.  4 to 10 elements are common.
+    Both reads and writes are common.
+
+Builtins
+    Frequent reads.  Almost never written.
+    Size 126 interned strings (as of Py2.3b1).
+    A few keys are accessed much more frequently than others.
+
+Uniquification
+    Dictionaries of any size.  Bulk of work is in creation.
+    Repeated writes to a smaller set of keys.
+    Single read of each key.
+    Some use cases have two consecutive accesses to the same key.
+
+    * Removing duplicates from a sequence.
+        dict.fromkeys(seqn).keys()
+
+    * Counting elements in a sequence.
+        for e in seqn:
+          d[e] = d.get(e,0) + 1
+
+    * Accumulating references in a dictionary of lists:
+
+        for pagenumber, page in enumerate(pages):
+          for word in page:
+            d.setdefault(word, []).append(pagenumber)
+
+    Note, the second example is a use case characterized by a get and set
+    to the same key.  There are similar use cases with a __contains__
+    followed by a get, set, or del to the same key.  Part of the
+    justification for d.setdefault is combining the two lookups into one.
+
+Membership Testing
+    Dictionaries of any size.  Created once and then rarely changes.
+    Single write to each key.
+    Many calls to __contains__() or has_key().
+    Similar access patterns occur with replacement dictionaries
+        such as with the % formatting operator.
+
+Dynamic Mappings
+    Characterized by deletions interspersed with adds and replacements.
+    Performance benefits greatly from the re-use of dummy entries.
+
+
+Data Layout (assuming a 32-bit box with 64 bytes per cache line)
+----------------------------------------------------------------
+
+Smalldicts (8 entries) are attached to the dictobject structure
+and the whole group nearly fills two consecutive cache lines.
+
+Larger dicts use the first half of the dictobject structure (one cache
+line) and a separate, continuous block of entries (at 12 bytes each
+for a total of 5.333 entries per cache line).
+
+
+Tunable Dictionary Parameters
+-----------------------------
+
+* PyDict_MINSIZE.  Currently set to 8.
+    Must be a power of two.  New dicts have to zero-out every cell.
+    Each additional 8 consumes 1.5 cache lines.  Increasing improves
+    the sparseness of small dictionaries but costs time to read in
+    the additional cache lines if they are not already in cache.
+    That case is common when keyword arguments are passed.
+
+* Maximum dictionary load in PyDict_SetItem.  Currently set to 2/3.
+    Increasing this ratio makes dictionaries more dense resulting
+    in more collisions.  Decreasing it improves sparseness at the
+    expense of spreading entries over more cache lines and at the
+    cost of total memory consumed.
+
+    The load test occurs in highly time sensitive code.  Efforts
+    to make the test more complex (for example, varying the load
+    for different sizes) have degraded performance.
+
+* Growth rate upon hitting maximum load.  Currently set to *2.
+    Raising this to *4 results in half the number of resizes,
+    less effort to resize, better sparseness for some (but not
+    all dict sizes), and potentially doubles memory consumption
+    depending on the size of the dictionary.  Setting to *4
+    eliminates every other resize step.
+
+* Maximum sparseness (minimum dictionary load).  What percentage
+    of entries can be unused before the dictionary shrinks to
+    free up memory and speed up iteration?  (The current CPython
+    code does not represent this parameter directly.)
+
+* Shrinkage rate upon exceeding maximum sparseness.  The current
+    CPython code never even checks sparseness when deleting a
+    key.  When a new key is added, it resizes based on the number
+    of active keys, so that the addition may trigger shrinkage
+    rather than growth.
+
+Tune-ups should be measured across a broad range of applications and
+use cases.  A change to any parameter will help in some situations and
+hurt in others.  The key is to find settings that help the most common
+cases and do the least damage to the less common cases.  Results will
+vary dramatically depending on the exact number of keys, whether the
+keys are all strings, whether reads or writes dominate, the exact
+hash values of the keys (some sets of values have fewer collisions than
+others).  Any one test or benchmark is likely to prove misleading.
+
+While making a dictionary more sparse reduces collisions, it impairs
+iteration and key listing.  Those methods loop over every potential
+entry.  Doubling the size of dictionary results in twice as many
+non-overlapping memory accesses for keys(), items(), values(),
+__iter__(), iterkeys(), iteritems(), itervalues(), and update().
+Also, every dictionary iterates at least twice, once for the memset()
+when it is created and once by dealloc().
+
+Dictionary operations involving only a single key can be O(1) unless 
+resizing is possible.  By checking for a resize only when the 
+dictionary can grow (and may *require* resizing), other operations
+remain O(1), and the odds of resize thrashing or memory fragmentation
+are reduced. In particular, an algorithm that empties a dictionary
+by repeatedly invoking .pop will see no resizing, which might
+not be necessary at all because the dictionary is eventually
+discarded entirely.
+
+
+Results of Cache Locality Experiments
+-------------------------------------
+
+When an entry is retrieved from memory, 4.333 adjacent entries are also
+retrieved into a cache line.  Since accessing items in cache is *much*
+cheaper than a cache miss, an enticing idea is to probe the adjacent
+entries as a first step in collision resolution.  Unfortunately, the
+introduction of any regularity into collision searches results in more
+collisions than the current random chaining approach.
+
+Exploiting cache locality at the expense of additional collisions fails
+to payoff when the entries are already loaded in cache (the expense
+is paid with no compensating benefit).  This occurs in small dictionaries
+where the whole dictionary fits into a pair of cache lines.  It also
+occurs frequently in large dictionaries which have a common access pattern
+where some keys are accessed much more frequently than others.  The
+more popular entries *and* their collision chains tend to remain in cache.
+
+To exploit cache locality, change the collision resolution section
+in lookdict() and lookdict_string().  Set i^=1 at the top of the
+loop and move the  i = (i << 2) + i + perturb + 1 to an unrolled
+version of the loop.
+
+This optimization strategy can be leveraged in several ways:
+
+* If the dictionary is kept sparse (through the tunable parameters),
+then the occurrence of additional collisions is lessened.
+
+* If lookdict() and lookdict_string() are specialized for small dicts
+and for largedicts, then the versions for large_dicts can be given
+an alternate search strategy without increasing collisions in small dicts
+which already have the maximum benefit of cache locality.
+
+* If the use case for a dictionary is known to have a random key
+access pattern (as opposed to a more common pattern with a Zipf's law
+distribution), then there will be more benefit for large dictionaries
+because any given key is no more likely than another to already be
+in cache.
+
+* In use cases with paired accesses to the same key, the second access
+is always in cache and gets no benefit from efforts to further improve
+cache locality.
+
+Optimizing the Search of Small Dictionaries
+-------------------------------------------
+
+If lookdict() and lookdict_string() are specialized for smaller dictionaries,
+then a custom search approach can be implemented that exploits the small
+search space and cache locality.
+
+* The simplest example is a linear search of contiguous entries.  This is
+  simple to implement, guaranteed to terminate rapidly, never searches
+  the same entry twice, and precludes the need to check for dummy entries.
+
+* A more advanced example is a self-organizing search so that the most
+  frequently accessed entries get probed first.  The organization
+  adapts if the access pattern changes over time.  Treaps are ideally
+  suited for self-organization with the most common entries at the
+  top of the heap and a rapid binary search pattern.  Most probes and
+  results are all located at the top of the tree allowing them all to
+  be located in one or two cache lines.
+
+* Also, small dictionaries may be made more dense, perhaps filling all
+  eight cells to take the maximum advantage of two cache lines.
+
+
+Strategy Pattern
+----------------
+
+Consider allowing the user to set the tunable parameters or to select a
+particular search method.  Since some dictionary use cases have known
+sizes and access patterns, the user may be able to provide useful hints.
+
+1) For example, if membership testing or lookups dominate runtime and memory
+   is not at a premium, the user may benefit from setting the maximum load
+   ratio at 5% or 10% instead of the usual 66.7%.  This will sharply
+   curtail the number of collisions but will increase iteration time.
+   The builtin namespace is a prime example of a dictionary that can
+   benefit from being highly sparse.
+
+2) Dictionary creation time can be shortened in cases where the ultimate
+   size of the dictionary is known in advance.  The dictionary can be
+   pre-sized so that no resize operations are required during creation.
+   Not only does this save resizes, but the key insertion will go
+   more quickly because the first half of the keys will be inserted into
+   a more sparse environment than before.  The preconditions for this
+   strategy arise whenever a dictionary is created from a key or item
+   sequence and the number of *unique* keys is known.
+
+3) If the key space is large and the access pattern is known to be random,
+   then search strategies exploiting cache locality can be fruitful.
+   The preconditions for this strategy arise in simulations and
+   numerical analysis.
+
+4) If the keys are fixed and the access pattern strongly favors some of
+   the keys, then the entries can be stored contiguously and accessed
+   with a linear search or treap.  This exploits knowledge of the data,
+   cache locality, and a simplified search routine.  It also eliminates
+   the need to test for dummy entries on each probe.  The preconditions
+   for this strategy arise in symbol tables and in the builtin dictionary.
+
+
+Readonly Dictionaries
+---------------------
+Some dictionary use cases pass through a build stage and then move to a
+more heavily exercised lookup stage with no further changes to the
+dictionary.
+
+An idea that emerged on python-dev is to be able to convert a dictionary
+to a read-only state.  This can help prevent programming errors and also
+provide knowledge that can be exploited for lookup optimization.
+
+The dictionary can be immediately rebuilt (eliminating dummy entries),
+resized (to an appropriate level of sparseness), and the keys can be
+jostled (to minimize collisions).  The lookdict() routine can then
+eliminate the test for dummy entries (saving about 1/4 of the time
+spent in the collision resolution loop).
+
+An additional possibility is to insert links into the empty spaces
+so that dictionary iteration can proceed in len(d) steps instead of
+(mp->mask + 1) steps.  Alternatively, a separate tuple of keys can be
+kept just for iteration.
+
+
+Caching Lookups
+---------------
+The idea is to exploit key access patterns by anticipating future lookups
+based on previous lookups.
+
+The simplest incarnation is to save the most recently accessed entry.
+This gives optimal performance for use cases where every get is followed
+by a set or del to the same key.
diff --git a/Python-2.7.5/Objects/dictobject.c b/Python-2.7.5/Objects/dictobject.c
new file mode 100644
index 0000000..ba36b18
--- /dev/null
+++ b/Python-2.7.5/Objects/dictobject.c
@@ -0,0 +1,3244 @@
+
+/* Dictionary object implementation using a hash table */
+
+/* The distribution includes a separate file, Objects/dictnotes.txt,
+   describing explorations into dictionary design and optimization.
+   It covers typical dictionary use patterns, the parameters for
+   tuning dictionaries, and several ideas for possible optimizations.
+*/
+
+#include "Python.h"
+
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+    PyObject *tup;
+    tup = PyTuple_Pack(1, arg);
+    if (!tup)
+        return; /* caller will expect error to be set anyway */
+    PyErr_SetObject(PyExc_KeyError, tup);
+    Py_DECREF(tup);
+}
+
+/* Define this out if you don't want conversion statistics on exit. */
+#undef SHOW_CONVERSION_COUNTS
+
+/* See large comment block below.  This must be >= 1. */
+#define PERTURB_SHIFT 5
+
+/*
+Major subtleties ahead:  Most hash schemes depend on having a "good" hash
+function, in the sense of simulating randomness.  Python doesn't:  its most
+important hash functions (for strings and ints) are very regular in common
+cases:
+
+>>> map(hash, (0, 1, 2, 3))
+[0, 1, 2, 3]
+>>> map(hash, ("namea", "nameb", "namec", "named"))
+[-1658398457, -1658398460, -1658398459, -1658398462]
+>>>
+
+This isn't necessarily bad!  To the contrary, in a table of size 2**i, taking
+the low-order i bits as the initial table index is extremely fast, and there
+are no collisions at all for dicts indexed by a contiguous range of ints.
+The same is approximately true when keys are "consecutive" strings.  So this
+gives better-than-random behavior in common cases, and that's very desirable.
+
+OTOH, when collisions occur, the tendency to fill contiguous slices of the
+hash table makes a good collision resolution strategy crucial.  Taking only
+the last i bits of the hash code is also vulnerable:  for example, consider
+[i << 16 for i in range(20000)] as a set of keys.  Since ints are their own
+hash codes, and this fits in a dict of size 2**15, the last 15 bits of every
+hash code are all 0:  they *all* map to the same table index.
+
+But catering to unusual cases should not slow the usual ones, so we just take
+the last i bits anyway.  It's up to collision resolution to do the rest.  If
+we *usually* find the key we're looking for on the first try (and, it turns
+out, we usually do -- the table load factor is kept under 2/3, so the odds
+are solidly in our favor), then it makes best sense to keep the initial index
+computation dirt cheap.
+
+The first half of collision resolution is to visit table indices via this
+recurrence:
+
+    j = ((5*j) + 1) mod 2**i
+
+For any initial j in range(2**i), repeating that 2**i times generates each
+int in range(2**i) exactly once (see any text on random-number generation for
+proof).  By itself, this doesn't help much:  like linear probing (setting
+j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
+order.  This would be bad, except that's not the only thing we do, and it's
+actually *good* in the common cases where hash keys are consecutive.  In an
+example that's really too small to make this entirely clear, for a table of
+size 2**3 the order of indices is:
+
+    0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
+
+If two things come in at index 5, the first place we look after is index 2,
+not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
+Linear probing is deadly in this case because there the fixed probe order
+is the *same* as the order consecutive keys are likely to arrive.  But it's
+extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
+and certain that consecutive hash codes do not.
+
+The other half of the strategy is to get the other bits of the hash code
+into play.  This is done by initializing a (unsigned) vrbl "perturb" to the
+full hash code, and changing the recurrence to:
+
+    j = (5*j) + 1 + perturb;
+    perturb >>= PERTURB_SHIFT;
+    use j % 2**i as the next table index;
+
+Now the probe sequence depends (eventually) on every bit in the hash code,
+and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
+because it quickly magnifies small differences in the bits that didn't affect
+the initial index.  Note that because perturb is unsigned, if the recurrence
+is executed often enough perturb eventually becomes and remains 0.  At that
+point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
+that's certain to find an empty slot eventually (since it generates every int
+in range(2**i), and we make sure there's always at least one empty slot).
+
+Selecting a good value for PERTURB_SHIFT is a balancing act.  You want it
+small so that the high bits of the hash code continue to affect the probe
+sequence across iterations; but you want it large so that in really bad cases
+the high-order hash bits have an effect on early iterations.  5 was "the
+best" in minimizing total collisions across experiments Tim Peters ran (on
+both normal and pathological cases), but 4 and 6 weren't significantly worse.
+
+Historical:  Reimer Behrends contributed the idea of using a polynomial-based
+approach, using repeated multiplication by x in GF(2**n) where an irreducible
+polynomial for each table size was chosen such that x was a primitive root.
+Christian Tismer later extended that to use division by x instead, as an
+efficient way to get the high bits of the hash code into play.  This scheme
+also gave excellent collision statistics, but was more expensive:  two
+if-tests were required inside the loop; computing "the next" index took about
+the same number of operations but without as much potential parallelism
+(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
+above, and then shifting perturb can be done while the table index is being
+masked); and the PyDictObject struct required a member to hold the table's
+polynomial.  In Tim's experiments the current scheme ran faster, produced
+equally good collision statistics, needed less code & used less memory.
+
+Theoretical Python 2.5 headache:  hash codes are only C "long", but
+sizeof(Py_ssize_t) > sizeof(long) may be possible.  In that case, and if a
+dict is genuinely huge, then only the slots directly reachable via indexing
+by a C long can be the first slot in a probe sequence.  The probe sequence
+will still eventually reach every slot in the table, but the collision rate
+on initial probes may be much higher than this scheme was designed for.
+Getting a hash code as fat as Py_ssize_t is the only real cure.  But in
+practice, this probably won't make a lick of difference for many years (at
+which point everyone will have terabytes of RAM on 64-bit boxes).
+*/
+
+/* Object used as dummy key to fill deleted entries */
+static PyObject *dummy = NULL; /* Initialized by first call to newPyDictObject() */
+
+#ifdef Py_REF_DEBUG
+PyObject *
+_PyDict_Dummy(void)
+{
+    return dummy;
+}
+#endif
+
+/* forward declarations */
+static PyDictEntry *
+lookdict_string(PyDictObject *mp, PyObject *key, long hash);
+
+#ifdef SHOW_CONVERSION_COUNTS
+static long created = 0L;
+static long converted = 0L;
+
+static void
+show_counts(void)
+{
+    fprintf(stderr, "created %ld string dicts\n", created);
+    fprintf(stderr, "converted %ld to normal dicts\n", converted);
+    fprintf(stderr, "%.2f%% conversion rate\n", (100.0*converted)/created);
+}
+#endif
+
+/* Debug statistic to compare allocations with reuse through the free list */
+#undef SHOW_ALLOC_COUNT
+#ifdef SHOW_ALLOC_COUNT
+static size_t count_alloc = 0;
+static size_t count_reuse = 0;
+
+static void
+show_alloc(void)
+{
+    fprintf(stderr, "Dict allocations: %" PY_FORMAT_SIZE_T "d\n",
+        count_alloc);
+    fprintf(stderr, "Dict reuse through freelist: %" PY_FORMAT_SIZE_T
+        "d\n", count_reuse);
+    fprintf(stderr, "%.2f%% reuse rate\n\n",
+        (100.0*count_reuse/(count_alloc+count_reuse)));
+}
+#endif
+
+/* Debug statistic to count GC tracking of dicts */
+#ifdef SHOW_TRACK_COUNT
+static Py_ssize_t count_untracked = 0;
+static Py_ssize_t count_tracked = 0;
+
+static void
+show_track(void)
+{
+    fprintf(stderr, "Dicts created: %" PY_FORMAT_SIZE_T "d\n",
+        count_tracked + count_untracked);
+    fprintf(stderr, "Dicts tracked by the GC: %" PY_FORMAT_SIZE_T
+        "d\n", count_tracked);
+    fprintf(stderr, "%.2f%% dict tracking rate\n\n",
+        (100.0*count_tracked/(count_untracked+count_tracked)));
+}
+#endif
+
+
+/* Initialization macros.
+   There are two ways to create a dict:  PyDict_New() is the main C API
+   function, and the tp_new slot maps to dict_new().  In the latter case we
+   can save a little time over what PyDict_New does because it's guaranteed
+   that the PyDictObject struct is already zeroed out.
+   Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have
+   an excellent reason not to).
+*/
+
+#define INIT_NONZERO_DICT_SLOTS(mp) do {                                \
+    (mp)->ma_table = (mp)->ma_smalltable;                               \
+    (mp)->ma_mask = PyDict_MINSIZE - 1;                                 \
+    } while(0)
+
+#define EMPTY_TO_MINSIZE(mp) do {                                       \
+    memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));        \
+    (mp)->ma_used = (mp)->ma_fill = 0;                                  \
+    INIT_NONZERO_DICT_SLOTS(mp);                                        \
+    } while(0)
+
+/* Dictionary reuse scheme to save calls to malloc, free, and memset */
+#ifndef PyDict_MAXFREELIST
+#define PyDict_MAXFREELIST 80
+#endif
+static PyDictObject *free_list[PyDict_MAXFREELIST];
+static int numfree = 0;
+
+void
+PyDict_Fini(void)
+{
+    PyDictObject *op;
+
+    while (numfree) {
+        op = free_list[--numfree];
+        assert(PyDict_CheckExact(op));
+        PyObject_GC_Del(op);
+    }
+}
+
+PyObject *
+PyDict_New(void)
+{
+    register PyDictObject *mp;
+    if (dummy == NULL) { /* Auto-initialize dummy */
+        dummy = PyString_FromString("<dummy key>");
+        if (dummy == NULL)
+            return NULL;
+#ifdef SHOW_CONVERSION_COUNTS
+        Py_AtExit(show_counts);
+#endif
+#ifdef SHOW_ALLOC_COUNT
+        Py_AtExit(show_alloc);
+#endif
+#ifdef SHOW_TRACK_COUNT
+        Py_AtExit(show_track);
+#endif
+    }
+    if (numfree) {
+        mp = free_list[--numfree];
+        assert (mp != NULL);
+        assert (Py_TYPE(mp) == &PyDict_Type);
+        _Py_NewReference((PyObject *)mp);
+        if (mp->ma_fill) {
+            EMPTY_TO_MINSIZE(mp);
+        } else {
+            /* At least set ma_table and ma_mask; these are wrong
+               if an empty but presized dict is added to freelist */
+            INIT_NONZERO_DICT_SLOTS(mp);
+        }
+        assert (mp->ma_used == 0);
+        assert (mp->ma_table == mp->ma_smalltable);
+        assert (mp->ma_mask == PyDict_MINSIZE - 1);
+#ifdef SHOW_ALLOC_COUNT
+        count_reuse++;
+#endif
+    } else {
+        mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
+        if (mp == NULL)
+            return NULL;
+        EMPTY_TO_MINSIZE(mp);
+#ifdef SHOW_ALLOC_COUNT
+        count_alloc++;
+#endif
+    }
+    mp->ma_lookup = lookdict_string;
+#ifdef SHOW_TRACK_COUNT
+    count_untracked++;
+#endif
+#ifdef SHOW_CONVERSION_COUNTS
+    ++created;
+#endif
+    return (PyObject *)mp;
+}
+
+/*
+The basic lookup function used by all operations.
+This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
+Open addressing is preferred over chaining since the link overhead for
+chaining would be substantial (100% with typical malloc overhead).
+
+The initial probe index is computed as hash mod the table size. Subsequent
+probe indices are computed as explained earlier.
+
+All arithmetic on hash should ignore overflow.
+
+(The details in this version are due to Tim Peters, building on many past
+contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
+Christian Tismer).
+
+lookdict() is general-purpose, and may return NULL if (and only if) a
+comparison raises an exception (this was new in Python 2.5).
+lookdict_string() below is specialized to string keys, comparison of which can
+never raise an exception; that function can never return NULL.  For both, when
+the key isn't found a PyDictEntry* is returned for which the me_value field is
+NULL; this is the slot in the dict at which the key would have been found, and
+the caller can (if it wishes) add the <key, value> pair to the returned
+PyDictEntry*.
+*/
+static PyDictEntry *
+lookdict(PyDictObject *mp, PyObject *key, register long hash)
+{
+    register size_t i;
+    register size_t perturb;
+    register PyDictEntry *freeslot;
+    register size_t mask = (size_t)mp->ma_mask;
+    PyDictEntry *ep0 = mp->ma_table;
+    register PyDictEntry *ep;
+    register int cmp;
+    PyObject *startkey;
+
+    i = (size_t)hash & mask;
+    ep = &ep0[i];
+    if (ep->me_key == NULL || ep->me_key == key)
+        return ep;
+
+    if (ep->me_key == dummy)
+        freeslot = ep;
+    else {
+        if (ep->me_hash == hash) {
+            startkey = ep->me_key;
+            Py_INCREF(startkey);
+            cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+            Py_DECREF(startkey);
+            if (cmp < 0)
+                return NULL;
+            if (ep0 == mp->ma_table && ep->me_key == startkey) {
+                if (cmp > 0)
+                    return ep;
+            }
+            else {
+                /* The compare did major nasty stuff to the
+                 * dict:  start over.
+                 * XXX A clever adversary could prevent this
+                 * XXX from terminating.
+                 */
+                return lookdict(mp, key, hash);
+            }
+        }
+        freeslot = NULL;
+    }
+
+    /* In the loop, me_key == dummy is by far (factor of 100s) the
+       least likely outcome, so test for that last. */
+    for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+        i = (i << 2) + i + perturb + 1;
+        ep = &ep0[i & mask];
+        if (ep->me_key == NULL)
+            return freeslot == NULL ? ep : freeslot;
+        if (ep->me_key == key)
+            return ep;
+        if (ep->me_hash == hash && ep->me_key != dummy) {
+            startkey = ep->me_key;
+            Py_INCREF(startkey);
+            cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+            Py_DECREF(startkey);
+            if (cmp < 0)
+                return NULL;
+            if (ep0 == mp->ma_table && ep->me_key == startkey) {
+                if (cmp > 0)
+                    return ep;
+            }
+            else {
+                /* The compare did major nasty stuff to the
+                 * dict:  start over.
+                 * XXX A clever adversary could prevent this
+                 * XXX from terminating.
+                 */
+                return lookdict(mp, key, hash);
+            }
+        }
+        else if (ep->me_key == dummy && freeslot == NULL)
+            freeslot = ep;
+    }
+    assert(0);          /* NOT REACHED */
+    return 0;
+}
+
+/*
+ * Hacked up version of lookdict which can assume keys are always strings;
+ * this assumption allows testing for errors during PyObject_RichCompareBool()
+ * to be dropped; string-string comparisons never raise exceptions.  This also
+ * means we don't need to go through PyObject_RichCompareBool(); we can always
+ * use _PyString_Eq() directly.
+ *
+ * This is valuable because dicts with only string keys are very common.
+ */
+static PyDictEntry *
+lookdict_string(PyDictObject *mp, PyObject *key, register long hash)
+{
+    register size_t i;
+    register size_t perturb;
+    register PyDictEntry *freeslot;
+    register size_t mask = (size_t)mp->ma_mask;
+    PyDictEntry *ep0 = mp->ma_table;
+    register PyDictEntry *ep;
+
+    /* Make sure this function doesn't have to handle non-string keys,
+       including subclasses of str; e.g., one reason to subclass
+       strings is to override __eq__, and for speed we don't cater to
+       that here. */
+    if (!PyString_CheckExact(key)) {
+#ifdef SHOW_CONVERSION_COUNTS
+        ++converted;
+#endif
+        mp->ma_lookup = lookdict;
+        return lookdict(mp, key, hash);
+    }
+    i = hash & mask;
+    ep = &ep0[i];
+    if (ep->me_key == NULL || ep->me_key == key)
+        return ep;
+    if (ep->me_key == dummy)
+        freeslot = ep;
+    else {
+        if (ep->me_hash == hash && _PyString_Eq(ep->me_key, key))
+            return ep;
+        freeslot = NULL;
+    }
+
+    /* In the loop, me_key == dummy is by far (factor of 100s) the
+       least likely outcome, so test for that last. */
+    for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+        i = (i << 2) + i + perturb + 1;
+        ep = &ep0[i & mask];
+        if (ep->me_key == NULL)
+            return freeslot == NULL ? ep : freeslot;
+        if (ep->me_key == key
+            || (ep->me_hash == hash
+            && ep->me_key != dummy
+            && _PyString_Eq(ep->me_key, key)))
+            return ep;
+        if (ep->me_key == dummy && freeslot == NULL)
+            freeslot = ep;
+    }
+    assert(0);          /* NOT REACHED */
+    return 0;
+}
+
+#ifdef SHOW_TRACK_COUNT
+#define INCREASE_TRACK_COUNT \
+    (count_tracked++, count_untracked--);
+#define DECREASE_TRACK_COUNT \
+    (count_tracked--, count_untracked++);
+#else
+#define INCREASE_TRACK_COUNT
+#define DECREASE_TRACK_COUNT
+#endif
+
+#define MAINTAIN_TRACKING(mp, key, value) \
+    do { \
+        if (!_PyObject_GC_IS_TRACKED(mp)) { \
+            if (_PyObject_GC_MAY_BE_TRACKED(key) || \
+                _PyObject_GC_MAY_BE_TRACKED(value)) { \
+                _PyObject_GC_TRACK(mp); \
+                INCREASE_TRACK_COUNT \
+            } \
+        } \
+    } while(0)
+
+void
+_PyDict_MaybeUntrack(PyObject *op)
+{
+    PyDictObject *mp;
+    PyObject *value;
+    Py_ssize_t mask, i;
+    PyDictEntry *ep;
+
+    if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
+        return;
+
+    mp = (PyDictObject *) op;
+    ep = mp->ma_table;
+    mask = mp->ma_mask;
+    for (i = 0; i <= mask; i++) {
+        if ((value = ep[i].me_value) == NULL)
+            continue;
+        if (_PyObject_GC_MAY_BE_TRACKED(value) ||
+            _PyObject_GC_MAY_BE_TRACKED(ep[i].me_key))
+            return;
+    }
+    DECREASE_TRACK_COUNT
+    _PyObject_GC_UNTRACK(op);
+}
+
+/*
+Internal routine to insert a new item into the table when you have entry object.
+Used by insertdict.
+*/
+static int
+insertdict_by_entry(register PyDictObject *mp, PyObject *key, long hash,
+                    PyDictEntry *ep, PyObject *value)
+{
+    PyObject *old_value;
+
+    MAINTAIN_TRACKING(mp, key, value);
+    if (ep->me_value != NULL) {
+        old_value = ep->me_value;
+        ep->me_value = value;
+        Py_DECREF(old_value); /* which **CAN** re-enter */
+        Py_DECREF(key);
+    }
+    else {
+        if (ep->me_key == NULL)
+            mp->ma_fill++;
+        else {
+            assert(ep->me_key == dummy);
+            Py_DECREF(dummy);
+        }
+        ep->me_key = key;
+        ep->me_hash = (Py_ssize_t)hash;
+        ep->me_value = value;
+        mp->ma_used++;
+    }
+    return 0;
+}
+
+
+/*
+Internal routine to insert a new item into the table.
+Used both by the internal resize routine and by the public insert routine.
+Eats a reference to key and one to value.
+Returns -1 if an error occurred, or 0 on success.
+*/
+static int
+insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
+{
+    register PyDictEntry *ep;
+
+    assert(mp->ma_lookup != NULL);
+    ep = mp->ma_lookup(mp, key, hash);
+    if (ep == NULL) {
+        Py_DECREF(key);
+        Py_DECREF(value);
+        return -1;
+    }
+    return insertdict_by_entry(mp, key, hash, ep, value);
+}
+
+/*
+Internal routine used by dictresize() to insert an item which is
+known to be absent from the dict.  This routine also assumes that
+the dict contains no deleted entries.  Besides the performance benefit,
+using insertdict() in dictresize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key` and `value`.
+*/
+static void
+insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
+                 PyObject *value)
+{
+    register size_t i;
+    register size_t perturb;
+    register size_t mask = (size_t)mp->ma_mask;
+    PyDictEntry *ep0 = mp->ma_table;
+    register PyDictEntry *ep;
+
+    MAINTAIN_TRACKING(mp, key, value);
+    i = hash & mask;
+    ep = &ep0[i];
+    for (perturb = hash; ep->me_key != NULL; perturb >>= PERTURB_SHIFT) {
+        i = (i << 2) + i + perturb + 1;
+        ep = &ep0[i & mask];
+    }
+    assert(ep->me_value == NULL);
+    mp->ma_fill++;
+    ep->me_key = key;
+    ep->me_hash = (Py_ssize_t)hash;
+    ep->me_value = value;
+    mp->ma_used++;
+}
+
+/*
+Restructure the table by allocating a new table and reinserting all
+items again.  When entries have been deleted, the new table may
+actually be smaller than the old one.
+*/
+static int
+dictresize(PyDictObject *mp, Py_ssize_t minused)
+{
+    Py_ssize_t newsize;
+    PyDictEntry *oldtable, *newtable, *ep;
+    Py_ssize_t i;
+    int is_oldtable_malloced;
+    PyDictEntry small_copy[PyDict_MINSIZE];
+
+    assert(minused >= 0);
+
+    /* Find the smallest table size > minused. */
+    for (newsize = PyDict_MINSIZE;
+         newsize <= minused && newsize > 0;
+         newsize <<= 1)
+        ;
+    if (newsize <= 0) {
+        PyErr_NoMemory();
+        return -1;
+    }
+
+    /* Get space for a new table. */
+    oldtable = mp->ma_table;
+    assert(oldtable != NULL);
+    is_oldtable_malloced = oldtable != mp->ma_smalltable;
+
+    if (newsize == PyDict_MINSIZE) {
+        /* A large table is shrinking, or we can't get any smaller. */
+        newtable = mp->ma_smalltable;
+        if (newtable == oldtable) {
+            if (mp->ma_fill == mp->ma_used) {
+                /* No dummies, so no point doing anything. */
+                return 0;
+            }
+            /* We're not going to resize it, but rebuild the
+               table anyway to purge old dummy entries.
+               Subtle:  This is *necessary* if fill==size,
+               as lookdict needs at least one virgin slot to
+               terminate failing searches.  If fill < size, it's
+               merely desirable, as dummies slow searches. */
+            assert(mp->ma_fill > mp->ma_used);
+            memcpy(small_copy, oldtable, sizeof(small_copy));
+            oldtable = small_copy;
+        }
+    }
+    else {
+        newtable = PyMem_NEW(PyDictEntry, newsize);
+        if (newtable == NULL) {
+            PyErr_NoMemory();
+            return -1;
+        }
+    }
+
+    /* Make the dict empty, using the new table. */
+    assert(newtable != oldtable);
+    mp->ma_table = newtable;
+    mp->ma_mask = newsize - 1;
+    memset(newtable, 0, sizeof(PyDictEntry) * newsize);
+    mp->ma_used = 0;
+    i = mp->ma_fill;
+    mp->ma_fill = 0;
+
+    /* Copy the data over; this is refcount-neutral for active entries;
+       dummy entries aren't copied over, of course */
+    for (ep = oldtable; i > 0; ep++) {
+        if (ep->me_value != NULL) {             /* active entry */
+            --i;
+            insertdict_clean(mp, ep->me_key, (long)ep->me_hash,
+                             ep->me_value);
+        }
+        else if (ep->me_key != NULL) {          /* dummy entry */
+            --i;
+            assert(ep->me_key == dummy);
+            Py_DECREF(ep->me_key);
+        }
+        /* else key == value == NULL:  nothing to do */
+    }
+
+    if (is_oldtable_malloced)
+        PyMem_DEL(oldtable);
+    return 0;
+}
+
+/* Create a new dictionary pre-sized to hold an estimated number of elements.
+   Underestimates are okay because the dictionary will resize as necessary.
+   Overestimates just mean the dictionary will be more sparse than usual.
+*/
+
+PyObject *
+_PyDict_NewPresized(Py_ssize_t minused)
+{
+    PyObject *op = PyDict_New();
+
+    if (minused>5 && op != NULL && dictresize((PyDictObject *)op, minused) == -1) {
+        Py_DECREF(op);
+        return NULL;
+    }
+    return op;
+}
+
+/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
+ * that may occur (originally dicts supported only string keys, and exceptions
+ * weren't possible).  So, while the original intent was that a NULL return
+ * meant the key wasn't present, in reality it can mean that, or that an error
+ * (suppressed) occurred while computing the key's hash, or that some error
+ * (suppressed) occurred when comparing keys in the dict's internal probe
+ * sequence.  A nasty example of the latter is when a Python-coded comparison
+ * function hits a stack-depth error, which can cause this to return NULL
+ * even if the key is present.
+ */
+PyObject *
+PyDict_GetItem(PyObject *op, PyObject *key)
+{
+    long hash;
+    PyDictObject *mp = (PyDictObject *)op;
+    PyDictEntry *ep;
+    PyThreadState *tstate;
+    if (!PyDict_Check(op))
+        return NULL;
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1)
+    {
+        hash = PyObject_Hash(key);
+        if (hash == -1) {
+            PyErr_Clear();
+            return NULL;
+        }
+    }
+
+    /* We can arrive here with a NULL tstate during initialization: try
+       running "python -Wi" for an example related to string interning.
+       Let's just hope that no exception occurs then...  This must be
+       _PyThreadState_Current and not PyThreadState_GET() because in debug
+       mode, the latter complains if tstate is NULL. */
+    tstate = _PyThreadState_Current;
+    if (tstate != NULL && tstate->curexc_type != NULL) {
+        /* preserve the existing exception */
+        PyObject *err_type, *err_value, *err_tb;
+        PyErr_Fetch(&err_type, &err_value, &err_tb);
+        ep = (mp->ma_lookup)(mp, key, hash);
+        /* ignore errors */
+        PyErr_Restore(err_type, err_value, err_tb);
+        if (ep == NULL)
+            return NULL;
+    }
+    else {
+        ep = (mp->ma_lookup)(mp, key, hash);
+        if (ep == NULL) {
+            PyErr_Clear();
+            return NULL;
+        }
+    }
+    return ep->me_value;
+}
+
+static int
+dict_set_item_by_hash_or_entry(register PyObject *op, PyObject *key,
+                               long hash, PyDictEntry *ep, PyObject *value)
+{
+    register PyDictObject *mp;
+    register Py_ssize_t n_used;
+
+    mp = (PyDictObject *)op;
+    assert(mp->ma_fill <= mp->ma_mask);  /* at least one empty slot */
+    n_used = mp->ma_used;
+    Py_INCREF(value);
+    Py_INCREF(key);
+    if (ep == NULL) {
+        if (insertdict(mp, key, hash, value) != 0)
+            return -1;
+    }
+    else {
+        if (insertdict_by_entry(mp, key, hash, ep, value) != 0)
+            return -1;
+    }
+    /* If we added a key, we can safely resize.  Otherwise just return!
+     * If fill >= 2/3 size, adjust size.  Normally, this doubles or
+     * quaduples the size, but it's also possible for the dict to shrink
+     * (if ma_fill is much larger than ma_used, meaning a lot of dict
+     * keys have been * deleted).
+     *
+     * Quadrupling the size improves average dictionary sparseness
+     * (reducing collisions) at the cost of some memory and iteration
+     * speed (which loops over every possible entry).  It also halves
+     * the number of expensive resize operations in a growing dictionary.
+     *
+     * Very large dictionaries (over 50K items) use doubling instead.
+     * This may help applications with severe memory constraints.
+     */
+    if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2))
+        return 0;
+    return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used);
+}
+
+/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
+ * dictionary if it's merely replacing the value for an existing key.
+ * This means that it's safe to loop over a dictionary with PyDict_Next()
+ * and occasionally replace a value -- but you can't insert new keys or
+ * remove them.
+ */
+int
+PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
+{
+    register long hash;
+
+    if (!PyDict_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    assert(key);
+    assert(value);
+    if (PyString_CheckExact(key)) {
+        hash = ((PyStringObject *)key)->ob_shash;
+        if (hash == -1)
+            hash = PyObject_Hash(key);
+    }
+    else {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return -1;
+    }
+    return dict_set_item_by_hash_or_entry(op, key, hash, NULL, value);
+}
+
+int
+PyDict_DelItem(PyObject *op, PyObject *key)
+{
+    register PyDictObject *mp;
+    register long hash;
+    register PyDictEntry *ep;
+    PyObject *old_value, *old_key;
+
+    if (!PyDict_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    assert(key);
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return -1;
+    }
+    mp = (PyDictObject *)op;
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL)
+        return -1;
+    if (ep->me_value == NULL) {
+        set_key_error(key);
+        return -1;
+    }
+    old_key = ep->me_key;
+    Py_INCREF(dummy);
+    ep->me_key = dummy;
+    old_value = ep->me_value;
+    ep->me_value = NULL;
+    mp->ma_used--;
+    Py_DECREF(old_value);
+    Py_DECREF(old_key);
+    return 0;
+}
+
+void
+PyDict_Clear(PyObject *op)
+{
+    PyDictObject *mp;
+    PyDictEntry *ep, *table;
+    int table_is_malloced;
+    Py_ssize_t fill;
+    PyDictEntry small_copy[PyDict_MINSIZE];
+#ifdef Py_DEBUG
+    Py_ssize_t i, n;
+#endif
+
+    if (!PyDict_Check(op))
+        return;
+    mp = (PyDictObject *)op;
+#ifdef Py_DEBUG
+    n = mp->ma_mask + 1;
+    i = 0;
+#endif
+
+    table = mp->ma_table;
+    assert(table != NULL);
+    table_is_malloced = table != mp->ma_smalltable;
+
+    /* This is delicate.  During the process of clearing the dict,
+     * decrefs can cause the dict to mutate.  To avoid fatal confusion
+     * (voice of experience), we have to make the dict empty before
+     * clearing the slots, and never refer to anything via mp->xxx while
+     * clearing.
+     */
+    fill = mp->ma_fill;
+    if (table_is_malloced)
+        EMPTY_TO_MINSIZE(mp);
+
+    else if (fill > 0) {
+        /* It's a small table with something that needs to be cleared.
+         * Afraid the only safe way is to copy the dict entries into
+         * another small table first.
+         */
+        memcpy(small_copy, table, sizeof(small_copy));
+        table = small_copy;
+        EMPTY_TO_MINSIZE(mp);
+    }
+    /* else it's a small table that's already empty */
+
+    /* Now we can finally clear things.  If C had refcounts, we could
+     * assert that the refcount on table is 1 now, i.e. that this function
+     * has unique access to it, so decref side-effects can't alter it.
+     */
+    for (ep = table; fill > 0; ++ep) {
+#ifdef Py_DEBUG
+        assert(i < n);
+        ++i;
+#endif
+        if (ep->me_key) {
+            --fill;
+            Py_DECREF(ep->me_key);
+            Py_XDECREF(ep->me_value);
+        }
+#ifdef Py_DEBUG
+        else
+            assert(ep->me_value == NULL);
+#endif
+    }
+
+    if (table_is_malloced)
+        PyMem_DEL(table);
+}
+
+/*
+ * Iterate over a dict.  Use like so:
+ *
+ *     Py_ssize_t i;
+ *     PyObject *key, *value;
+ *     i = 0;   # important!  i should not otherwise be changed by you
+ *     while (PyDict_Next(yourdict, &i, &key, &value)) {
+ *              Refer to borrowed references in key and value.
+ *     }
+ *
+ * CAUTION:  In general, it isn't safe to use PyDict_Next in a loop that
+ * mutates the dict.  One exception:  it is safe if the loop merely changes
+ * the values associated with the keys (but doesn't insert new keys or
+ * delete keys), via PyDict_SetItem().
+ */
+int
+PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t mask;
+    register PyDictEntry *ep;
+
+    if (!PyDict_Check(op))
+        return 0;
+    i = *ppos;
+    if (i < 0)
+        return 0;
+    ep = ((PyDictObject *)op)->ma_table;
+    mask = ((PyDictObject *)op)->ma_mask;
+    while (i <= mask && ep[i].me_value == NULL)
+        i++;
+    *ppos = i+1;
+    if (i > mask)
+        return 0;
+    if (pkey)
+        *pkey = ep[i].me_key;
+    if (pvalue)
+        *pvalue = ep[i].me_value;
+    return 1;
+}
+
+/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/
+int
+_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t mask;
+    register PyDictEntry *ep;
+
+    if (!PyDict_Check(op))
+        return 0;
+    i = *ppos;
+    if (i < 0)
+        return 0;
+    ep = ((PyDictObject *)op)->ma_table;
+    mask = ((PyDictObject *)op)->ma_mask;
+    while (i <= mask && ep[i].me_value == NULL)
+        i++;
+    *ppos = i+1;
+    if (i > mask)
+        return 0;
+    *phash = (long)(ep[i].me_hash);
+    if (pkey)
+        *pkey = ep[i].me_key;
+    if (pvalue)
+        *pvalue = ep[i].me_value;
+    return 1;
+}
+
+/* Methods */
+
+static void
+dict_dealloc(register PyDictObject *mp)
+{
+    register PyDictEntry *ep;
+    Py_ssize_t fill = mp->ma_fill;
+    PyObject_GC_UnTrack(mp);
+    Py_TRASHCAN_SAFE_BEGIN(mp)
+    for (ep = mp->ma_table; fill > 0; ep++) {
+        if (ep->me_key) {
+            --fill;
+            Py_DECREF(ep->me_key);
+            Py_XDECREF(ep->me_value);
+        }
+    }
+    if (mp->ma_table != mp->ma_smalltable)
+        PyMem_DEL(mp->ma_table);
+    if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
+        free_list[numfree++] = mp;
+    else
+        Py_TYPE(mp)->tp_free((PyObject *)mp);
+    Py_TRASHCAN_SAFE_END(mp)
+}
+
+static int
+dict_print(register PyDictObject *mp, register FILE *fp, register int flags)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t any;
+    int status;
+
+    status = Py_ReprEnter((PyObject*)mp);
+    if (status != 0) {
+        if (status < 0)
+            return status;
+        Py_BEGIN_ALLOW_THREADS
+        fprintf(fp, "{...}");
+        Py_END_ALLOW_THREADS
+        return 0;
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "{");
+    Py_END_ALLOW_THREADS
+    any = 0;
+    for (i = 0; i <= mp->ma_mask; i++) {
+        PyDictEntry *ep = mp->ma_table + i;
+        PyObject *pvalue = ep->me_value;
+        if (pvalue != NULL) {
+            /* Prevent PyObject_Repr from deleting value during
+               key format */
+            Py_INCREF(pvalue);
+            if (any++ > 0) {
+                Py_BEGIN_ALLOW_THREADS
+                fprintf(fp, ", ");
+                Py_END_ALLOW_THREADS
+            }
+            if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) {
+                Py_DECREF(pvalue);
+                Py_ReprLeave((PyObject*)mp);
+                return -1;
+            }
+            Py_BEGIN_ALLOW_THREADS
+            fprintf(fp, ": ");
+            Py_END_ALLOW_THREADS
+            if (PyObject_Print(pvalue, fp, 0) != 0) {
+                Py_DECREF(pvalue);
+                Py_ReprLeave((PyObject*)mp);
+                return -1;
+            }
+            Py_DECREF(pvalue);
+        }
+    }
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "}");
+    Py_END_ALLOW_THREADS
+    Py_ReprLeave((PyObject*)mp);
+    return 0;
+}
+
+static PyObject *
+dict_repr(PyDictObject *mp)
+{
+    Py_ssize_t i;
+    PyObject *s, *temp, *colon = NULL;
+    PyObject *pieces = NULL, *result = NULL;
+    PyObject *key, *value;
+
+    i = Py_ReprEnter((PyObject *)mp);
+    if (i != 0) {
+        return i > 0 ? PyString_FromString("{...}") : NULL;
+    }
+
+    if (mp->ma_used == 0) {
+        result = PyString_FromString("{}");
+        goto Done;
+    }
+
+    pieces = PyList_New(0);
+    if (pieces == NULL)
+        goto Done;
+
+    colon = PyString_FromString(": ");
+    if (colon == NULL)
+        goto Done;
+
+    /* Do repr() on each key+value pair, and insert ": " between them.
+       Note that repr may mutate the dict. */
+    i = 0;
+    while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
+        int status;
+        /* Prevent repr from deleting value during key format. */
+        Py_INCREF(value);
+        s = PyObject_Repr(key);
+        PyString_Concat(&s, colon);
+        PyString_ConcatAndDel(&s, PyObject_Repr(value));
+        Py_DECREF(value);
+        if (s == NULL)
+            goto Done;
+        status = PyList_Append(pieces, s);
+        Py_DECREF(s);  /* append created a new ref */
+        if (status < 0)
+            goto Done;
+    }
+
+    /* Add "{}" decorations to the first and last items. */
+    assert(PyList_GET_SIZE(pieces) > 0);
+    s = PyString_FromString("{");
+    if (s == NULL)
+        goto Done;
+    temp = PyList_GET_ITEM(pieces, 0);
+    PyString_ConcatAndDel(&s, temp);
+    PyList_SET_ITEM(pieces, 0, s);
+    if (s == NULL)
+        goto Done;
+
+    s = PyString_FromString("}");
+    if (s == NULL)
+        goto Done;
+    temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
+    PyString_ConcatAndDel(&temp, s);
+    PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
+    if (temp == NULL)
+        goto Done;
+
+    /* Paste them all together with ", " between. */
+    s = PyString_FromString(", ");
+    if (s == NULL)
+        goto Done;
+    result = _PyString_Join(s, pieces);
+    Py_DECREF(s);
+
+Done:
+    Py_XDECREF(pieces);
+    Py_XDECREF(colon);
+    Py_ReprLeave((PyObject *)mp);
+    return result;
+}
+
+static Py_ssize_t
+dict_length(PyDictObject *mp)
+{
+    return mp->ma_used;
+}
+
+static PyObject *
+dict_subscript(PyDictObject *mp, register PyObject *key)
+{
+    PyObject *v;
+    long hash;
+    PyDictEntry *ep;
+    assert(mp->ma_table != NULL);
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return NULL;
+    }
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL)
+        return NULL;
+    v = ep->me_value;
+    if (v == NULL) {
+        if (!PyDict_CheckExact(mp)) {
+            /* Look up __missing__ method if we're a subclass. */
+            PyObject *missing, *res;
+            static PyObject *missing_str = NULL;
+            missing = _PyObject_LookupSpecial((PyObject *)mp,
+                                              "__missing__",
+                                              &missing_str);
+            if (missing != NULL) {
+                res = PyObject_CallFunctionObjArgs(missing,
+                                                   key, NULL);
+                Py_DECREF(missing);
+                return res;
+            }
+            else if (PyErr_Occurred())
+                return NULL;
+        }
+        set_key_error(key);
+        return NULL;
+    }
+    else
+        Py_INCREF(v);
+    return v;
+}
+
+static int
+dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
+{
+    if (w == NULL)
+        return PyDict_DelItem((PyObject *)mp, v);
+    else
+        return PyDict_SetItem((PyObject *)mp, v, w);
+}
+
+static PyMappingMethods dict_as_mapping = {
+    (lenfunc)dict_length, /*mp_length*/
+    (binaryfunc)dict_subscript, /*mp_subscript*/
+    (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
+};
+
+static PyObject *
+dict_keys(register PyDictObject *mp)
+{
+    register PyObject *v;
+    register Py_ssize_t i, j;
+    PyDictEntry *ep;
+    Py_ssize_t mask, n;
+
+  again:
+    n = mp->ma_used;
+    v = PyList_New(n);
+    if (v == NULL)
+        return NULL;
+    if (n != mp->ma_used) {
+        /* Durnit.  The allocations caused the dict to resize.
+         * Just start over, this shouldn't normally happen.
+         */
+        Py_DECREF(v);
+        goto again;
+    }
+    ep = mp->ma_table;
+    mask = mp->ma_mask;
+    for (i = 0, j = 0; i <= mask; i++) {
+        if (ep[i].me_value != NULL) {
+            PyObject *key = ep[i].me_key;
+            Py_INCREF(key);
+            PyList_SET_ITEM(v, j, key);
+            j++;
+        }
+    }
+    assert(j == n);
+    return v;
+}
+
+static PyObject *
+dict_values(register PyDictObject *mp)
+{
+    register PyObject *v;
+    register Py_ssize_t i, j;
+    PyDictEntry *ep;
+    Py_ssize_t mask, n;
+
+  again:
+    n = mp->ma_used;
+    v = PyList_New(n);
+    if (v == NULL)
+        return NULL;
+    if (n != mp->ma_used) {
+        /* Durnit.  The allocations caused the dict to resize.
+         * Just start over, this shouldn't normally happen.
+         */
+        Py_DECREF(v);
+        goto again;
+    }
+    ep = mp->ma_table;
+    mask = mp->ma_mask;
+    for (i = 0, j = 0; i <= mask; i++) {
+        if (ep[i].me_value != NULL) {
+            PyObject *value = ep[i].me_value;
+            Py_INCREF(value);
+            PyList_SET_ITEM(v, j, value);
+            j++;
+        }
+    }
+    assert(j == n);
+    return v;
+}
+
+static PyObject *
+dict_items(register PyDictObject *mp)
+{
+    register PyObject *v;
+    register Py_ssize_t i, j, n;
+    Py_ssize_t mask;
+    PyObject *item, *key, *value;
+    PyDictEntry *ep;
+
+    /* Preallocate the list of tuples, to avoid allocations during
+     * the loop over the items, which could trigger GC, which
+     * could resize the dict. :-(
+     */
+  again:
+    n = mp->ma_used;
+    v = PyList_New(n);
+    if (v == NULL)
+        return NULL;
+    for (i = 0; i < n; i++) {
+        item = PyTuple_New(2);
+        if (item == NULL) {
+            Py_DECREF(v);
+            return NULL;
+        }
+        PyList_SET_ITEM(v, i, item);
+    }
+    if (n != mp->ma_used) {
+        /* Durnit.  The allocations caused the dict to resize.
+         * Just start over, this shouldn't normally happen.
+         */
+        Py_DECREF(v);
+        goto again;
+    }
+    /* Nothing we do below makes any function calls. */
+    ep = mp->ma_table;
+    mask = mp->ma_mask;
+    for (i = 0, j = 0; i <= mask; i++) {
+        if ((value=ep[i].me_value) != NULL) {
+            key = ep[i].me_key;
+            item = PyList_GET_ITEM(v, j);
+            Py_INCREF(key);
+            PyTuple_SET_ITEM(item, 0, key);
+            Py_INCREF(value);
+            PyTuple_SET_ITEM(item, 1, value);
+            j++;
+        }
+    }
+    assert(j == n);
+    return v;
+}
+
+static PyObject *
+dict_fromkeys(PyObject *cls, PyObject *args)
+{
+    PyObject *seq;
+    PyObject *value = Py_None;
+    PyObject *it;       /* iter(seq) */
+    PyObject *key;
+    PyObject *d;
+    int status;
+
+    if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value))
+        return NULL;
+
+    d = PyObject_CallObject(cls, NULL);
+    if (d == NULL)
+        return NULL;
+
+    if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
+        if (PyDict_CheckExact(seq)) {
+            PyDictObject *mp = (PyDictObject *)d;
+            PyObject *oldvalue;
+            Py_ssize_t pos = 0;
+            PyObject *key;
+            long hash;
+
+            if (dictresize(mp, Py_SIZE(seq))) {
+                Py_DECREF(d);
+                return NULL;
+            }
+
+            while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) {
+                Py_INCREF(key);
+                Py_INCREF(value);
+                if (insertdict(mp, key, hash, value)) {
+                    Py_DECREF(d);
+                    return NULL;
+                }
+            }
+            return d;
+        }
+        if (PyAnySet_CheckExact(seq)) {
+            PyDictObject *mp = (PyDictObject *)d;
+            Py_ssize_t pos = 0;
+            PyObject *key;
+            long hash;
+
+            if (dictresize(mp, PySet_GET_SIZE(seq))) {
+                Py_DECREF(d);
+                return NULL;
+            }
+
+            while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
+                Py_INCREF(key);
+                Py_INCREF(value);
+                if (insertdict(mp, key, hash, value)) {
+                    Py_DECREF(d);
+                    return NULL;
+                }
+            }
+            return d;
+        }
+    }
+
+    it = PyObject_GetIter(seq);
+    if (it == NULL){
+        Py_DECREF(d);
+        return NULL;
+    }
+
+    if (PyDict_CheckExact(d)) {
+        while ((key = PyIter_Next(it)) != NULL) {
+            status = PyDict_SetItem(d, key, value);
+            Py_DECREF(key);
+            if (status < 0)
+                goto Fail;
+        }
+    } else {
+        while ((key = PyIter_Next(it)) != NULL) {
+            status = PyObject_SetItem(d, key, value);
+            Py_DECREF(key);
+            if (status < 0)
+                goto Fail;
+        }
+    }
+
+    if (PyErr_Occurred())
+        goto Fail;
+    Py_DECREF(it);
+    return d;
+
+Fail:
+    Py_DECREF(it);
+    Py_DECREF(d);
+    return NULL;
+}
+
+static int
+dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methname)
+{
+    PyObject *arg = NULL;
+    int result = 0;
+
+    if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg))
+        result = -1;
+
+    else if (arg != NULL) {
+        if (PyObject_HasAttrString(arg, "keys"))
+            result = PyDict_Merge(self, arg, 1);
+        else
+            result = PyDict_MergeFromSeq2(self, arg, 1);
+    }
+    if (result == 0 && kwds != NULL)
+        result = PyDict_Merge(self, kwds, 1);
+    return result;
+}
+
+static PyObject *
+dict_update(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    if (dict_update_common(self, args, kwds, "update") != -1)
+        Py_RETURN_NONE;
+    return NULL;
+}
+
+/* Update unconditionally replaces existing items.
+   Merge has a 3rd argument 'override'; if set, it acts like Update,
+   otherwise it leaves existing items unchanged.
+
+   PyDict_{Update,Merge} update/merge from a mapping object.
+
+   PyDict_MergeFromSeq2 updates/merges from any iterable object
+   producing iterable objects of length 2.
+*/
+
+int
+PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
+{
+    PyObject *it;       /* iter(seq2) */
+    Py_ssize_t i;       /* index into seq2 of current element */
+    PyObject *item;     /* seq2[i] */
+    PyObject *fast;     /* item as a 2-tuple or 2-list */
+
+    assert(d != NULL);
+    assert(PyDict_Check(d));
+    assert(seq2 != NULL);
+
+    it = PyObject_GetIter(seq2);
+    if (it == NULL)
+        return -1;
+
+    for (i = 0; ; ++i) {
+        PyObject *key, *value;
+        Py_ssize_t n;
+
+        fast = NULL;
+        item = PyIter_Next(it);
+        if (item == NULL) {
+            if (PyErr_Occurred())
+                goto Fail;
+            break;
+        }
+
+        /* Convert item to sequence, and verify length 2. */
+        fast = PySequence_Fast(item, "");
+        if (fast == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_TypeError))
+                PyErr_Format(PyExc_TypeError,
+                    "cannot convert dictionary update "
+                    "sequence element #%zd to a sequence",
+                    i);
+            goto Fail;
+        }
+        n = PySequence_Fast_GET_SIZE(fast);
+        if (n != 2) {
+            PyErr_Format(PyExc_ValueError,
+                         "dictionary update sequence element #%zd "
+                         "has length %zd; 2 is required",
+                         i, n);
+            goto Fail;
+        }
+
+        /* Update/merge with this (key, value) pair. */
+        key = PySequence_Fast_GET_ITEM(fast, 0);
+        value = PySequence_Fast_GET_ITEM(fast, 1);
+        if (override || PyDict_GetItem(d, key) == NULL) {
+            int status = PyDict_SetItem(d, key, value);
+            if (status < 0)
+                goto Fail;
+        }
+        Py_DECREF(fast);
+        Py_DECREF(item);
+    }
+
+    i = 0;
+    goto Return;
+Fail:
+    Py_XDECREF(item);
+    Py_XDECREF(fast);
+    i = -1;
+Return:
+    Py_DECREF(it);
+    return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
+}
+
+int
+PyDict_Update(PyObject *a, PyObject *b)
+{
+    return PyDict_Merge(a, b, 1);
+}
+
+int
+PyDict_Merge(PyObject *a, PyObject *b, int override)
+{
+    register PyDictObject *mp, *other;
+    register Py_ssize_t i;
+    PyDictEntry *entry;
+
+    /* We accept for the argument either a concrete dictionary object,
+     * or an abstract "mapping" object.  For the former, we can do
+     * things quite efficiently.  For the latter, we only require that
+     * PyMapping_Keys() and PyObject_GetItem() be supported.
+     */
+    if (a == NULL || !PyDict_Check(a) || b == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    mp = (PyDictObject*)a;
+    if (PyDict_Check(b)) {
+        other = (PyDictObject*)b;
+        if (other == mp || other->ma_used == 0)
+            /* a.update(a) or a.update({}); nothing to do */
+            return 0;
+        if (mp->ma_used == 0)
+            /* Since the target dict is empty, PyDict_GetItem()
+             * always returns NULL.  Setting override to 1
+             * skips the unnecessary test.
+             */
+            override = 1;
+        /* Do one big resize at the start, rather than
+         * incrementally resizing as we insert new items.  Expect
+         * that there will be no (or few) overlapping keys.
+         */
+        if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
+           if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0)
+               return -1;
+        }
+        for (i = 0; i <= other->ma_mask; i++) {
+            entry = &other->ma_table[i];
+            if (entry->me_value != NULL &&
+                (override ||
+                 PyDict_GetItem(a, entry->me_key) == NULL)) {
+                Py_INCREF(entry->me_key);
+                Py_INCREF(entry->me_value);
+                if (insertdict(mp, entry->me_key,
+                               (long)entry->me_hash,
+                               entry->me_value) != 0)
+                    return -1;
+            }
+        }
+    }
+    else {
+        /* Do it the generic, slower way */
+        PyObject *keys = PyMapping_Keys(b);
+        PyObject *iter;
+        PyObject *key, *value;
+        int status;
+
+        if (keys == NULL)
+            /* Docstring says this is equivalent to E.keys() so
+             * if E doesn't have a .keys() method we want
+             * AttributeError to percolate up.  Might as well
+             * do the same for any other error.
+             */
+            return -1;
+
+        iter = PyObject_GetIter(keys);
+        Py_DECREF(keys);
+        if (iter == NULL)
+            return -1;
+
+        for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
+            if (!override && PyDict_GetItem(a, key) != NULL) {
+                Py_DECREF(key);
+                continue;
+            }
+            value = PyObject_GetItem(b, key);
+            if (value == NULL) {
+                Py_DECREF(iter);
+                Py_DECREF(key);
+                return -1;
+            }
+            status = PyDict_SetItem(a, key, value);
+            Py_DECREF(key);
+            Py_DECREF(value);
+            if (status < 0) {
+                Py_DECREF(iter);
+                return -1;
+            }
+        }
+        Py_DECREF(iter);
+        if (PyErr_Occurred())
+            /* Iterator completed, via error */
+            return -1;
+    }
+    return 0;
+}
+
+static PyObject *
+dict_copy(register PyDictObject *mp)
+{
+    return PyDict_Copy((PyObject*)mp);
+}
+
+PyObject *
+PyDict_Copy(PyObject *o)
+{
+    PyObject *copy;
+
+    if (o == NULL || !PyDict_Check(o)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    copy = PyDict_New();
+    if (copy == NULL)
+        return NULL;
+    if (PyDict_Merge(copy, o, 1) == 0)
+        return copy;
+    Py_DECREF(copy);
+    return NULL;
+}
+
+Py_ssize_t
+PyDict_Size(PyObject *mp)
+{
+    if (mp == NULL || !PyDict_Check(mp)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return ((PyDictObject *)mp)->ma_used;
+}
+
+PyObject *
+PyDict_Keys(PyObject *mp)
+{
+    if (mp == NULL || !PyDict_Check(mp)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return dict_keys((PyDictObject *)mp);
+}
+
+PyObject *
+PyDict_Values(PyObject *mp)
+{
+    if (mp == NULL || !PyDict_Check(mp)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return dict_values((PyDictObject *)mp);
+}
+
+PyObject *
+PyDict_Items(PyObject *mp)
+{
+    if (mp == NULL || !PyDict_Check(mp)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return dict_items((PyDictObject *)mp);
+}
+
+/* Subroutine which returns the smallest key in a for which b's value
+   is different or absent.  The value is returned too, through the
+   pval argument.  Both are NULL if no key in a is found for which b's status
+   differs.  The refcounts on (and only on) non-NULL *pval and function return
+   values must be decremented by the caller (characterize() increments them
+   to ensure that mutating comparison and PyDict_GetItem calls can't delete
+   them before the caller is done looking at them). */
+
+static PyObject *
+characterize(PyDictObject *a, PyDictObject *b, PyObject **pval)
+{
+    PyObject *akey = NULL; /* smallest key in a s.t. a[akey] != b[akey] */
+    PyObject *aval = NULL; /* a[akey] */
+    Py_ssize_t i;
+    int cmp;
+
+    for (i = 0; i <= a->ma_mask; i++) {
+        PyObject *thiskey, *thisaval, *thisbval;
+        if (a->ma_table[i].me_value == NULL)
+            continue;
+        thiskey = a->ma_table[i].me_key;
+        Py_INCREF(thiskey);  /* keep alive across compares */
+        if (akey != NULL) {
+            cmp = PyObject_RichCompareBool(akey, thiskey, Py_LT);
+            if (cmp < 0) {
+                Py_DECREF(thiskey);
+                goto Fail;
+            }
+            if (cmp > 0 ||
+                i > a->ma_mask ||
+                a->ma_table[i].me_value == NULL)
+            {
+                /* Not the *smallest* a key; or maybe it is
+                 * but the compare shrunk the dict so we can't
+                 * find its associated value anymore; or
+                 * maybe it is but the compare deleted the
+                 * a[thiskey] entry.
+                 */
+                Py_DECREF(thiskey);
+                continue;
+            }
+        }
+
+        /* Compare a[thiskey] to b[thiskey]; cmp <- true iff equal. */
+        thisaval = a->ma_table[i].me_value;
+        assert(thisaval);
+        Py_INCREF(thisaval);   /* keep alive */
+        thisbval = PyDict_GetItem((PyObject *)b, thiskey);
+        if (thisbval == NULL)
+            cmp = 0;
+        else {
+            /* both dicts have thiskey:  same values? */
+            cmp = PyObject_RichCompareBool(
+                                    thisaval, thisbval, Py_EQ);
+            if (cmp < 0) {
+                Py_DECREF(thiskey);
+                Py_DECREF(thisaval);
+                goto Fail;
+            }
+        }
+        if (cmp == 0) {
+            /* New winner. */
+            Py_XDECREF(akey);
+            Py_XDECREF(aval);
+            akey = thiskey;
+            aval = thisaval;
+        }
+        else {
+            Py_DECREF(thiskey);
+            Py_DECREF(thisaval);
+        }
+    }
+    *pval = aval;
+    return akey;
+
+Fail:
+    Py_XDECREF(akey);
+    Py_XDECREF(aval);
+    *pval = NULL;
+    return NULL;
+}
+
+static int
+dict_compare(PyDictObject *a, PyDictObject *b)
+{
+    PyObject *adiff, *bdiff, *aval, *bval;
+    int res;
+
+    /* Compare lengths first */
+    if (a->ma_used < b->ma_used)
+        return -1;              /* a is shorter */
+    else if (a->ma_used > b->ma_used)
+        return 1;               /* b is shorter */
+
+    /* Same length -- check all keys */
+    bdiff = bval = NULL;
+    adiff = characterize(a, b, &aval);
+    if (adiff == NULL) {
+        assert(!aval);
+        /* Either an error, or a is a subset with the same length so
+         * must be equal.
+         */
+        res = PyErr_Occurred() ? -1 : 0;
+        goto Finished;
+    }
+    bdiff = characterize(b, a, &bval);
+    if (bdiff == NULL && PyErr_Occurred()) {
+        assert(!bval);
+        res = -1;
+        goto Finished;
+    }
+    res = 0;
+    if (bdiff) {
+        /* bdiff == NULL "should be" impossible now, but perhaps
+         * the last comparison done by the characterize() on a had
+         * the side effect of making the dicts equal!
+         */
+        res = PyObject_Compare(adiff, bdiff);
+    }
+    if (res == 0 && bval != NULL)
+        res = PyObject_Compare(aval, bval);
+
+Finished:
+    Py_XDECREF(adiff);
+    Py_XDECREF(bdiff);
+    Py_XDECREF(aval);
+    Py_XDECREF(bval);
+    return res;
+}
+
+/* Return 1 if dicts equal, 0 if not, -1 if error.
+ * Gets out as soon as any difference is detected.
+ * Uses only Py_EQ comparison.
+ */
+static int
+dict_equal(PyDictObject *a, PyDictObject *b)
+{
+    Py_ssize_t i;
+
+    if (a->ma_used != b->ma_used)
+        /* can't be equal if # of entries differ */
+        return 0;
+
+    /* Same # of entries -- check all of 'em.  Exit early on any diff. */
+    for (i = 0; i <= a->ma_mask; i++) {
+        PyObject *aval = a->ma_table[i].me_value;
+        if (aval != NULL) {
+            int cmp;
+            PyObject *bval;
+            PyObject *key = a->ma_table[i].me_key;
+            /* temporarily bump aval's refcount to ensure it stays
+               alive until we're done with it */
+            Py_INCREF(aval);
+            /* ditto for key */
+            Py_INCREF(key);
+            bval = PyDict_GetItem((PyObject *)b, key);
+            Py_DECREF(key);
+            if (bval == NULL) {
+                Py_DECREF(aval);
+                return 0;
+            }
+            cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
+            Py_DECREF(aval);
+            if (cmp <= 0)  /* error or not equal */
+                return cmp;
+        }
+    }
+    return 1;
+ }
+
+static PyObject *
+dict_richcompare(PyObject *v, PyObject *w, int op)
+{
+    int cmp;
+    PyObject *res;
+
+    if (!PyDict_Check(v) || !PyDict_Check(w)) {
+        res = Py_NotImplemented;
+    }
+    else if (op == Py_EQ || op == Py_NE) {
+        cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
+        if (cmp < 0)
+            return NULL;
+        res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
+    }
+    else {
+        /* Py3K warning if comparison isn't == or !=  */
+        if (PyErr_WarnPy3k("dict inequality comparisons not supported "
+                           "in 3.x", 1) < 0) {
+            return NULL;
+        }
+        res = Py_NotImplemented;
+    }
+    Py_INCREF(res);
+    return res;
+ }
+
+static PyObject *
+dict_contains(register PyDictObject *mp, PyObject *key)
+{
+    long hash;
+    PyDictEntry *ep;
+
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return NULL;
+    }
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL)
+        return NULL;
+    return PyBool_FromLong(ep->me_value != NULL);
+}
+
+static PyObject *
+dict_has_key(register PyDictObject *mp, PyObject *key)
+{
+    if (PyErr_WarnPy3k("dict.has_key() not supported in 3.x; "
+                       "use the in operator", 1) < 0)
+        return NULL;
+    return dict_contains(mp, key);
+}
+
+static PyObject *
+dict_get(register PyDictObject *mp, PyObject *args)
+{
+    PyObject *key;
+    PyObject *failobj = Py_None;
+    PyObject *val = NULL;
+    long hash;
+    PyDictEntry *ep;
+
+    if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
+        return NULL;
+
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return NULL;
+    }
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL)
+        return NULL;
+    val = ep->me_value;
+    if (val == NULL)
+        val = failobj;
+    Py_INCREF(val);
+    return val;
+}
+
+
+static PyObject *
+dict_setdefault(register PyDictObject *mp, PyObject *args)
+{
+    PyObject *key;
+    PyObject *failobj = Py_None;
+    PyObject *val = NULL;
+    long hash;
+    PyDictEntry *ep;
+
+    if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
+        return NULL;
+
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return NULL;
+    }
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL)
+        return NULL;
+    val = ep->me_value;
+    if (val == NULL) {
+        if (dict_set_item_by_hash_or_entry((PyObject*)mp, key, hash, ep,
+                                           failobj) == 0)
+            val = failobj;
+    }
+    Py_XINCREF(val);
+    return val;
+}
+
+
+static PyObject *
+dict_clear(register PyDictObject *mp)
+{
+    PyDict_Clear((PyObject *)mp);
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+dict_pop(PyDictObject *mp, PyObject *args)
+{
+    long hash;
+    PyDictEntry *ep;
+    PyObject *old_value, *old_key;
+    PyObject *key, *deflt = NULL;
+
+    if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt))
+        return NULL;
+    if (mp->ma_used == 0) {
+        if (deflt) {
+            Py_INCREF(deflt);
+            return deflt;
+        }
+        set_key_error(key);
+        return NULL;
+    }
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return NULL;
+    }
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL)
+        return NULL;
+    if (ep->me_value == NULL) {
+        if (deflt) {
+            Py_INCREF(deflt);
+            return deflt;
+        }
+        set_key_error(key);
+        return NULL;
+    }
+    old_key = ep->me_key;
+    Py_INCREF(dummy);
+    ep->me_key = dummy;
+    old_value = ep->me_value;
+    ep->me_value = NULL;
+    mp->ma_used--;
+    Py_DECREF(old_key);
+    return old_value;
+}
+
+static PyObject *
+dict_popitem(PyDictObject *mp)
+{
+    Py_ssize_t i = 0;
+    PyDictEntry *ep;
+    PyObject *res;
+
+    /* Allocate the result tuple before checking the size.  Believe it
+     * or not, this allocation could trigger a garbage collection which
+     * could empty the dict, so if we checked the size first and that
+     * happened, the result would be an infinite loop (searching for an
+     * entry that no longer exists).  Note that the usual popitem()
+     * idiom is "while d: k, v = d.popitem()". so needing to throw the
+     * tuple away if the dict *is* empty isn't a significant
+     * inefficiency -- possible, but unlikely in practice.
+     */
+    res = PyTuple_New(2);
+    if (res == NULL)
+        return NULL;
+    if (mp->ma_used == 0) {
+        Py_DECREF(res);
+        PyErr_SetString(PyExc_KeyError,
+                        "popitem(): dictionary is empty");
+        return NULL;
+    }
+    /* Set ep to "the first" dict entry with a value.  We abuse the hash
+     * field of slot 0 to hold a search finger:
+     * If slot 0 has a value, use slot 0.
+     * Else slot 0 is being used to hold a search finger,
+     * and we use its hash value as the first index to look.
+     */
+    ep = &mp->ma_table[0];
+    if (ep->me_value == NULL) {
+        i = ep->me_hash;
+        /* The hash field may be a real hash value, or it may be a
+         * legit search finger, or it may be a once-legit search
+         * finger that's out of bounds now because it wrapped around
+         * or the table shrunk -- simply make sure it's in bounds now.
+         */
+        if (i > mp->ma_mask || i < 1)
+            i = 1;              /* skip slot 0 */
+        while ((ep = &mp->ma_table[i])->me_value == NULL) {
+            i++;
+            if (i > mp->ma_mask)
+                i = 1;
+        }
+    }
+    PyTuple_SET_ITEM(res, 0, ep->me_key);
+    PyTuple_SET_ITEM(res, 1, ep->me_value);
+    Py_INCREF(dummy);
+    ep->me_key = dummy;
+    ep->me_value = NULL;
+    mp->ma_used--;
+    assert(mp->ma_table[0].me_value == NULL);
+    mp->ma_table[0].me_hash = i + 1;  /* next place to start */
+    return res;
+}
+
+static int
+dict_traverse(PyObject *op, visitproc visit, void *arg)
+{
+    Py_ssize_t i = 0;
+    PyObject *pk;
+    PyObject *pv;
+
+    while (PyDict_Next(op, &i, &pk, &pv)) {
+        Py_VISIT(pk);
+        Py_VISIT(pv);
+    }
+    return 0;
+}
+
+static int
+dict_tp_clear(PyObject *op)
+{
+    PyDict_Clear(op);
+    return 0;
+}
+
+
+extern PyTypeObject PyDictIterKey_Type; /* Forward */
+extern PyTypeObject PyDictIterValue_Type; /* Forward */
+extern PyTypeObject PyDictIterItem_Type; /* Forward */
+static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
+
+static PyObject *
+dict_iterkeys(PyDictObject *dict)
+{
+    return dictiter_new(dict, &PyDictIterKey_Type);
+}
+
+static PyObject *
+dict_itervalues(PyDictObject *dict)
+{
+    return dictiter_new(dict, &PyDictIterValue_Type);
+}
+
+static PyObject *
+dict_iteritems(PyDictObject *dict)
+{
+    return dictiter_new(dict, &PyDictIterItem_Type);
+}
+
+static PyObject *
+dict_sizeof(PyDictObject *mp)
+{
+    Py_ssize_t res;
+
+    res = sizeof(PyDictObject);
+    if (mp->ma_table != mp->ma_smalltable)
+        res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry);
+    return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(has_key__doc__,
+"D.has_key(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(contains__doc__,
+"D.__contains__(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
+
+PyDoc_STRVAR(sizeof__doc__,
+"D.__sizeof__() -> size of D in memory, in bytes");
+
+PyDoc_STRVAR(get__doc__,
+"D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.");
+
+PyDoc_STRVAR(setdefault_doc__,
+"D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D");
+
+PyDoc_STRVAR(pop__doc__,
+"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\
+If key is not found, d is returned if given, otherwise KeyError is raised");
+
+PyDoc_STRVAR(popitem__doc__,
+"D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\
+2-tuple; but raise KeyError if D is empty.");
+
+PyDoc_STRVAR(keys__doc__,
+"D.keys() -> list of D's keys");
+
+PyDoc_STRVAR(items__doc__,
+"D.items() -> list of D's (key, value) pairs, as 2-tuples");
+
+PyDoc_STRVAR(values__doc__,
+"D.values() -> list of D's values");
+
+PyDoc_STRVAR(update__doc__,
+"D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.\n"
+"If E present and has a .keys() method, does:     for k in E: D[k] = E[k]\n\
+If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v\n\
+In either case, this is followed by: for k in F: D[k] = F[k]");
+
+PyDoc_STRVAR(fromkeys__doc__,
+"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\
+v defaults to None.");
+
+PyDoc_STRVAR(clear__doc__,
+"D.clear() -> None.  Remove all items from D.");
+
+PyDoc_STRVAR(copy__doc__,
+"D.copy() -> a shallow copy of D");
+
+PyDoc_STRVAR(iterkeys__doc__,
+"D.iterkeys() -> an iterator over the keys of D");
+
+PyDoc_STRVAR(itervalues__doc__,
+"D.itervalues() -> an iterator over the values of D");
+
+PyDoc_STRVAR(iteritems__doc__,
+"D.iteritems() -> an iterator over the (key, value) items of D");
+
+/* Forward */
+static PyObject *dictkeys_new(PyObject *);
+static PyObject *dictitems_new(PyObject *);
+static PyObject *dictvalues_new(PyObject *);
+
+PyDoc_STRVAR(viewkeys__doc__,
+             "D.viewkeys() -> a set-like object providing a view on D's keys");
+PyDoc_STRVAR(viewitems__doc__,
+             "D.viewitems() -> a set-like object providing a view on D's items");
+PyDoc_STRVAR(viewvalues__doc__,
+             "D.viewvalues() -> an object providing a view on D's values");
+
+static PyMethodDef mapp_methods[] = {
+    {"__contains__",(PyCFunction)dict_contains,         METH_O | METH_COEXIST,
+     contains__doc__},
+    {"__getitem__", (PyCFunction)dict_subscript,        METH_O | METH_COEXIST,
+     getitem__doc__},
+    {"__sizeof__",      (PyCFunction)dict_sizeof,       METH_NOARGS,
+     sizeof__doc__},
+    {"has_key",         (PyCFunction)dict_has_key,      METH_O,
+     has_key__doc__},
+    {"get",         (PyCFunction)dict_get,          METH_VARARGS,
+     get__doc__},
+    {"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS,
+     setdefault_doc__},
+    {"pop",         (PyCFunction)dict_pop,          METH_VARARGS,
+     pop__doc__},
+    {"popitem",         (PyCFunction)dict_popitem,      METH_NOARGS,
+     popitem__doc__},
+    {"keys",            (PyCFunction)dict_keys,         METH_NOARGS,
+    keys__doc__},
+    {"items",           (PyCFunction)dict_items,        METH_NOARGS,
+     items__doc__},
+    {"values",          (PyCFunction)dict_values,       METH_NOARGS,
+     values__doc__},
+    {"viewkeys",        (PyCFunction)dictkeys_new,      METH_NOARGS,
+     viewkeys__doc__},
+    {"viewitems",       (PyCFunction)dictitems_new,     METH_NOARGS,
+     viewitems__doc__},
+    {"viewvalues",      (PyCFunction)dictvalues_new,    METH_NOARGS,
+     viewvalues__doc__},
+    {"update",          (PyCFunction)dict_update,       METH_VARARGS | METH_KEYWORDS,
+     update__doc__},
+    {"fromkeys",        (PyCFunction)dict_fromkeys,     METH_VARARGS | METH_CLASS,
+     fromkeys__doc__},
+    {"clear",           (PyCFunction)dict_clear,        METH_NOARGS,
+     clear__doc__},
+    {"copy",            (PyCFunction)dict_copy,         METH_NOARGS,
+     copy__doc__},
+    {"iterkeys",        (PyCFunction)dict_iterkeys,     METH_NOARGS,
+     iterkeys__doc__},
+    {"itervalues",      (PyCFunction)dict_itervalues,   METH_NOARGS,
+     itervalues__doc__},
+    {"iteritems",       (PyCFunction)dict_iteritems,    METH_NOARGS,
+     iteritems__doc__},
+    {NULL,              NULL}   /* sentinel */
+};
+
+/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
+int
+PyDict_Contains(PyObject *op, PyObject *key)
+{
+    long hash;
+    PyDictObject *mp = (PyDictObject *)op;
+    PyDictEntry *ep;
+
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return -1;
+    }
+    ep = (mp->ma_lookup)(mp, key, hash);
+    return ep == NULL ? -1 : (ep->me_value != NULL);
+}
+
+/* Internal version of PyDict_Contains used when the hash value is already known */
+int
+_PyDict_Contains(PyObject *op, PyObject *key, long hash)
+{
+    PyDictObject *mp = (PyDictObject *)op;
+    PyDictEntry *ep;
+
+    ep = (mp->ma_lookup)(mp, key, hash);
+    return ep == NULL ? -1 : (ep->me_value != NULL);
+}
+
+/* Hack to implement "key in dict" */
+static PySequenceMethods dict_as_sequence = {
+    0,                          /* sq_length */
+    0,                          /* sq_concat */
+    0,                          /* sq_repeat */
+    0,                          /* sq_item */
+    0,                          /* sq_slice */
+    0,                          /* sq_ass_item */
+    0,                          /* sq_ass_slice */
+    PyDict_Contains,            /* sq_contains */
+    0,                          /* sq_inplace_concat */
+    0,                          /* sq_inplace_repeat */
+};
+
+static PyObject *
+dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *self;
+
+    assert(type != NULL && type->tp_alloc != NULL);
+    self = type->tp_alloc(type, 0);
+    if (self != NULL) {
+        PyDictObject *d = (PyDictObject *)self;
+        /* It's guaranteed that tp->alloc zeroed out the struct. */
+        assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
+        INIT_NONZERO_DICT_SLOTS(d);
+        d->ma_lookup = lookdict_string;
+        /* The object has been implicitly tracked by tp_alloc */
+        if (type == &PyDict_Type)
+            _PyObject_GC_UNTRACK(d);
+#ifdef SHOW_CONVERSION_COUNTS
+        ++created;
+#endif
+#ifdef SHOW_TRACK_COUNT
+        if (_PyObject_GC_IS_TRACKED(d))
+            count_tracked++;
+        else
+            count_untracked++;
+#endif
+    }
+    return self;
+}
+
+static int
+dict_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    return dict_update_common(self, args, kwds, "dict");
+}
+
+static PyObject *
+dict_iter(PyDictObject *dict)
+{
+    return dictiter_new(dict, &PyDictIterKey_Type);
+}
+
+PyDoc_STRVAR(dictionary_doc,
+"dict() -> new empty dictionary\n"
+"dict(mapping) -> new dictionary initialized from a mapping object's\n"
+"    (key, value) pairs\n"
+"dict(iterable) -> new dictionary initialized as if via:\n"
+"    d = {}\n"
+"    for k, v in iterable:\n"
+"        d[k] = v\n"
+"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
+"    in the keyword argument list.  For example:  dict(one=1, two=2)");
+
+PyTypeObject PyDict_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dict",
+    sizeof(PyDictObject),
+    0,
+    (destructor)dict_dealloc,                   /* tp_dealloc */
+    (printfunc)dict_print,                      /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)dict_compare,                      /* tp_compare */
+    (reprfunc)dict_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    &dict_as_sequence,                          /* tp_as_sequence */
+    &dict_as_mapping,                           /* tp_as_mapping */
+    (hashfunc)PyObject_HashNotImplemented,      /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS,         /* tp_flags */
+    dictionary_doc,                             /* tp_doc */
+    dict_traverse,                              /* tp_traverse */
+    dict_tp_clear,                              /* tp_clear */
+    dict_richcompare,                           /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    (getiterfunc)dict_iter,                     /* tp_iter */
+    0,                                          /* tp_iternext */
+    mapp_methods,                               /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    dict_init,                                  /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    dict_new,                                   /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
+
+/* For backward compatibility with old dictionary interface */
+
+PyObject *
+PyDict_GetItemString(PyObject *v, const char *key)
+{
+    PyObject *kv, *rv;
+    kv = PyString_FromString(key);
+    if (kv == NULL)
+        return NULL;
+    rv = PyDict_GetItem(v, kv);
+    Py_DECREF(kv);
+    return rv;
+}
+
+int
+PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
+{
+    PyObject *kv;
+    int err;
+    kv = PyString_FromString(key);
+    if (kv == NULL)
+        return -1;
+    PyString_InternInPlace(&kv); /* XXX Should we really? */
+    err = PyDict_SetItem(v, kv, item);
+    Py_DECREF(kv);
+    return err;
+}
+
+int
+PyDict_DelItemString(PyObject *v, const char *key)
+{
+    PyObject *kv;
+    int err;
+    kv = PyString_FromString(key);
+    if (kv == NULL)
+        return -1;
+    err = PyDict_DelItem(v, kv);
+    Py_DECREF(kv);
+    return err;
+}
+
+/* Dictionary iterator types */
+
+typedef struct {
+    PyObject_HEAD
+    PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
+    Py_ssize_t di_used;
+    Py_ssize_t di_pos;
+    PyObject* di_result; /* reusable result tuple for iteritems */
+    Py_ssize_t len;
+} dictiterobject;
+
+static PyObject *
+dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
+{
+    dictiterobject *di;
+    di = PyObject_GC_New(dictiterobject, itertype);
+    if (di == NULL)
+        return NULL;
+    Py_INCREF(dict);
+    di->di_dict = dict;
+    di->di_used = dict->ma_used;
+    di->di_pos = 0;
+    di->len = dict->ma_used;
+    if (itertype == &PyDictIterItem_Type) {
+        di->di_result = PyTuple_Pack(2, Py_None, Py_None);
+        if (di->di_result == NULL) {
+            Py_DECREF(di);
+            return NULL;
+        }
+    }
+    else
+        di->di_result = NULL;
+    _PyObject_GC_TRACK(di);
+    return (PyObject *)di;
+}
+
+static void
+dictiter_dealloc(dictiterobject *di)
+{
+    Py_XDECREF(di->di_dict);
+    Py_XDECREF(di->di_result);
+    PyObject_GC_Del(di);
+}
+
+static int
+dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
+{
+    Py_VISIT(di->di_dict);
+    Py_VISIT(di->di_result);
+    return 0;
+}
+
+static PyObject *
+dictiter_len(dictiterobject *di)
+{
+    Py_ssize_t len = 0;
+    if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
+        len = di->len;
+    return PyInt_FromSize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dictiter_methods[] = {
+    {"__length_hint__", (PyCFunction)dictiter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyObject *dictiter_iternextkey(dictiterobject *di)
+{
+    PyObject *key;
+    register Py_ssize_t i, mask;
+    register PyDictEntry *ep;
+    PyDictObject *d = di->di_dict;
+
+    if (d == NULL)
+        return NULL;
+    assert (PyDict_Check(d));
+
+    if (di->di_used != d->ma_used) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "dictionary changed size during iteration");
+        di->di_used = -1; /* Make this state sticky */
+        return NULL;
+    }
+
+    i = di->di_pos;
+    if (i < 0)
+        goto fail;
+    ep = d->ma_table;
+    mask = d->ma_mask;
+    while (i <= mask && ep[i].me_value == NULL)
+        i++;
+    di->di_pos = i+1;
+    if (i > mask)
+        goto fail;
+    di->len--;
+    key = ep[i].me_key;
+    Py_INCREF(key);
+    return key;
+
+fail:
+    Py_DECREF(d);
+    di->di_dict = NULL;
+    return NULL;
+}
+
+PyTypeObject PyDictIterKey_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dictionary-keyiterator",                   /* tp_name */
+    sizeof(dictiterobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)dictiter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)dictiter_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)dictiter_iternextkey,         /* tp_iternext */
+    dictiter_methods,                           /* tp_methods */
+    0,
+};
+
+static PyObject *dictiter_iternextvalue(dictiterobject *di)
+{
+    PyObject *value;
+    register Py_ssize_t i, mask;
+    register PyDictEntry *ep;
+    PyDictObject *d = di->di_dict;
+
+    if (d == NULL)
+        return NULL;
+    assert (PyDict_Check(d));
+
+    if (di->di_used != d->ma_used) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "dictionary changed size during iteration");
+        di->di_used = -1; /* Make this state sticky */
+        return NULL;
+    }
+
+    i = di->di_pos;
+    mask = d->ma_mask;
+    if (i < 0 || i > mask)
+        goto fail;
+    ep = d->ma_table;
+    while ((value=ep[i].me_value) == NULL) {
+        i++;
+        if (i > mask)
+            goto fail;
+    }
+    di->di_pos = i+1;
+    di->len--;
+    Py_INCREF(value);
+    return value;
+
+fail:
+    Py_DECREF(d);
+    di->di_dict = NULL;
+    return NULL;
+}
+
+PyTypeObject PyDictIterValue_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dictionary-valueiterator",                 /* tp_name */
+    sizeof(dictiterobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)dictiter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)dictiter_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)dictiter_iternextvalue,       /* tp_iternext */
+    dictiter_methods,                           /* tp_methods */
+    0,
+};
+
+static PyObject *dictiter_iternextitem(dictiterobject *di)
+{
+    PyObject *key, *value, *result = di->di_result;
+    register Py_ssize_t i, mask;
+    register PyDictEntry *ep;
+    PyDictObject *d = di->di_dict;
+
+    if (d == NULL)
+        return NULL;
+    assert (PyDict_Check(d));
+
+    if (di->di_used != d->ma_used) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "dictionary changed size during iteration");
+        di->di_used = -1; /* Make this state sticky */
+        return NULL;
+    }
+
+    i = di->di_pos;
+    if (i < 0)
+        goto fail;
+    ep = d->ma_table;
+    mask = d->ma_mask;
+    while (i <= mask && ep[i].me_value == NULL)
+        i++;
+    di->di_pos = i+1;
+    if (i > mask)
+        goto fail;
+
+    if (result->ob_refcnt == 1) {
+        Py_INCREF(result);
+        Py_DECREF(PyTuple_GET_ITEM(result, 0));
+        Py_DECREF(PyTuple_GET_ITEM(result, 1));
+    } else {
+        result = PyTuple_New(2);
+        if (result == NULL)
+            return NULL;
+    }
+    di->len--;
+    key = ep[i].me_key;
+    value = ep[i].me_value;
+    Py_INCREF(key);
+    Py_INCREF(value);
+    PyTuple_SET_ITEM(result, 0, key);
+    PyTuple_SET_ITEM(result, 1, value);
+    return result;
+
+fail:
+    Py_DECREF(d);
+    di->di_dict = NULL;
+    return NULL;
+}
+
+PyTypeObject PyDictIterItem_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dictionary-itemiterator",                  /* tp_name */
+    sizeof(dictiterobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)dictiter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)dictiter_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)dictiter_iternextitem,        /* tp_iternext */
+    dictiter_methods,                           /* tp_methods */
+    0,
+};
+
+/***********************************************/
+/* View objects for keys(), items(), values(). */
+/***********************************************/
+
+/* The instance lay-out is the same for all three; but the type differs. */
+
+typedef struct {
+    PyObject_HEAD
+    PyDictObject *dv_dict;
+} dictviewobject;
+
+
+static void
+dictview_dealloc(dictviewobject *dv)
+{
+    Py_XDECREF(dv->dv_dict);
+    PyObject_GC_Del(dv);
+}
+
+static int
+dictview_traverse(dictviewobject *dv, visitproc visit, void *arg)
+{
+    Py_VISIT(dv->dv_dict);
+    return 0;
+}
+
+static Py_ssize_t
+dictview_len(dictviewobject *dv)
+{
+    Py_ssize_t len = 0;
+    if (dv->dv_dict != NULL)
+        len = dv->dv_dict->ma_used;
+    return len;
+}
+
+static PyObject *
+dictview_new(PyObject *dict, PyTypeObject *type)
+{
+    dictviewobject *dv;
+    if (dict == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    if (!PyDict_Check(dict)) {
+        /* XXX Get rid of this restriction later */
+        PyErr_Format(PyExc_TypeError,
+                     "%s() requires a dict argument, not '%s'",
+                     type->tp_name, dict->ob_type->tp_name);
+        return NULL;
+    }
+    dv = PyObject_GC_New(dictviewobject, type);
+    if (dv == NULL)
+        return NULL;
+    Py_INCREF(dict);
+    dv->dv_dict = (PyDictObject *)dict;
+    _PyObject_GC_TRACK(dv);
+    return (PyObject *)dv;
+}
+
+/* TODO(guido): The views objects are not complete:
+
+ * support more set operations
+ * support arbitrary mappings?
+   - either these should be static or exported in dictobject.h
+   - if public then they should probably be in builtins
+*/
+
+/* Return 1 if self is a subset of other, iterating over self;
+   0 if not; -1 if an error occurred. */
+static int
+all_contained_in(PyObject *self, PyObject *other)
+{
+    PyObject *iter = PyObject_GetIter(self);
+    int ok = 1;
+
+    if (iter == NULL)
+        return -1;
+    for (;;) {
+        PyObject *next = PyIter_Next(iter);
+        if (next == NULL) {
+            if (PyErr_Occurred())
+                ok = -1;
+            break;
+        }
+        ok = PySequence_Contains(other, next);
+        Py_DECREF(next);
+        if (ok <= 0)
+            break;
+    }
+    Py_DECREF(iter);
+    return ok;
+}
+
+static PyObject *
+dictview_richcompare(PyObject *self, PyObject *other, int op)
+{
+    Py_ssize_t len_self, len_other;
+    int ok;
+    PyObject *result;
+
+    assert(self != NULL);
+    assert(PyDictViewSet_Check(self));
+    assert(other != NULL);
+
+    if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    len_self = PyObject_Size(self);
+    if (len_self < 0)
+        return NULL;
+    len_other = PyObject_Size(other);
+    if (len_other < 0)
+        return NULL;
+
+    ok = 0;
+    switch(op) {
+
+    case Py_NE:
+    case Py_EQ:
+        if (len_self == len_other)
+            ok = all_contained_in(self, other);
+        if (op == Py_NE && ok >= 0)
+            ok = !ok;
+        break;
+
+    case Py_LT:
+        if (len_self < len_other)
+            ok = all_contained_in(self, other);
+        break;
+
+      case Py_LE:
+          if (len_self <= len_other)
+              ok = all_contained_in(self, other);
+          break;
+
+    case Py_GT:
+        if (len_self > len_other)
+            ok = all_contained_in(other, self);
+        break;
+
+    case Py_GE:
+        if (len_self >= len_other)
+            ok = all_contained_in(other, self);
+        break;
+
+    }
+    if (ok < 0)
+        return NULL;
+    result = ok ? Py_True : Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
+static PyObject *
+dictview_repr(dictviewobject *dv)
+{
+    PyObject *seq;
+    PyObject *seq_str;
+    PyObject *result;
+
+    seq = PySequence_List((PyObject *)dv);
+    if (seq == NULL)
+        return NULL;
+
+    seq_str = PyObject_Repr(seq);
+    result = PyString_FromFormat("%s(%s)", Py_TYPE(dv)->tp_name,
+                                 PyString_AS_STRING(seq_str));
+    Py_DECREF(seq_str);
+    Py_DECREF(seq);
+    return result;
+}
+
+/*** dict_keys ***/
+
+static PyObject *
+dictkeys_iter(dictviewobject *dv)
+{
+    if (dv->dv_dict == NULL) {
+        Py_RETURN_NONE;
+    }
+    return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
+}
+
+static int
+dictkeys_contains(dictviewobject *dv, PyObject *obj)
+{
+    if (dv->dv_dict == NULL)
+        return 0;
+    return PyDict_Contains((PyObject *)dv->dv_dict, obj);
+}
+
+static PySequenceMethods dictkeys_as_sequence = {
+    (lenfunc)dictview_len,              /* sq_length */
+    0,                                  /* sq_concat */
+    0,                                  /* sq_repeat */
+    0,                                  /* sq_item */
+    0,                                  /* sq_slice */
+    0,                                  /* sq_ass_item */
+    0,                                  /* sq_ass_slice */
+    (objobjproc)dictkeys_contains,      /* sq_contains */
+};
+
+static PyObject*
+dictviews_sub(PyObject* self, PyObject *other)
+{
+    PyObject *result = PySet_New(self);
+    PyObject *tmp;
+    if (result == NULL)
+        return NULL;
+
+    tmp = PyObject_CallMethod(result, "difference_update", "O", other);
+    if (tmp == NULL) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    Py_DECREF(tmp);
+    return result;
+}
+
+static PyObject*
+dictviews_and(PyObject* self, PyObject *other)
+{
+    PyObject *result = PySet_New(self);
+    PyObject *tmp;
+    if (result == NULL)
+        return NULL;
+
+    tmp = PyObject_CallMethod(result, "intersection_update", "O", other);
+    if (tmp == NULL) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    Py_DECREF(tmp);
+    return result;
+}
+
+static PyObject*
+dictviews_or(PyObject* self, PyObject *other)
+{
+    PyObject *result = PySet_New(self);
+    PyObject *tmp;
+    if (result == NULL)
+        return NULL;
+
+    tmp = PyObject_CallMethod(result, "update", "O", other);
+    if (tmp == NULL) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    Py_DECREF(tmp);
+    return result;
+}
+
+static PyObject*
+dictviews_xor(PyObject* self, PyObject *other)
+{
+    PyObject *result = PySet_New(self);
+    PyObject *tmp;
+    if (result == NULL)
+        return NULL;
+
+    tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O",
+                              other);
+    if (tmp == NULL) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    Py_DECREF(tmp);
+    return result;
+}
+
+static PyNumberMethods dictviews_as_number = {
+    0,                                  /*nb_add*/
+    (binaryfunc)dictviews_sub,          /*nb_subtract*/
+    0,                                  /*nb_multiply*/
+    0,                                  /*nb_divide*/
+    0,                                  /*nb_remainder*/
+    0,                                  /*nb_divmod*/
+    0,                                  /*nb_power*/
+    0,                                  /*nb_negative*/
+    0,                                  /*nb_positive*/
+    0,                                  /*nb_absolute*/
+    0,                                  /*nb_nonzero*/
+    0,                                  /*nb_invert*/
+    0,                                  /*nb_lshift*/
+    0,                                  /*nb_rshift*/
+    (binaryfunc)dictviews_and,          /*nb_and*/
+    (binaryfunc)dictviews_xor,          /*nb_xor*/
+    (binaryfunc)dictviews_or,           /*nb_or*/
+};
+
+static PyMethodDef dictkeys_methods[] = {
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyDictKeys_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dict_keys",                                /* tp_name */
+    sizeof(dictviewobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)dictview_dealloc,               /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_reserved */
+    (reprfunc)dictview_repr,                    /* tp_repr */
+    &dictviews_as_number,                       /* tp_as_number */
+    &dictkeys_as_sequence,                      /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_CHECKTYPES,                  /* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)dictview_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    dictview_richcompare,                       /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    (getiterfunc)dictkeys_iter,                 /* tp_iter */
+    0,                                          /* tp_iternext */
+    dictkeys_methods,                           /* tp_methods */
+    0,
+};
+
+static PyObject *
+dictkeys_new(PyObject *dict)
+{
+    return dictview_new(dict, &PyDictKeys_Type);
+}
+
+/*** dict_items ***/
+
+static PyObject *
+dictitems_iter(dictviewobject *dv)
+{
+    if (dv->dv_dict == NULL) {
+        Py_RETURN_NONE;
+    }
+    return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
+}
+
+static int
+dictitems_contains(dictviewobject *dv, PyObject *obj)
+{
+    PyObject *key, *value, *found;
+    if (dv->dv_dict == NULL)
+        return 0;
+    if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
+        return 0;
+    key = PyTuple_GET_ITEM(obj, 0);
+    value = PyTuple_GET_ITEM(obj, 1);
+    found = PyDict_GetItem((PyObject *)dv->dv_dict, key);
+    if (found == NULL) {
+        if (PyErr_Occurred())
+            return -1;
+        return 0;
+    }
+    return PyObject_RichCompareBool(value, found, Py_EQ);
+}
+
+static PySequenceMethods dictitems_as_sequence = {
+    (lenfunc)dictview_len,              /* sq_length */
+    0,                                  /* sq_concat */
+    0,                                  /* sq_repeat */
+    0,                                  /* sq_item */
+    0,                                  /* sq_slice */
+    0,                                  /* sq_ass_item */
+    0,                                  /* sq_ass_slice */
+    (objobjproc)dictitems_contains,     /* sq_contains */
+};
+
+static PyMethodDef dictitems_methods[] = {
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyDictItems_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dict_items",                               /* tp_name */
+    sizeof(dictviewobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)dictview_dealloc,               /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_reserved */
+    (reprfunc)dictview_repr,                    /* tp_repr */
+    &dictviews_as_number,                       /* tp_as_number */
+    &dictitems_as_sequence,                     /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_CHECKTYPES,                  /* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)dictview_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    dictview_richcompare,                       /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    (getiterfunc)dictitems_iter,                /* tp_iter */
+    0,                                          /* tp_iternext */
+    dictitems_methods,                          /* tp_methods */
+    0,
+};
+
+static PyObject *
+dictitems_new(PyObject *dict)
+{
+    return dictview_new(dict, &PyDictItems_Type);
+}
+
+/*** dict_values ***/
+
+static PyObject *
+dictvalues_iter(dictviewobject *dv)
+{
+    if (dv->dv_dict == NULL) {
+        Py_RETURN_NONE;
+    }
+    return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
+}
+
+static PySequenceMethods dictvalues_as_sequence = {
+    (lenfunc)dictview_len,              /* sq_length */
+    0,                                  /* sq_concat */
+    0,                                  /* sq_repeat */
+    0,                                  /* sq_item */
+    0,                                  /* sq_slice */
+    0,                                  /* sq_ass_item */
+    0,                                  /* sq_ass_slice */
+    (objobjproc)0,                      /* sq_contains */
+};
+
+static PyMethodDef dictvalues_methods[] = {
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyDictValues_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "dict_values",                              /* tp_name */
+    sizeof(dictviewobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)dictview_dealloc,               /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_reserved */
+    (reprfunc)dictview_repr,                    /* tp_repr */
+    0,                                          /* tp_as_number */
+    &dictvalues_as_sequence,                    /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)dictview_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    (getiterfunc)dictvalues_iter,               /* tp_iter */
+    0,                                          /* tp_iternext */
+    dictvalues_methods,                         /* tp_methods */
+    0,
+};
+
+static PyObject *
+dictvalues_new(PyObject *dict)
+{
+    return dictview_new(dict, &PyDictValues_Type);
+}
diff --git a/Python-2.7.5/Objects/enumobject.c b/Python-2.7.5/Objects/enumobject.c
new file mode 100644
index 0000000..1ef381f
--- /dev/null
+++ b/Python-2.7.5/Objects/enumobject.c
@@ -0,0 +1,381 @@
+/* enumerate object */
+
+#include "Python.h"
+
+typedef struct {
+    PyObject_HEAD
+    Py_ssize_t en_index;           /* current index of enumeration */
+    PyObject* en_sit;          /* secondary iterator of enumeration */
+    PyObject* en_result;           /* result tuple  */
+    PyObject* en_longindex;        /* index for sequences >= PY_SSIZE_T_MAX */
+} enumobject;
+
+static PyObject *
+enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    enumobject *en;
+    PyObject *seq = NULL;
+    PyObject *start = NULL;
+    static char *kwlist[] = {"sequence", "start", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
+                                     &seq, &start))
+        return NULL;
+
+    en = (enumobject *)type->tp_alloc(type, 0);
+    if (en == NULL)
+        return NULL;
+    if (start != NULL) {
+        start = PyNumber_Index(start);
+        if (start == NULL) {
+            Py_DECREF(en);
+            return NULL;
+        }
+        assert(PyInt_Check(start) || PyLong_Check(start));
+        en->en_index = PyInt_AsSsize_t(start);
+        if (en->en_index == -1 && PyErr_Occurred()) {
+            PyErr_Clear();
+            en->en_index = PY_SSIZE_T_MAX;
+            en->en_longindex = start;
+        } else {
+            en->en_longindex = NULL;
+            Py_DECREF(start);
+        }
+    } else {
+        en->en_index = 0;
+        en->en_longindex = NULL;
+    }
+    en->en_sit = PyObject_GetIter(seq);
+    if (en->en_sit == NULL) {
+        Py_DECREF(en);
+        return NULL;
+    }
+    en->en_result = PyTuple_Pack(2, Py_None, Py_None);
+    if (en->en_result == NULL) {
+        Py_DECREF(en);
+        return NULL;
+    }
+    return (PyObject *)en;
+}
+
+static void
+enum_dealloc(enumobject *en)
+{
+    PyObject_GC_UnTrack(en);
+    Py_XDECREF(en->en_sit);
+    Py_XDECREF(en->en_result);
+    Py_XDECREF(en->en_longindex);
+    Py_TYPE(en)->tp_free(en);
+}
+
+static int
+enum_traverse(enumobject *en, visitproc visit, void *arg)
+{
+    Py_VISIT(en->en_sit);
+    Py_VISIT(en->en_result);
+    Py_VISIT(en->en_longindex);
+    return 0;
+}
+
+static PyObject *
+enum_next_long(enumobject *en, PyObject* next_item)
+{
+    static PyObject *one = NULL;
+    PyObject *result = en->en_result;
+    PyObject *next_index;
+    PyObject *stepped_up;
+
+    if (en->en_longindex == NULL) {
+        en->en_longindex = PyInt_FromSsize_t(PY_SSIZE_T_MAX);
+        if (en->en_longindex == NULL)
+            return NULL;
+    }
+    if (one == NULL) {
+        one = PyInt_FromLong(1);
+        if (one == NULL)
+            return NULL;
+    }
+    next_index = en->en_longindex;
+    assert(next_index != NULL);
+    stepped_up = PyNumber_Add(next_index, one);
+    if (stepped_up == NULL)
+        return NULL;
+    en->en_longindex = stepped_up;
+
+    if (result->ob_refcnt == 1) {
+        Py_INCREF(result);
+        Py_DECREF(PyTuple_GET_ITEM(result, 0));
+        Py_DECREF(PyTuple_GET_ITEM(result, 1));
+    } else {
+        result = PyTuple_New(2);
+        if (result == NULL) {
+            Py_DECREF(next_index);
+            Py_DECREF(next_item);
+            return NULL;
+        }
+    }
+    PyTuple_SET_ITEM(result, 0, next_index);
+    PyTuple_SET_ITEM(result, 1, next_item);
+    return result;
+}
+
+static PyObject *
+enum_next(enumobject *en)
+{
+    PyObject *next_index;
+    PyObject *next_item;
+    PyObject *result = en->en_result;
+    PyObject *it = en->en_sit;
+
+    next_item = (*Py_TYPE(it)->tp_iternext)(it);
+    if (next_item == NULL)
+        return NULL;
+
+    if (en->en_index == PY_SSIZE_T_MAX)
+        return enum_next_long(en, next_item);
+
+    next_index = PyInt_FromSsize_t(en->en_index);
+    if (next_index == NULL) {
+        Py_DECREF(next_item);
+        return NULL;
+    }
+    en->en_index++;
+
+    if (result->ob_refcnt == 1) {
+        Py_INCREF(result);
+        Py_DECREF(PyTuple_GET_ITEM(result, 0));
+        Py_DECREF(PyTuple_GET_ITEM(result, 1));
+    } else {
+        result = PyTuple_New(2);
+        if (result == NULL) {
+            Py_DECREF(next_index);
+            Py_DECREF(next_item);
+            return NULL;
+        }
+    }
+    PyTuple_SET_ITEM(result, 0, next_index);
+    PyTuple_SET_ITEM(result, 1, next_item);
+    return result;
+}
+
+PyDoc_STRVAR(enum_doc,
+"enumerate(iterable[, start]) -> iterator for index, value of iterable\n"
+"\n"
+"Return an enumerate object.  iterable must be another object that supports\n"
+"iteration.  The enumerate object yields pairs containing a count (from\n"
+"start, which defaults to zero) and a value yielded by the iterable argument.\n"
+"enumerate is useful for obtaining an indexed list:\n"
+"    (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
+
+PyTypeObject PyEnum_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "enumerate",                    /* tp_name */
+    sizeof(enumobject),             /* tp_basicsize */
+    0,                              /* tp_itemsize */
+    /* methods */
+    (destructor)enum_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 */
+    0,                              /* tp_str */
+    PyObject_GenericGetAttr,        /* tp_getattro */
+    0,                              /* tp_setattro */
+    0,                              /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE,    /* tp_flags */
+    enum_doc,                       /* tp_doc */
+    (traverseproc)enum_traverse,    /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    PyObject_SelfIter,                  /* tp_iter */
+    (iternextfunc)enum_next,        /* tp_iternext */
+    0,                              /* tp_methods */
+    0,                              /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    PyType_GenericAlloc,            /* tp_alloc */
+    enum_new,                       /* tp_new */
+    PyObject_GC_Del,                /* tp_free */
+};
+
+/* Reversed Object ***************************************************************/
+
+typedef struct {
+    PyObject_HEAD
+    Py_ssize_t      index;
+    PyObject* seq;
+} reversedobject;
+
+static PyObject *
+reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Py_ssize_t n;
+    PyObject *seq, *reversed_meth;
+    static PyObject *reversed_cache = NULL;
+    reversedobject *ro;
+
+    if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
+        return NULL;
+
+    if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
+        return NULL;
+
+    if (PyInstance_Check(seq)) {
+        reversed_meth = PyObject_GetAttrString(seq, "__reversed__");
+        if (reversed_meth == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                PyErr_Clear();
+            else
+                return NULL;
+        }
+    }
+    else {
+        reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__",
+                                                &reversed_cache);
+        if (reversed_meth == NULL && PyErr_Occurred())
+            return NULL;
+    }
+    if (reversed_meth != NULL) {
+        PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);
+        Py_DECREF(reversed_meth);
+        return res;
+    }
+
+    if (!PySequence_Check(seq)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "argument to reversed() must be a sequence");
+        return NULL;
+    }
+
+    n = PySequence_Size(seq);
+    if (n == -1)
+        return NULL;
+
+    ro = (reversedobject *)type->tp_alloc(type, 0);
+    if (ro == NULL)
+        return NULL;
+
+    ro->index = n-1;
+    Py_INCREF(seq);
+    ro->seq = seq;
+    return (PyObject *)ro;
+}
+
+static void
+reversed_dealloc(reversedobject *ro)
+{
+    PyObject_GC_UnTrack(ro);
+    Py_XDECREF(ro->seq);
+    Py_TYPE(ro)->tp_free(ro);
+}
+
+static int
+reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
+{
+    Py_VISIT(ro->seq);
+    return 0;
+}
+
+static PyObject *
+reversed_next(reversedobject *ro)
+{
+    PyObject *item;
+    Py_ssize_t index = ro->index;
+
+    if (index >= 0) {
+        item = PySequence_GetItem(ro->seq, index);
+        if (item != NULL) {
+            ro->index--;
+            return item;
+        }
+        if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+            PyErr_ExceptionMatches(PyExc_StopIteration))
+            PyErr_Clear();
+    }
+    ro->index = -1;
+    Py_CLEAR(ro->seq);
+    return NULL;
+}
+
+PyDoc_STRVAR(reversed_doc,
+"reversed(sequence) -> reverse iterator over values of the sequence\n"
+"\n"
+"Return a reverse iterator");
+
+static PyObject *
+reversed_len(reversedobject *ro)
+{
+    Py_ssize_t position, seqsize;
+
+    if (ro->seq == NULL)
+        return PyInt_FromLong(0);
+    seqsize = PySequence_Size(ro->seq);
+    if (seqsize == -1)
+        return NULL;
+    position = ro->index + 1;
+    return PyInt_FromSsize_t((seqsize < position)  ?  0  :  position);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef reversediter_methods[] = {
+    {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyReversed_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "reversed",                     /* tp_name */
+    sizeof(reversedobject),         /* tp_basicsize */
+    0,                              /* tp_itemsize */
+    /* methods */
+    (destructor)reversed_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 */
+    0,                              /* tp_str */
+    PyObject_GenericGetAttr,        /* tp_getattro */
+    0,                              /* tp_setattro */
+    0,                              /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE,    /* tp_flags */
+    reversed_doc,                   /* tp_doc */
+    (traverseproc)reversed_traverse,/* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    PyObject_SelfIter,                  /* tp_iter */
+    (iternextfunc)reversed_next,    /* tp_iternext */
+    reversediter_methods,               /* tp_methods */
+    0,                              /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    PyType_GenericAlloc,            /* tp_alloc */
+    reversed_new,                   /* tp_new */
+    PyObject_GC_Del,                /* tp_free */
+};
diff --git a/Python-2.7.5/Objects/exceptions.c b/Python-2.7.5/Objects/exceptions.c
new file mode 100644
index 0000000..0f86cfb
--- /dev/null
+++ b/Python-2.7.5/Objects/exceptions.c
@@ -0,0 +1,2219 @@
+/*
+ * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
+ *
+ * Thanks go to Tim Peters and Michael Hudson for debugging.
+ */
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include "structmember.h"
+#include "osdefs.h"
+
+#define EXC_MODULE_NAME "exceptions."
+
+/* NOTE: If the exception class hierarchy changes, don't forget to update
+ * Lib/test/exception_hierarchy.txt
+ */
+
+PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
+\n\
+Exceptions found here are defined both in the exceptions module and the\n\
+built-in namespace.  It is recommended that user-defined exceptions\n\
+inherit from Exception.  See the documentation for the exception\n\
+inheritance hierarchy.\n\
+");
+
+/*
+ *    BaseException
+ */
+static PyObject *
+BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyBaseExceptionObject *self;
+
+    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
+    if (!self)
+        return NULL;
+    /* the dict is created on the fly in PyObject_GenericSetAttr */
+    self->message = self->dict = NULL;
+
+    self->args = PyTuple_New(0);
+    if (!self->args) {
+        Py_DECREF(self);
+        return NULL;
+    }
+
+    self->message = PyString_FromString("");
+    if (!self->message) {
+        Py_DECREF(self);
+        return NULL;
+    }
+
+    return (PyObject *)self;
+}
+
+static int
+BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
+{
+    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
+        return -1;
+
+    Py_DECREF(self->args);
+    self->args = args;
+    Py_INCREF(self->args);
+
+    if (PyTuple_GET_SIZE(self->args) == 1) {
+        Py_CLEAR(self->message);
+        self->message = PyTuple_GET_ITEM(self->args, 0);
+        Py_INCREF(self->message);
+    }
+    return 0;
+}
+
+static int
+BaseException_clear(PyBaseExceptionObject *self)
+{
+    Py_CLEAR(self->dict);
+    Py_CLEAR(self->args);
+    Py_CLEAR(self->message);
+    return 0;
+}
+
+static void
+BaseException_dealloc(PyBaseExceptionObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    BaseException_clear(self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->dict);
+    Py_VISIT(self->args);
+    Py_VISIT(self->message);
+    return 0;
+}
+
+static PyObject *
+BaseException_str(PyBaseExceptionObject *self)
+{
+    PyObject *out;
+
+    switch (PyTuple_GET_SIZE(self->args)) {
+    case 0:
+        out = PyString_FromString("");
+        break;
+    case 1:
+        out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
+        break;
+    default:
+        out = PyObject_Str(self->args);
+        break;
+    }
+
+    return out;
+}
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+BaseException_unicode(PyBaseExceptionObject *self)
+{
+    PyObject *out;
+
+    /* issue6108: if __str__ has been overridden in the subclass, unicode()
+       should return the message returned by __str__ as used to happen
+       before this method was implemented. */
+    if (Py_TYPE(self)->tp_str != (reprfunc)BaseException_str) {
+        PyObject *str;
+        /* Unlike PyObject_Str, tp_str can return unicode (i.e. return the
+           equivalent of unicode(e.__str__()) instead of unicode(str(e))). */
+        str = Py_TYPE(self)->tp_str((PyObject*)self);
+        if (str == NULL)
+            return NULL;
+        out = PyObject_Unicode(str);
+        Py_DECREF(str);
+        return out;
+    }
+
+    switch (PyTuple_GET_SIZE(self->args)) {
+    case 0:
+        out = PyUnicode_FromString("");
+        break;
+    case 1:
+        out = PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
+        break;
+    default:
+        out = PyObject_Unicode(self->args);
+        break;
+    }
+
+    return out;
+}
+#endif
+
+static PyObject *
+BaseException_repr(PyBaseExceptionObject *self)
+{
+    PyObject *repr_suffix;
+    PyObject *repr;
+    char *name;
+    char *dot;
+
+    repr_suffix = PyObject_Repr(self->args);
+    if (!repr_suffix)
+        return NULL;
+
+    name = (char *)Py_TYPE(self)->tp_name;
+    dot = strrchr(name, '.');
+    if (dot != NULL) name = dot+1;
+
+    repr = PyString_FromString(name);
+    if (!repr) {
+        Py_DECREF(repr_suffix);
+        return NULL;
+    }
+
+    PyString_ConcatAndDel(&repr, repr_suffix);
+    return repr;
+}
+
+/* Pickling support */
+static PyObject *
+BaseException_reduce(PyBaseExceptionObject *self)
+{
+    if (self->args && self->dict)
+        return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
+    else
+        return PyTuple_Pack(2, Py_TYPE(self), self->args);
+}
+
+/*
+ * Needed for backward compatibility, since exceptions used to store
+ * all their attributes in the __dict__. Code is taken from cPickle's
+ * load_build function.
+ */
+static PyObject *
+BaseException_setstate(PyObject *self, PyObject *state)
+{
+    PyObject *d_key, *d_value;
+    Py_ssize_t i = 0;
+
+    if (state != Py_None) {
+        if (!PyDict_Check(state)) {
+            PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
+            return NULL;
+        }
+        while (PyDict_Next(state, &i, &d_key, &d_value)) {
+            if (PyObject_SetAttr(self, d_key, d_value) < 0)
+                return NULL;
+        }
+    }
+    Py_RETURN_NONE;
+}
+
+
+static PyMethodDef BaseException_methods[] = {
+   {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
+   {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
+#ifdef Py_USING_UNICODE
+   {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
+#endif
+   {NULL, NULL, 0, NULL},
+};
+
+
+
+static PyObject *
+BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
+{
+    if (PyErr_WarnPy3k("__getitem__ not supported for exception "
+                       "classes in 3.x; use args attribute", 1) < 0)
+        return NULL;
+    return PySequence_GetItem(self->args, index);
+}
+
+static PyObject *
+BaseException_getslice(PyBaseExceptionObject *self,
+                        Py_ssize_t start, Py_ssize_t stop)
+{
+    if (PyErr_WarnPy3k("__getslice__ not supported for exception "
+                       "classes in 3.x; use args attribute", 1) < 0)
+        return NULL;
+    return PySequence_GetSlice(self->args, start, stop);
+}
+
+static PySequenceMethods BaseException_as_sequence = {
+    0,                      /* sq_length; */
+    0,                      /* sq_concat; */
+    0,                      /* sq_repeat; */
+    (ssizeargfunc)BaseException_getitem,  /* sq_item; */
+    (ssizessizeargfunc)BaseException_getslice,  /* sq_slice; */
+    0,                      /* sq_ass_item; */
+    0,                      /* sq_ass_slice; */
+    0,                      /* sq_contains; */
+    0,                      /* sq_inplace_concat; */
+    0                       /* sq_inplace_repeat; */
+};
+
+static PyObject *
+BaseException_get_dict(PyBaseExceptionObject *self)
+{
+    if (self->dict == NULL) {
+        self->dict = PyDict_New();
+        if (!self->dict)
+            return NULL;
+    }
+    Py_INCREF(self->dict);
+    return self->dict;
+}
+
+static int
+BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
+{
+    if (val == NULL) {
+        PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
+        return -1;
+    }
+    if (!PyDict_Check(val)) {
+        PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
+        return -1;
+    }
+    Py_CLEAR(self->dict);
+    Py_INCREF(val);
+    self->dict = val;
+    return 0;
+}
+
+static PyObject *
+BaseException_get_args(PyBaseExceptionObject *self)
+{
+    if (self->args == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    Py_INCREF(self->args);
+    return self->args;
+}
+
+static int
+BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
+{
+    PyObject *seq;
+    if (val == NULL) {
+        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
+        return -1;
+    }
+    seq = PySequence_Tuple(val);
+    if (!seq)
+        return -1;
+    Py_CLEAR(self->args);
+    self->args = seq;
+    return 0;
+}
+
+static PyObject *
+BaseException_get_message(PyBaseExceptionObject *self)
+{
+    PyObject *msg;
+
+    /* if "message" is in self->dict, accessing a user-set message attribute */
+    if (self->dict &&
+        (msg = PyDict_GetItemString(self->dict, "message"))) {
+        Py_INCREF(msg);
+        return msg;
+    }
+
+    if (self->message == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "message attribute was deleted");
+        return NULL;
+    }
+
+    /* accessing the deprecated "builtin" message attribute of Exception */
+    if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                     "BaseException.message has been deprecated as "
+                     "of Python 2.6", 1) < 0)
+        return NULL;
+
+    Py_INCREF(self->message);
+    return self->message;
+}
+
+static int
+BaseException_set_message(PyBaseExceptionObject *self, PyObject *val)
+{
+    /* if val is NULL, delete the message attribute */
+    if (val == NULL) {
+        if (self->dict && PyDict_GetItemString(self->dict, "message")) {
+            if (PyDict_DelItemString(self->dict, "message") < 0)
+                return -1;
+        }
+        Py_CLEAR(self->message);
+        return 0;
+    }
+
+    /* else set it in __dict__, but may need to create the dict first */
+    if (self->dict == NULL) {
+        self->dict = PyDict_New();
+        if (!self->dict)
+            return -1;
+    }
+    return PyDict_SetItemString(self->dict, "message", val);
+}
+
+static PyGetSetDef BaseException_getset[] = {
+    {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
+    {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
+    {"message", (getter)BaseException_get_message,
+            (setter)BaseException_set_message},
+    {NULL},
+};
+
+
+static PyTypeObject _PyExc_BaseException = {
+    PyObject_HEAD_INIT(NULL)
+    0,                          /*ob_size*/
+    EXC_MODULE_NAME "BaseException", /*tp_name*/
+    sizeof(PyBaseExceptionObject), /*tp_basicsize*/
+    0,                          /*tp_itemsize*/
+    (destructor)BaseException_dealloc, /*tp_dealloc*/
+    0,                          /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /* tp_compare; */
+    (reprfunc)BaseException_repr, /*tp_repr*/
+    0,                          /*tp_as_number*/
+    &BaseException_as_sequence, /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    0,                          /*tp_hash */
+    0,                          /*tp_call*/
+    (reprfunc)BaseException_str,  /*tp_str*/
+    PyObject_GenericGetAttr,    /*tp_getattro*/
+    PyObject_GenericSetAttr,    /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASE_EXC_SUBCLASS,  /*tp_flags*/
+    PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
+    (traverseproc)BaseException_traverse, /* tp_traverse */
+    (inquiry)BaseException_clear, /* tp_clear */
+    0,                          /* tp_richcompare */
+    0,                          /* tp_weaklistoffset */
+    0,                          /* tp_iter */
+    0,                          /* tp_iternext */
+    BaseException_methods,      /* tp_methods */
+    0,                          /* tp_members */
+    BaseException_getset,       /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
+    (initproc)BaseException_init, /* tp_init */
+    0,                          /* tp_alloc */
+    BaseException_new,          /* tp_new */
+};
+/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
+from the previous implmentation and also allowing Python objects to be used
+in the API */
+PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
+
+/* note these macros omit the last semicolon so the macro invocation may
+ * include it and not look strange.
+ */
+#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+    PyObject_HEAD_INIT(NULL) \
+    0, \
+    EXC_MODULE_NAME # EXCNAME, \
+    sizeof(PyBaseExceptionObject), \
+    0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, \
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+    PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
+    (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
+    0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
+    (initproc)BaseException_init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+    PyObject_HEAD_INIT(NULL) \
+    0, \
+    EXC_MODULE_NAME # EXCNAME, \
+    sizeof(Py ## EXCSTORE ## Object), \
+    0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, \
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+    PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
+    (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
+    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
+    (initproc)EXCSTORE ## _init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+    PyObject_HEAD_INIT(NULL) \
+    0, \
+    EXC_MODULE_NAME # EXCNAME, \
+    sizeof(Py ## EXCSTORE ## Object), 0, \
+    (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    (reprfunc)EXCSTR, 0, 0, 0, \
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+    PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
+    (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
+    EXCMEMBERS, 0, &_ ## EXCBASE, \
+    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
+    (initproc)EXCSTORE ## _init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+
+/*
+ *    Exception extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, Exception,
+                       "Common base class for all non-exit exceptions.");
+
+
+/*
+ *    StandardError extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, StandardError,
+    "Base class for all standard Python exceptions that do not represent\n"
+    "interpreter exiting.");
+
+
+/*
+ *    TypeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, TypeError,
+                       "Inappropriate argument type.");
+
+
+/*
+ *    StopIteration extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, StopIteration,
+                       "Signal the end from iterator.next().");
+
+
+/*
+ *    GeneratorExit extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, GeneratorExit,
+                       "Request that a generator exit.");
+
+
+/*
+ *    SystemExit extends BaseException
+ */
+
+static int
+SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
+{
+    Py_ssize_t size = PyTuple_GET_SIZE(args);
+
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    if (size == 0)
+        return 0;
+    Py_CLEAR(self->code);
+    if (size == 1)
+        self->code = PyTuple_GET_ITEM(args, 0);
+    else if (size > 1)
+        self->code = args;
+    Py_INCREF(self->code);
+    return 0;
+}
+
+static int
+SystemExit_clear(PySystemExitObject *self)
+{
+    Py_CLEAR(self->code);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+SystemExit_dealloc(PySystemExitObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    SystemExit_clear(self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->code);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyMemberDef SystemExit_members[] = {
+    {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
+        PyDoc_STR("exception code")},
+    {NULL}  /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
+                        SystemExit_dealloc, 0, SystemExit_members, 0,
+                        "Request to exit from the interpreter.");
+
+/*
+ *    KeyboardInterrupt extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
+                       "Program interrupted by user.");
+
+
+/*
+ *    ImportError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ImportError,
+          "Import can't find module, or can't find name in module.");
+
+
+/*
+ *    EnvironmentError extends StandardError
+ */
+
+/* Where a function has a single filename, such as open() or some
+ * of the os module functions, PyErr_SetFromErrnoWithFilename() is
+ * called, giving a third argument which is the filename.  But, so
+ * that old code using in-place unpacking doesn't break, e.g.:
+ *
+ * except IOError, (errno, strerror):
+ *
+ * we hack args so that it only contains two items.  This also
+ * means we need our own __str__() which prints out the filename
+ * when it was supplied.
+ */
+static int
+EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
+    PyObject *kwds)
+{
+    PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
+    PyObject *subslice = NULL;
+
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
+        return 0;
+    }
+
+    if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
+                           &myerrno, &strerror, &filename)) {
+        return -1;
+    }
+    Py_CLEAR(self->myerrno);       /* replacing */
+    self->myerrno = myerrno;
+    Py_INCREF(self->myerrno);
+
+    Py_CLEAR(self->strerror);      /* replacing */
+    self->strerror = strerror;
+    Py_INCREF(self->strerror);
+
+    /* self->filename will remain Py_None otherwise */
+    if (filename != NULL) {
+        Py_CLEAR(self->filename);      /* replacing */
+        self->filename = filename;
+        Py_INCREF(self->filename);
+
+        subslice = PyTuple_GetSlice(args, 0, 2);
+        if (!subslice)
+            return -1;
+
+        Py_DECREF(self->args);  /* replacing args */
+        self->args = subslice;
+    }
+    return 0;
+}
+
+static int
+EnvironmentError_clear(PyEnvironmentErrorObject *self)
+{
+    Py_CLEAR(self->myerrno);
+    Py_CLEAR(self->strerror);
+    Py_CLEAR(self->filename);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    EnvironmentError_clear(self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
+        void *arg)
+{
+    Py_VISIT(self->myerrno);
+    Py_VISIT(self->strerror);
+    Py_VISIT(self->filename);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyObject *
+EnvironmentError_str(PyEnvironmentErrorObject *self)
+{
+    PyObject *rtnval = NULL;
+
+    if (self->filename) {
+        PyObject *fmt;
+        PyObject *repr;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Errno %s] %s: %s");
+        if (!fmt)
+            return NULL;
+
+        repr = PyObject_Repr(self->filename);
+        if (!repr) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+        tuple = PyTuple_New(3);
+        if (!tuple) {
+            Py_DECREF(repr);
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->myerrno) {
+            Py_INCREF(self->myerrno);
+            PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        PyTuple_SET_ITEM(tuple, 2, repr);
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else if (self->myerrno && self->strerror) {
+        PyObject *fmt;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Errno %s] %s");
+        if (!fmt)
+            return NULL;
+
+        tuple = PyTuple_New(2);
+        if (!tuple) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->myerrno) {
+            Py_INCREF(self->myerrno);
+            PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else
+        rtnval = BaseException_str((PyBaseExceptionObject *)self);
+
+    return rtnval;
+}
+
+static PyMemberDef EnvironmentError_members[] = {
+    {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
+        PyDoc_STR("exception errno")},
+    {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
+        PyDoc_STR("exception strerror")},
+    {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
+        PyDoc_STR("exception filename")},
+    {NULL}  /* Sentinel */
+};
+
+
+static PyObject *
+EnvironmentError_reduce(PyEnvironmentErrorObject *self)
+{
+    PyObject *args = self->args;
+    PyObject *res = NULL, *tmp;
+
+    /* self->args is only the first two real arguments if there was a
+     * file name given to EnvironmentError. */
+    if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
+        args = PyTuple_New(3);
+        if (!args)
+            return NULL;
+
+        tmp = PyTuple_GET_ITEM(self->args, 0);
+        Py_INCREF(tmp);
+        PyTuple_SET_ITEM(args, 0, tmp);
+
+        tmp = PyTuple_GET_ITEM(self->args, 1);
+        Py_INCREF(tmp);
+        PyTuple_SET_ITEM(args, 1, tmp);
+
+        Py_INCREF(self->filename);
+        PyTuple_SET_ITEM(args, 2, self->filename);
+    } else
+        Py_INCREF(args);
+
+    if (self->dict)
+        res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
+    else
+        res = PyTuple_Pack(2, Py_TYPE(self), args);
+    Py_DECREF(args);
+    return res;
+}
+
+
+static PyMethodDef EnvironmentError_methods[] = {
+    {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
+    {NULL}
+};
+
+ComplexExtendsException(PyExc_StandardError, EnvironmentError,
+                        EnvironmentError, EnvironmentError_dealloc,
+                        EnvironmentError_methods, EnvironmentError_members,
+                        EnvironmentError_str,
+                        "Base class for I/O related errors.");
+
+
+/*
+ *    IOError extends EnvironmentError
+ */
+MiddlingExtendsException(PyExc_EnvironmentError, IOError,
+                         EnvironmentError, "I/O operation failed.");
+
+
+/*
+ *    OSError extends EnvironmentError
+ */
+MiddlingExtendsException(PyExc_EnvironmentError, OSError,
+                         EnvironmentError, "OS system call failed.");
+
+
+/*
+ *    WindowsError extends OSError
+ */
+#ifdef MS_WINDOWS
+#include "errmap.h"
+
+static int
+WindowsError_clear(PyWindowsErrorObject *self)
+{
+    Py_CLEAR(self->myerrno);
+    Py_CLEAR(self->strerror);
+    Py_CLEAR(self->filename);
+    Py_CLEAR(self->winerror);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+WindowsError_dealloc(PyWindowsErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    WindowsError_clear(self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->myerrno);
+    Py_VISIT(self->strerror);
+    Py_VISIT(self->filename);
+    Py_VISIT(self->winerror);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static int
+WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *o_errcode = NULL;
+    long errcode;
+    long posix_errno;
+
+    if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
+            == -1)
+        return -1;
+
+    if (self->myerrno == NULL)
+        return 0;
+
+    /* Set errno to the POSIX errno, and winerror to the Win32
+       error code. */
+    errcode = PyInt_AsLong(self->myerrno);
+    if (errcode == -1 && PyErr_Occurred())
+        return -1;
+    posix_errno = winerror_to_errno(errcode);
+
+    Py_CLEAR(self->winerror);
+    self->winerror = self->myerrno;
+
+    o_errcode = PyInt_FromLong(posix_errno);
+    if (!o_errcode)
+        return -1;
+
+    self->myerrno = o_errcode;
+
+    return 0;
+}
+
+
+static PyObject *
+WindowsError_str(PyWindowsErrorObject *self)
+{
+    PyObject *rtnval = NULL;
+
+    if (self->filename) {
+        PyObject *fmt;
+        PyObject *repr;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Error %s] %s: %s");
+        if (!fmt)
+            return NULL;
+
+        repr = PyObject_Repr(self->filename);
+        if (!repr) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+        tuple = PyTuple_New(3);
+        if (!tuple) {
+            Py_DECREF(repr);
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->winerror) {
+            Py_INCREF(self->winerror);
+            PyTuple_SET_ITEM(tuple, 0, self->winerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        PyTuple_SET_ITEM(tuple, 2, repr);
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else if (self->winerror && self->strerror) {
+        PyObject *fmt;
+        PyObject *tuple;
+
+        fmt = PyString_FromString("[Error %s] %s");
+        if (!fmt)
+            return NULL;
+
+        tuple = PyTuple_New(2);
+        if (!tuple) {
+            Py_DECREF(fmt);
+            return NULL;
+        }
+
+        if (self->winerror) {
+            Py_INCREF(self->winerror);
+            PyTuple_SET_ITEM(tuple, 0, self->winerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 0, Py_None);
+        }
+        if (self->strerror) {
+            Py_INCREF(self->strerror);
+            PyTuple_SET_ITEM(tuple, 1, self->strerror);
+        }
+        else {
+            Py_INCREF(Py_None);
+            PyTuple_SET_ITEM(tuple, 1, Py_None);
+        }
+
+        rtnval = PyString_Format(fmt, tuple);
+
+        Py_DECREF(fmt);
+        Py_DECREF(tuple);
+    }
+    else
+        rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
+
+    return rtnval;
+}
+
+static PyMemberDef WindowsError_members[] = {
+    {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
+        PyDoc_STR("POSIX exception code")},
+    {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
+        PyDoc_STR("exception strerror")},
+    {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
+        PyDoc_STR("exception filename")},
+    {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
+        PyDoc_STR("Win32 exception code")},
+    {NULL}  /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
+                        WindowsError_dealloc, 0, WindowsError_members,
+                        WindowsError_str, "MS-Windows OS system call failed.");
+
+#endif /* MS_WINDOWS */
+
+
+/*
+ *    VMSError extends OSError (I think)
+ */
+#ifdef __VMS
+MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
+                         "OpenVMS OS system call failed.");
+#endif
+
+
+/*
+ *    EOFError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, EOFError,
+                       "Read beyond end of file.");
+
+
+/*
+ *    RuntimeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, RuntimeError,
+                       "Unspecified run-time error.");
+
+
+/*
+ *    NotImplementedError extends RuntimeError
+ */
+SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
+                       "Method or function hasn't been implemented yet.");
+
+/*
+ *    NameError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, NameError,
+                       "Name not found globally.");
+
+/*
+ *    UnboundLocalError extends NameError
+ */
+SimpleExtendsException(PyExc_NameError, UnboundLocalError,
+                       "Local name referenced but not bound to a value.");
+
+/*
+ *    AttributeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, AttributeError,
+                       "Attribute not found.");
+
+
+/*
+ *    SyntaxError extends StandardError
+ */
+
+static int
+SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *info = NULL;
+    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
+
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    if (lenargs >= 1) {
+        Py_CLEAR(self->msg);
+        self->msg = PyTuple_GET_ITEM(args, 0);
+        Py_INCREF(self->msg);
+    }
+    if (lenargs == 2) {
+        info = PyTuple_GET_ITEM(args, 1);
+        info = PySequence_Tuple(info);
+        if (!info)
+            return -1;
+
+        if (PyTuple_GET_SIZE(info) != 4) {
+            /* not a very good error message, but it's what Python 2.4 gives */
+            PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+            Py_DECREF(info);
+            return -1;
+        }
+
+        Py_CLEAR(self->filename);
+        self->filename = PyTuple_GET_ITEM(info, 0);
+        Py_INCREF(self->filename);
+
+        Py_CLEAR(self->lineno);
+        self->lineno = PyTuple_GET_ITEM(info, 1);
+        Py_INCREF(self->lineno);
+
+        Py_CLEAR(self->offset);
+        self->offset = PyTuple_GET_ITEM(info, 2);
+        Py_INCREF(self->offset);
+
+        Py_CLEAR(self->text);
+        self->text = PyTuple_GET_ITEM(info, 3);
+        Py_INCREF(self->text);
+
+        Py_DECREF(info);
+    }
+    return 0;
+}
+
+static int
+SyntaxError_clear(PySyntaxErrorObject *self)
+{
+    Py_CLEAR(self->msg);
+    Py_CLEAR(self->filename);
+    Py_CLEAR(self->lineno);
+    Py_CLEAR(self->offset);
+    Py_CLEAR(self->text);
+    Py_CLEAR(self->print_file_and_line);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+SyntaxError_dealloc(PySyntaxErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    SyntaxError_clear(self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->msg);
+    Py_VISIT(self->filename);
+    Py_VISIT(self->lineno);
+    Py_VISIT(self->offset);
+    Py_VISIT(self->text);
+    Py_VISIT(self->print_file_and_line);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+/* This is called "my_basename" instead of just "basename" to avoid name
+   conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
+   defined, and Python does define that. */
+static char *
+my_basename(char *name)
+{
+    char *cp = name;
+    char *result = name;
+
+    if (name == NULL)
+        return "???";
+    while (*cp != '\0') {
+        if (*cp == SEP)
+            result = cp + 1;
+        ++cp;
+    }
+    return result;
+}
+
+
+static PyObject *
+SyntaxError_str(PySyntaxErrorObject *self)
+{
+    PyObject *str;
+    PyObject *result;
+    int have_filename = 0;
+    int have_lineno = 0;
+    char *buffer = NULL;
+    Py_ssize_t bufsize;
+
+    if (self->msg)
+        str = PyObject_Str(self->msg);
+    else
+        str = PyObject_Str(Py_None);
+    if (!str)
+        return NULL;
+    /* Don't fiddle with non-string return (shouldn't happen anyway) */
+    if (!PyString_Check(str))
+        return str;
+
+    /* XXX -- do all the additional formatting with filename and
+       lineno here */
+
+    have_filename = (self->filename != NULL) &&
+        PyString_Check(self->filename);
+    have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
+
+    if (!have_filename && !have_lineno)
+        return str;
+
+    bufsize = PyString_GET_SIZE(str) + 64;
+    if (have_filename)
+        bufsize += PyString_GET_SIZE(self->filename);
+
+    buffer = PyMem_MALLOC(bufsize);
+    if (buffer == NULL)
+        return str;
+
+    if (have_filename && have_lineno)
+        PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
+            PyString_AS_STRING(str),
+            my_basename(PyString_AS_STRING(self->filename)),
+            PyInt_AsLong(self->lineno));
+    else if (have_filename)
+        PyOS_snprintf(buffer, bufsize, "%s (%s)",
+            PyString_AS_STRING(str),
+            my_basename(PyString_AS_STRING(self->filename)));
+    else /* only have_lineno */
+        PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
+            PyString_AS_STRING(str),
+            PyInt_AsLong(self->lineno));
+
+    result = PyString_FromString(buffer);
+    PyMem_FREE(buffer);
+
+    if (result == NULL)
+        result = str;
+    else
+        Py_DECREF(str);
+    return result;
+}
+
+static PyMemberDef SyntaxError_members[] = {
+    {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
+        PyDoc_STR("exception msg")},
+    {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
+        PyDoc_STR("exception filename")},
+    {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
+        PyDoc_STR("exception lineno")},
+    {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
+        PyDoc_STR("exception offset")},
+    {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
+        PyDoc_STR("exception text")},
+    {"print_file_and_line", T_OBJECT,
+        offsetof(PySyntaxErrorObject, print_file_and_line), 0,
+        PyDoc_STR("exception print_file_and_line")},
+    {NULL}  /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
+                        SyntaxError_dealloc, 0, SyntaxError_members,
+                        SyntaxError_str, "Invalid syntax.");
+
+
+/*
+ *    IndentationError extends SyntaxError
+ */
+MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
+                         "Improper indentation.");
+
+
+/*
+ *    TabError extends IndentationError
+ */
+MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
+                         "Improper mixture of spaces and tabs.");
+
+
+/*
+ *    LookupError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, LookupError,
+                       "Base class for lookup errors.");
+
+
+/*
+ *    IndexError extends LookupError
+ */
+SimpleExtendsException(PyExc_LookupError, IndexError,
+                       "Sequence index out of range.");
+
+
+/*
+ *    KeyError extends LookupError
+ */
+static PyObject *
+KeyError_str(PyBaseExceptionObject *self)
+{
+    /* If args is a tuple of exactly one item, apply repr to args[0].
+       This is done so that e.g. the exception raised by {}[''] prints
+         KeyError: ''
+       rather than the confusing
+         KeyError
+       alone.  The downside is that if KeyError is raised with an explanatory
+       string, that string will be displayed in quotes.  Too bad.
+       If args is anything else, use the default BaseException__str__().
+    */
+    if (PyTuple_GET_SIZE(self->args) == 1) {
+        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
+    }
+    return BaseException_str(self);
+}
+
+ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
+                        0, 0, 0, KeyError_str, "Mapping key not found.");
+
+
+/*
+ *    ValueError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ValueError,
+                       "Inappropriate argument value (of correct type).");
+
+/*
+ *    UnicodeError extends ValueError
+ */
+
+SimpleExtendsException(PyExc_ValueError, UnicodeError,
+                       "Unicode related error.");
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+get_string(PyObject *attr, const char *name)
+{
+    if (!attr) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+        return NULL;
+    }
+
+    if (!PyString_Check(attr)) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
+        return NULL;
+    }
+    Py_INCREF(attr);
+    return attr;
+}
+
+
+static int
+set_string(PyObject **attr, const char *value)
+{
+    PyObject *obj = PyString_FromString(value);
+    if (!obj)
+        return -1;
+    Py_CLEAR(*attr);
+    *attr = obj;
+    return 0;
+}
+
+
+static PyObject *
+get_unicode(PyObject *attr, const char *name)
+{
+    if (!attr) {
+        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+        return NULL;
+    }
+
+    if (!PyUnicode_Check(attr)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%.200s attribute must be unicode", name);
+        return NULL;
+    }
+    Py_INCREF(attr);
+    return attr;
+}
+
+PyObject *
+PyUnicodeEncodeError_GetEncoding(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
+}
+
+PyObject *
+PyUnicodeDecodeError_GetEncoding(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
+}
+
+PyObject *
+PyUnicodeEncodeError_GetObject(PyObject *exc)
+{
+    return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+PyObject *
+PyUnicodeDecodeError_GetObject(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+PyObject *
+PyUnicodeTranslateError_GetObject(PyObject *exc)
+{
+    return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+int
+PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+    Py_ssize_t size;
+    PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
+                                "object");
+    if (!obj)
+        return -1;
+    *start = ((PyUnicodeErrorObject *)exc)->start;
+    size = PyUnicode_GET_SIZE(obj);
+    if (*start<0)
+        *start = 0; /*XXX check for values <0*/
+    if (*start>=size)
+        *start = size-1;
+    Py_DECREF(obj);
+    return 0;
+}
+
+
+int
+PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+    Py_ssize_t size;
+    PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
+                               "object");
+    if (!obj)
+        return -1;
+    size = PyString_GET_SIZE(obj);
+    *start = ((PyUnicodeErrorObject *)exc)->start;
+    if (*start<0)
+        *start = 0;
+    if (*start>=size)
+        *start = size-1;
+    Py_DECREF(obj);
+    return 0;
+}
+
+
+int
+PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+    return PyUnicodeEncodeError_GetStart(exc, start);
+}
+
+
+int
+PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+    ((PyUnicodeErrorObject *)exc)->start = start;
+    return 0;
+}
+
+
+int
+PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+    ((PyUnicodeErrorObject *)exc)->start = start;
+    return 0;
+}
+
+
+int
+PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+    ((PyUnicodeErrorObject *)exc)->start = start;
+    return 0;
+}
+
+
+int
+PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+{
+    Py_ssize_t size;
+    PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
+                                "object");
+    if (!obj)
+        return -1;
+    *end = ((PyUnicodeErrorObject *)exc)->end;
+    size = PyUnicode_GET_SIZE(obj);
+    if (*end<1)
+        *end = 1;
+    if (*end>size)
+        *end = size;
+    Py_DECREF(obj);
+    return 0;
+}
+
+
+int
+PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+{
+    Py_ssize_t size;
+    PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
+                               "object");
+    if (!obj)
+        return -1;
+    *end = ((PyUnicodeErrorObject *)exc)->end;
+    size = PyString_GET_SIZE(obj);
+    if (*end<1)
+        *end = 1;
+    if (*end>size)
+        *end = size;
+    Py_DECREF(obj);
+    return 0;
+}
+
+
+int
+PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
+{
+    return PyUnicodeEncodeError_GetEnd(exc, start);
+}
+
+
+int
+PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+    ((PyUnicodeErrorObject *)exc)->end = end;
+    return 0;
+}
+
+
+int
+PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+    ((PyUnicodeErrorObject *)exc)->end = end;
+    return 0;
+}
+
+
+int
+PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+    ((PyUnicodeErrorObject *)exc)->end = end;
+    return 0;
+}
+
+PyObject *
+PyUnicodeEncodeError_GetReason(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+PyObject *
+PyUnicodeDecodeError_GetReason(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+PyObject *
+PyUnicodeTranslateError_GetReason(PyObject *exc)
+{
+    return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+int
+PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
+{
+    return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+int
+PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
+{
+    return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+int
+PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
+{
+    return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+static int
+UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
+                  PyTypeObject *objecttype)
+{
+    Py_CLEAR(self->encoding);
+    Py_CLEAR(self->object);
+    Py_CLEAR(self->reason);
+
+    if (!PyArg_ParseTuple(args, "O!O!nnO!",
+        &PyString_Type, &self->encoding,
+        objecttype, &self->object,
+        &self->start,
+        &self->end,
+        &PyString_Type, &self->reason)) {
+        self->encoding = self->object = self->reason = NULL;
+        return -1;
+    }
+
+    Py_INCREF(self->encoding);
+    Py_INCREF(self->object);
+    Py_INCREF(self->reason);
+
+    return 0;
+}
+
+static int
+UnicodeError_clear(PyUnicodeErrorObject *self)
+{
+    Py_CLEAR(self->encoding);
+    Py_CLEAR(self->object);
+    Py_CLEAR(self->reason);
+    return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+UnicodeError_dealloc(PyUnicodeErrorObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    UnicodeError_clear(self);
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->encoding);
+    Py_VISIT(self->object);
+    Py_VISIT(self->reason);
+    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyMemberDef UnicodeError_members[] = {
+    {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
+        PyDoc_STR("exception encoding")},
+    {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
+        PyDoc_STR("exception object")},
+    {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
+        PyDoc_STR("exception start")},
+    {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
+        PyDoc_STR("exception end")},
+    {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
+        PyDoc_STR("exception reason")},
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ *    UnicodeEncodeError extends UnicodeError
+ */
+
+static int
+UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+    return UnicodeError_init((PyUnicodeErrorObject *)self, args,
+                             kwds, &PyUnicode_Type);
+}
+
+static PyObject *
+UnicodeEncodeError_str(PyObject *self)
+{
+    PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
+    PyObject *result = NULL;
+    PyObject *reason_str = NULL;
+    PyObject *encoding_str = NULL;
+
+    /* Get reason and encoding as strings, which they might not be if
+       they've been modified after we were contructed. */
+    reason_str = PyObject_Str(uself->reason);
+    if (reason_str == NULL)
+        goto done;
+    encoding_str = PyObject_Str(uself->encoding);
+    if (encoding_str == NULL)
+        goto done;
+
+    if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
+        int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
+        char badchar_str[20];
+        if (badchar <= 0xff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
+        else if (badchar <= 0xffff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
+        else
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
+        result = PyString_FromFormat(
+            "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
+            PyString_AS_STRING(encoding_str),
+            badchar_str,
+            uself->start,
+            PyString_AS_STRING(reason_str));
+    }
+    else {
+        result = PyString_FromFormat(
+            "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
+            PyString_AS_STRING(encoding_str),
+            uself->start,
+            uself->end-1,
+            PyString_AS_STRING(reason_str));
+    }
+done:
+    Py_XDECREF(reason_str);
+    Py_XDECREF(encoding_str);
+    return result;
+}
+
+static PyTypeObject _PyExc_UnicodeEncodeError = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    EXC_MODULE_NAME "UnicodeEncodeError",
+    sizeof(PyUnicodeErrorObject), 0,
+    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
+    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+    (initproc)UnicodeEncodeError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
+
+PyObject *
+PyUnicodeEncodeError_Create(
+    const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
+    Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+    return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
+                                 encoding, object, length, start, end, reason);
+}
+
+
+/*
+ *    UnicodeDecodeError extends UnicodeError
+ */
+
+static int
+UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+    return UnicodeError_init((PyUnicodeErrorObject *)self, args,
+                             kwds, &PyString_Type);
+}
+
+static PyObject *
+UnicodeDecodeError_str(PyObject *self)
+{
+    PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
+    PyObject *result = NULL;
+    PyObject *reason_str = NULL;
+    PyObject *encoding_str = NULL;
+
+    /* Get reason and encoding as strings, which they might not be if
+       they've been modified after we were contructed. */
+    reason_str = PyObject_Str(uself->reason);
+    if (reason_str == NULL)
+        goto done;
+    encoding_str = PyObject_Str(uself->encoding);
+    if (encoding_str == NULL)
+        goto done;
+
+    if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
+        /* FromFormat does not support %02x, so format that separately */
+        char byte[4];
+        PyOS_snprintf(byte, sizeof(byte), "%02x",
+                      ((int)PyString_AS_STRING(uself->object)[uself->start])&0xff);
+        result = PyString_FromFormat(
+            "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
+            PyString_AS_STRING(encoding_str),
+            byte,
+            uself->start,
+            PyString_AS_STRING(reason_str));
+    }
+    else {
+        result = PyString_FromFormat(
+            "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
+            PyString_AS_STRING(encoding_str),
+            uself->start,
+            uself->end-1,
+            PyString_AS_STRING(reason_str));
+    }
+done:
+    Py_XDECREF(reason_str);
+    Py_XDECREF(encoding_str);
+    return result;
+}
+
+static PyTypeObject _PyExc_UnicodeDecodeError = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    EXC_MODULE_NAME "UnicodeDecodeError",
+    sizeof(PyUnicodeErrorObject), 0,
+    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
+    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+    (initproc)UnicodeDecodeError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
+
+PyObject *
+PyUnicodeDecodeError_Create(
+    const char *encoding, const char *object, Py_ssize_t length,
+    Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
+                                 encoding, object, length, start, end, reason);
+}
+
+
+/*
+ *    UnicodeTranslateError extends UnicodeError
+ */
+
+static int
+UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
+                           PyObject *kwds)
+{
+    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+        return -1;
+
+    Py_CLEAR(self->object);
+    Py_CLEAR(self->reason);
+
+    if (!PyArg_ParseTuple(args, "O!nnO!",
+        &PyUnicode_Type, &self->object,
+        &self->start,
+        &self->end,
+        &PyString_Type, &self->reason)) {
+        self->object = self->reason = NULL;
+        return -1;
+    }
+
+    Py_INCREF(self->object);
+    Py_INCREF(self->reason);
+
+    return 0;
+}
+
+
+static PyObject *
+UnicodeTranslateError_str(PyObject *self)
+{
+    PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
+    PyObject *result = NULL;
+    PyObject *reason_str = NULL;
+
+    /* Get reason as a string, which it might not be if it's been
+       modified after we were contructed. */
+    reason_str = PyObject_Str(uself->reason);
+    if (reason_str == NULL)
+        goto done;
+
+    if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
+        int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
+        char badchar_str[20];
+        if (badchar <= 0xff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
+        else if (badchar <= 0xffff)
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
+        else
+            PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
+        result = PyString_FromFormat(
+            "can't translate character u'\\%s' in position %zd: %.400s",
+            badchar_str,
+            uself->start,
+            PyString_AS_STRING(reason_str));
+    } else {
+        result = PyString_FromFormat(
+            "can't translate characters in position %zd-%zd: %.400s",
+            uself->start,
+            uself->end-1,
+            PyString_AS_STRING(reason_str));
+    }
+done:
+    Py_XDECREF(reason_str);
+    return result;
+}
+
+static PyTypeObject _PyExc_UnicodeTranslateError = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    EXC_MODULE_NAME "UnicodeTranslateError",
+    sizeof(PyUnicodeErrorObject), 0,
+    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
+    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+    (initproc)UnicodeTranslateError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
+
+PyObject *
+PyUnicodeTranslateError_Create(
+    const Py_UNICODE *object, Py_ssize_t length,
+    Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
+                                 object, length, start, end, reason);
+}
+#endif
+
+
+/*
+ *    AssertionError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, AssertionError,
+                       "Assertion failed.");
+
+
+/*
+ *    ArithmeticError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ArithmeticError,
+                       "Base class for arithmetic errors.");
+
+
+/*
+ *    FloatingPointError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
+                       "Floating point operation failed.");
+
+
+/*
+ *    OverflowError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
+                       "Result too large to be represented.");
+
+
+/*
+ *    ZeroDivisionError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
+          "Second argument to a division or modulo operation was zero.");
+
+
+/*
+ *    SystemError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, SystemError,
+    "Internal error in the Python interpreter.\n"
+    "\n"
+    "Please report this to the Python maintainer, along with the traceback,\n"
+    "the Python version, and the hardware/OS platform and version.");
+
+
+/*
+ *    ReferenceError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ReferenceError,
+                       "Weak ref proxy used after referent went away.");
+
+
+/*
+ *    MemoryError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
+
+/*
+ *    BufferError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, BufferError, "Buffer error.");
+
+
+/* Warning category docstrings */
+
+/*
+ *    Warning extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, Warning,
+                       "Base class for warning categories.");
+
+
+/*
+ *    UserWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, UserWarning,
+                       "Base class for warnings generated by user code.");
+
+
+/*
+ *    DeprecationWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, DeprecationWarning,
+                       "Base class for warnings about deprecated features.");
+
+
+/*
+ *    PendingDeprecationWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
+    "Base class for warnings about features which will be deprecated\n"
+    "in the future.");
+
+
+/*
+ *    SyntaxWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, SyntaxWarning,
+                       "Base class for warnings about dubious syntax.");
+
+
+/*
+ *    RuntimeWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, RuntimeWarning,
+                 "Base class for warnings about dubious runtime behavior.");
+
+
+/*
+ *    FutureWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, FutureWarning,
+    "Base class for warnings about constructs that will change semantically\n"
+    "in the future.");
+
+
+/*
+ *    ImportWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, ImportWarning,
+          "Base class for warnings about probable mistakes in module imports");
+
+
+/*
+ *    UnicodeWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, UnicodeWarning,
+    "Base class for warnings about Unicode related problems, mostly\n"
+    "related to conversion problems.");
+
+/*
+ *    BytesWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, BytesWarning,
+    "Base class for warnings about bytes and buffer related problems, mostly\n"
+    "related to conversion from str or comparing to str.");
+
+/* Pre-computed MemoryError instance.  Best to create this as early as
+ * possible and not wait until a MemoryError is actually raised!
+ */
+PyObject *PyExc_MemoryErrorInst=NULL;
+
+/* Pre-computed RuntimeError instance for when recursion depth is reached.
+   Meant to be used when normalizing the exception for exceeding the recursion
+   depth will cause its own infinite recursion.
+*/
+PyObject *PyExc_RecursionErrorInst = NULL;
+
+/* module global functions */
+static PyMethodDef functions[] = {
+    /* Sentinel */
+    {NULL, NULL}
+};
+
+#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
+    Py_FatalError("exceptions bootstrapping error.");
+
+#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
+    PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
+    if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
+        Py_FatalError("Module dictionary insertion problem.");
+
+
+PyMODINIT_FUNC
+_PyExc_Init(void)
+{
+    PyObject *m, *bltinmod, *bdict;
+
+    PRE_INIT(BaseException)
+    PRE_INIT(Exception)
+    PRE_INIT(StandardError)
+    PRE_INIT(TypeError)
+    PRE_INIT(StopIteration)
+    PRE_INIT(GeneratorExit)
+    PRE_INIT(SystemExit)
+    PRE_INIT(KeyboardInterrupt)
+    PRE_INIT(ImportError)
+    PRE_INIT(EnvironmentError)
+    PRE_INIT(IOError)
+    PRE_INIT(OSError)
+#ifdef MS_WINDOWS
+    PRE_INIT(WindowsError)
+#endif
+#ifdef __VMS
+    PRE_INIT(VMSError)
+#endif
+    PRE_INIT(EOFError)
+    PRE_INIT(RuntimeError)
+    PRE_INIT(NotImplementedError)
+    PRE_INIT(NameError)
+    PRE_INIT(UnboundLocalError)
+    PRE_INIT(AttributeError)
+    PRE_INIT(SyntaxError)
+    PRE_INIT(IndentationError)
+    PRE_INIT(TabError)
+    PRE_INIT(LookupError)
+    PRE_INIT(IndexError)
+    PRE_INIT(KeyError)
+    PRE_INIT(ValueError)
+    PRE_INIT(UnicodeError)
+#ifdef Py_USING_UNICODE
+    PRE_INIT(UnicodeEncodeError)
+    PRE_INIT(UnicodeDecodeError)
+    PRE_INIT(UnicodeTranslateError)
+#endif
+    PRE_INIT(AssertionError)
+    PRE_INIT(ArithmeticError)
+    PRE_INIT(FloatingPointError)
+    PRE_INIT(OverflowError)
+    PRE_INIT(ZeroDivisionError)
+    PRE_INIT(SystemError)
+    PRE_INIT(ReferenceError)
+    PRE_INIT(MemoryError)
+    PRE_INIT(BufferError)
+    PRE_INIT(Warning)
+    PRE_INIT(UserWarning)
+    PRE_INIT(DeprecationWarning)
+    PRE_INIT(PendingDeprecationWarning)
+    PRE_INIT(SyntaxWarning)
+    PRE_INIT(RuntimeWarning)
+    PRE_INIT(FutureWarning)
+    PRE_INIT(ImportWarning)
+    PRE_INIT(UnicodeWarning)
+    PRE_INIT(BytesWarning)
+
+    m = Py_InitModule4("exceptions", functions, exceptions_doc,
+        (PyObject *)NULL, PYTHON_API_VERSION);
+    if (m == NULL)
+        return;
+
+    bltinmod = PyImport_ImportModule("__builtin__");
+    if (bltinmod == NULL)
+        Py_FatalError("exceptions bootstrapping error.");
+    bdict = PyModule_GetDict(bltinmod);
+    if (bdict == NULL)
+        Py_FatalError("exceptions bootstrapping error.");
+
+    POST_INIT(BaseException)
+    POST_INIT(Exception)
+    POST_INIT(StandardError)
+    POST_INIT(TypeError)
+    POST_INIT(StopIteration)
+    POST_INIT(GeneratorExit)
+    POST_INIT(SystemExit)
+    POST_INIT(KeyboardInterrupt)
+    POST_INIT(ImportError)
+    POST_INIT(EnvironmentError)
+    POST_INIT(IOError)
+    POST_INIT(OSError)
+#ifdef MS_WINDOWS
+    POST_INIT(WindowsError)
+#endif
+#ifdef __VMS
+    POST_INIT(VMSError)
+#endif
+    POST_INIT(EOFError)
+    POST_INIT(RuntimeError)
+    POST_INIT(NotImplementedError)
+    POST_INIT(NameError)
+    POST_INIT(UnboundLocalError)
+    POST_INIT(AttributeError)
+    POST_INIT(SyntaxError)
+    POST_INIT(IndentationError)
+    POST_INIT(TabError)
+    POST_INIT(LookupError)
+    POST_INIT(IndexError)
+    POST_INIT(KeyError)
+    POST_INIT(ValueError)
+    POST_INIT(UnicodeError)
+#ifdef Py_USING_UNICODE
+    POST_INIT(UnicodeEncodeError)
+    POST_INIT(UnicodeDecodeError)
+    POST_INIT(UnicodeTranslateError)
+#endif
+    POST_INIT(AssertionError)
+    POST_INIT(ArithmeticError)
+    POST_INIT(FloatingPointError)
+    POST_INIT(OverflowError)
+    POST_INIT(ZeroDivisionError)
+    POST_INIT(SystemError)
+    POST_INIT(ReferenceError)
+    POST_INIT(MemoryError)
+    POST_INIT(BufferError)
+    POST_INIT(Warning)
+    POST_INIT(UserWarning)
+    POST_INIT(DeprecationWarning)
+    POST_INIT(PendingDeprecationWarning)
+    POST_INIT(SyntaxWarning)
+    POST_INIT(RuntimeWarning)
+    POST_INIT(FutureWarning)
+    POST_INIT(ImportWarning)
+    POST_INIT(UnicodeWarning)
+    POST_INIT(BytesWarning)
+
+    PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
+    if (!PyExc_MemoryErrorInst)
+        Py_FatalError("Cannot pre-allocate MemoryError instance");
+
+    PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL);
+    if (!PyExc_RecursionErrorInst)
+        Py_FatalError("Cannot pre-allocate RuntimeError instance for "
+                        "recursion errors");
+    else {
+        PyBaseExceptionObject *err_inst =
+            (PyBaseExceptionObject *)PyExc_RecursionErrorInst;
+        PyObject *args_tuple;
+        PyObject *exc_message;
+        exc_message = PyString_FromString("maximum recursion depth exceeded");
+        if (!exc_message)
+            Py_FatalError("cannot allocate argument for RuntimeError "
+                            "pre-allocation");
+        args_tuple = PyTuple_Pack(1, exc_message);
+        if (!args_tuple)
+            Py_FatalError("cannot allocate tuple for RuntimeError "
+                            "pre-allocation");
+        Py_DECREF(exc_message);
+        if (BaseException_init(err_inst, args_tuple, NULL))
+            Py_FatalError("init of pre-allocated RuntimeError failed");
+        Py_DECREF(args_tuple);
+    }
+    Py_DECREF(bltinmod);
+}
+
+void
+_PyExc_Fini(void)
+{
+    Py_CLEAR(PyExc_MemoryErrorInst);
+    Py_CLEAR(PyExc_RecursionErrorInst);
+}
diff --git a/Python-2.7.5/Objects/fileobject.c b/Python-2.7.5/Objects/fileobject.c
new file mode 100644
index 0000000..76cdf74
--- /dev/null
+++ b/Python-2.7.5/Objects/fileobject.c
@@ -0,0 +1,2884 @@
+/* File object implementation */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef MS_WINDOWS
+#define fileno _fileno
+/* can simulate truncate with Win32 API functions; see file_truncate */
+#define HAVE_FTRUNCATE
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#include <io.h>
+#endif
+
+#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_GETC_UNLOCKED
+#define GETC(f) getc_unlocked(f)
+#define FLOCKFILE(f) flockfile(f)
+#define FUNLOCKFILE(f) funlockfile(f)
+#else
+#define GETC(f) getc(f)
+#define FLOCKFILE(f)
+#define FUNLOCKFILE(f)
+#endif
+
+/* Bits in f_newlinetypes */
+#define NEWLINE_UNKNOWN 0       /* No newline seen, yet */
+#define NEWLINE_CR 1            /* \r newline seen */
+#define NEWLINE_LF 2            /* \n newline seen */
+#define NEWLINE_CRLF 4          /* \r\n newline seen */
+
+/*
+ * These macros release the GIL while preventing the f_close() function being
+ * called in the interval between them.  For that purpose, a running total of
+ * the number of currently running unlocked code sections is kept in
+ * the unlocked_count field of the PyFileObject. The close() method raises
+ * an IOError if that field is non-zero.  See issue #815646, #595601.
+ */
+
+#define FILE_BEGIN_ALLOW_THREADS(fobj) \
+{ \
+    fobj->unlocked_count++; \
+    Py_BEGIN_ALLOW_THREADS
+
+#define FILE_END_ALLOW_THREADS(fobj) \
+    Py_END_ALLOW_THREADS \
+    fobj->unlocked_count--; \
+    assert(fobj->unlocked_count >= 0); \
+}
+
+#define FILE_ABORT_ALLOW_THREADS(fobj) \
+    Py_BLOCK_THREADS \
+    fobj->unlocked_count--; \
+    assert(fobj->unlocked_count >= 0);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FILE *
+PyFile_AsFile(PyObject *f)
+{
+    if (f == NULL || !PyFile_Check(f))
+        return NULL;
+    else
+        return ((PyFileObject *)f)->f_fp;
+}
+
+void PyFile_IncUseCount(PyFileObject *fobj)
+{
+    fobj->unlocked_count++;
+}
+
+void PyFile_DecUseCount(PyFileObject *fobj)
+{
+    fobj->unlocked_count--;
+    assert(fobj->unlocked_count >= 0);
+}
+
+PyObject *
+PyFile_Name(PyObject *f)
+{
+    if (f == NULL || !PyFile_Check(f))
+        return NULL;
+    else
+        return ((PyFileObject *)f)->f_name;
+}
+
+/* This is a safe wrapper around PyObject_Print to print to the FILE
+   of a PyFileObject. PyObject_Print releases the GIL but knows nothing
+   about PyFileObject. */
+static int
+file_PyObject_Print(PyObject *op, PyFileObject *f, int flags)
+{
+    int result;
+    PyFile_IncUseCount(f);
+    result = PyObject_Print(op, f->f_fp, flags);
+    PyFile_DecUseCount(f);
+    return result;
+}
+
+/* On Unix, fopen will succeed for directories.
+   In Python, there should be no file objects referring to
+   directories, so we need a check.  */
+
+static PyFileObject*
+dircheck(PyFileObject* f)
+{
+#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
+    struct stat buf;
+    if (f->f_fp == NULL)
+        return f;
+    if (fstat(fileno(f->f_fp), &buf) == 0 &&
+        S_ISDIR(buf.st_mode)) {
+        char *msg = strerror(EISDIR);
+        PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)",
+                                              EISDIR, msg, f->f_name);
+        PyErr_SetObject(PyExc_IOError, exc);
+        Py_XDECREF(exc);
+        return NULL;
+    }
+#endif
+    return f;
+}
+
+
+static PyObject *
+fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
+                 int (*close)(FILE *))
+{
+    assert(name != NULL);
+    assert(f != NULL);
+    assert(PyFile_Check(f));
+    assert(f->f_fp == NULL);
+
+    Py_DECREF(f->f_name);
+    Py_DECREF(f->f_mode);
+    Py_DECREF(f->f_encoding);
+    Py_DECREF(f->f_errors);
+
+    Py_INCREF(name);
+    f->f_name = name;
+
+    f->f_mode = PyString_FromString(mode);
+
+    f->f_close = close;
+    f->f_softspace = 0;
+    f->f_binary = strchr(mode,'b') != NULL;
+    f->f_buf = NULL;
+    f->f_univ_newline = (strchr(mode, 'U') != NULL);
+    f->f_newlinetypes = NEWLINE_UNKNOWN;
+    f->f_skipnextlf = 0;
+    Py_INCREF(Py_None);
+    f->f_encoding = Py_None;
+    Py_INCREF(Py_None);
+    f->f_errors = Py_None;
+    f->readable = f->writable = 0;
+    if (strchr(mode, 'r') != NULL || f->f_univ_newline)
+        f->readable = 1;
+    if (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL)
+        f->writable = 1;
+    if (strchr(mode, '+') != NULL)
+        f->readable = f->writable = 1;
+
+    if (f->f_mode == NULL)
+        return NULL;
+    f->f_fp = fp;
+    f = dircheck(f);
+    return (PyObject *) f;
+}
+
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+#define Py_VERIFY_WINNT
+/* The CRT on windows compiled with Visual Studio 2005 and higher may
+ * assert if given invalid mode strings.  This is all fine and well
+ * in static languages like C where the mode string is typcially hard
+ * coded.  But in Python, were we pass in the mode string from the user,
+ * we need to verify it first manually
+ */
+static int _PyVerify_Mode_WINNT(const char *mode)
+{
+    /* See if mode string is valid on Windows to avoid hard assertions */
+    /* remove leading spacese */
+    int singles = 0;
+    int pairs = 0;
+    int encoding = 0;
+    const char *s, *c;
+
+    while(*mode == ' ') /* strip initial spaces */
+        ++mode;
+    if (!strchr("rwa", *mode)) /* must start with one of these */
+        return 0;
+    while (*++mode) {
+        if (*mode == ' ' || *mode == 'N') /* ignore spaces and N */
+            continue;
+        s = "+TD"; /* each of this can appear only once */
+        c = strchr(s, *mode);
+        if (c) {
+            ptrdiff_t idx = s-c;
+            if (singles & (1<<idx))
+                return 0;
+            singles |= (1<<idx);
+            continue;
+        }
+        s = "btcnSR"; /* only one of each letter in the pairs allowed */
+        c = strchr(s, *mode);
+        if (c) {
+            ptrdiff_t idx = (s-c)/2;
+            if (pairs & (1<<idx))
+                return 0;
+            pairs |= (1<<idx);
+            continue;
+        }
+        if (*mode == ',') {
+            encoding = 1;
+            break;
+        }
+        return 0; /* found an invalid char */
+    }
+
+    if (encoding) {
+        char *e[] = {"UTF-8", "UTF-16LE", "UNICODE"};
+        while (*mode == ' ')
+            ++mode;
+        /* find 'ccs =' */
+        if (strncmp(mode, "ccs", 3))
+            return 0;
+        mode += 3;
+        while (*mode == ' ')
+            ++mode;
+        if (*mode != '=')
+            return 0;
+        while (*mode == ' ')
+            ++mode;
+        for(encoding = 0; encoding<_countof(e); ++encoding) {
+            size_t l = strlen(e[encoding]);
+            if (!strncmp(mode, e[encoding], l)) {
+                mode += l; /* found a valid encoding */
+                break;
+            }
+        }
+        if (encoding == _countof(e))
+            return 0;
+    }
+    /* skip trailing spaces */
+    while (*mode == ' ')
+        ++mode;
+
+    return *mode == '\0'; /* must be at the end of the string */
+}
+#endif
+
+/* check for known incorrect mode strings - problem is, platforms are
+   free to accept any mode characters they like and are supposed to
+   ignore stuff they don't understand... write or append mode with
+   universal newline support is expressly forbidden by PEP 278.
+   Additionally, remove the 'U' from the mode string as platforms
+   won't know what it is. Non-zero return signals an exception */
+int
+_PyFile_SanitizeMode(char *mode)
+{
+    char *upos;
+    size_t len = strlen(mode);
+
+    if (!len) {
+        PyErr_SetString(PyExc_ValueError, "empty mode string");
+        return -1;
+    }
+
+    upos = strchr(mode, 'U');
+    if (upos) {
+        memmove(upos, upos+1, len-(upos-mode)); /* incl null char */
+
+        if (mode[0] == 'w' || mode[0] == 'a') {
+            PyErr_Format(PyExc_ValueError, "universal newline "
+                         "mode can only be used with modes "
+                         "starting with 'r'");
+            return -1;
+        }
+
+        if (mode[0] != 'r') {
+            memmove(mode+1, mode, strlen(mode)+1);
+            mode[0] = 'r';
+        }
+
+        if (!strchr(mode, 'b')) {
+            memmove(mode+2, mode+1, strlen(mode));
+            mode[1] = 'b';
+        }
+    } else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
+        PyErr_Format(PyExc_ValueError, "mode string must begin with "
+                    "one of 'r', 'w', 'a' or 'U', not '%.200s'", mode);
+        return -1;
+    }
+#ifdef Py_VERIFY_WINNT
+    /* additional checks on NT with visual studio 2005 and higher */
+    if (!_PyVerify_Mode_WINNT(mode)) {
+        PyErr_Format(PyExc_ValueError, "Invalid mode ('%.50s')", mode);
+        return -1;
+    }
+#endif
+    return 0;
+}
+
+static PyObject *
+open_the_file(PyFileObject *f, char *name, char *mode)
+{
+    char *newmode;
+    assert(f != NULL);
+    assert(PyFile_Check(f));
+#ifdef MS_WINDOWS
+    /* windows ignores the passed name in order to support Unicode */
+    assert(f->f_name != NULL);
+#else
+    assert(name != NULL);
+#endif
+    assert(mode != NULL);
+    assert(f->f_fp == NULL);
+
+    /* probably need to replace 'U' by 'rb' */
+    newmode = PyMem_MALLOC(strlen(mode) + 3);
+    if (!newmode) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+    strcpy(newmode, mode);
+
+    if (_PyFile_SanitizeMode(newmode)) {
+        f = NULL;
+        goto cleanup;
+    }
+
+    /* rexec.py can't stop a user from getting the file() constructor --
+       all they have to do is get *any* file object f, and then do
+       type(f).  Here we prevent them from doing damage with it. */
+    if (PyEval_GetRestricted()) {
+        PyErr_SetString(PyExc_IOError,
+        "file() constructor not accessible in restricted mode");
+        f = NULL;
+        goto cleanup;
+    }
+    errno = 0;
+
+#ifdef MS_WINDOWS
+    if (PyUnicode_Check(f->f_name)) {
+        PyObject *wmode;
+        wmode = PyUnicode_DecodeASCII(newmode, strlen(newmode), NULL);
+        if (f->f_name && wmode) {
+            FILE_BEGIN_ALLOW_THREADS(f)
+            /* PyUnicode_AS_UNICODE OK without thread
+               lock as it is a simple dereference. */
+            f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name),
+                              PyUnicode_AS_UNICODE(wmode));
+            FILE_END_ALLOW_THREADS(f)
+        }
+        Py_XDECREF(wmode);
+    }
+#endif
+    if (NULL == f->f_fp && NULL != name) {
+        FILE_BEGIN_ALLOW_THREADS(f)
+        f->f_fp = fopen(name, newmode);
+        FILE_END_ALLOW_THREADS(f)
+    }
+
+    if (f->f_fp == NULL) {
+#if defined  _MSC_VER && (_MSC_VER < 1400 || !defined(__STDC_SECURE_LIB__))
+        /* MSVC 6 (Microsoft) leaves errno at 0 for bad mode strings,
+         * across all Windows flavors.  When it sets EINVAL varies
+         * across Windows flavors, the exact conditions aren't
+         * documented, and the answer lies in the OS's implementation
+         * of Win32's CreateFile function (whose source is secret).
+         * Seems the best we can do is map EINVAL to ENOENT.
+         * Starting with Visual Studio .NET 2005, EINVAL is correctly
+         * set by our CRT error handler (set in exceptions.c.)
+         */
+        if (errno == 0)         /* bad mode string */
+            errno = EINVAL;
+        else if (errno == EINVAL) /* unknown, but not a mode string */
+            errno = ENOENT;
+#endif
+        /* EINVAL is returned when an invalid filename or
+         * an invalid mode is supplied. */
+        if (errno == EINVAL) {
+            PyObject *v;
+            char message[100];
+            PyOS_snprintf(message, 100,
+                "invalid mode ('%.50s') or filename", mode);
+            v = Py_BuildValue("(isO)", errno, message, f->f_name);
+            if (v != NULL) {
+                PyErr_SetObject(PyExc_IOError, v);
+                Py_DECREF(v);
+            }
+        }
+        else
+            PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name);
+        f = NULL;
+    }
+    if (f != NULL)
+        f = dircheck(f);
+
+cleanup:
+    PyMem_FREE(newmode);
+
+    return (PyObject *)f;
+}
+
+static PyObject *
+close_the_file(PyFileObject *f)
+{
+    int sts = 0;
+    int (*local_close)(FILE *);
+    FILE *local_fp = f->f_fp;
+    char *local_setbuf = f->f_setbuf;
+    if (local_fp != NULL) {
+        local_close = f->f_close;
+        if (local_close != NULL && f->unlocked_count > 0) {
+            if (f->ob_refcnt > 0) {
+                PyErr_SetString(PyExc_IOError,
+                    "close() called during concurrent "
+                    "operation on the same file object.");
+            } else {
+                /* This should not happen unless someone is
+                 * carelessly playing with the PyFileObject
+                 * struct fields and/or its associated FILE
+                 * pointer. */
+                PyErr_SetString(PyExc_SystemError,
+                    "PyFileObject locking error in "
+                    "destructor (refcnt <= 0 at close).");
+            }
+            return NULL;
+        }
+        /* NULL out the FILE pointer before releasing the GIL, because
+         * it will not be valid anymore after the close() function is
+         * called. */
+        f->f_fp = NULL;
+        if (local_close != NULL) {
+            /* Issue #9295: must temporarily reset f_setbuf so that another
+               thread doesn't free it when running file_close() concurrently.
+               Otherwise this close() will crash when flushing the buffer. */
+            f->f_setbuf = NULL;
+            Py_BEGIN_ALLOW_THREADS
+            errno = 0;
+            sts = (*local_close)(local_fp);
+            Py_END_ALLOW_THREADS
+            f->f_setbuf = local_setbuf;
+            if (sts == EOF)
+                return PyErr_SetFromErrno(PyExc_IOError);
+            if (sts != 0)
+                return PyInt_FromLong((long)sts);
+        }
+    }
+    Py_RETURN_NONE;
+}
+
+PyObject *
+PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
+{
+    PyFileObject *f;
+    PyObject *o_name;
+
+    f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type, NULL, NULL);
+    if (f == NULL)
+        return NULL;
+    o_name = PyString_FromString(name);
+    if (o_name == NULL) {
+        if (close != NULL && fp != NULL)
+            close(fp);
+        Py_DECREF(f);
+        return NULL;
+    }
+    if (fill_file_fields(f, fp, o_name, mode, close) == NULL) {
+        Py_DECREF(f);
+        Py_DECREF(o_name);
+        return NULL;
+    }
+    Py_DECREF(o_name);
+    return (PyObject *)f;
+}
+
+PyObject *
+PyFile_FromString(char *name, char *mode)
+{
+    extern int fclose(FILE *);
+    PyFileObject *f;
+
+    f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
+    if (f != NULL) {
+        if (open_the_file(f, name, mode) == NULL) {
+            Py_DECREF(f);
+            f = NULL;
+        }
+    }
+    return (PyObject *)f;
+}
+
+void
+PyFile_SetBufSize(PyObject *f, int bufsize)
+{
+    PyFileObject *file = (PyFileObject *)f;
+    if (bufsize >= 0) {
+        int type;
+        switch (bufsize) {
+        case 0:
+            type = _IONBF;
+            break;
+#ifdef HAVE_SETVBUF
+        case 1:
+            type = _IOLBF;
+            bufsize = BUFSIZ;
+            break;
+#endif
+        default:
+            type = _IOFBF;
+#ifndef HAVE_SETVBUF
+            bufsize = BUFSIZ;
+#endif
+            break;
+        }
+        fflush(file->f_fp);
+        if (type == _IONBF) {
+            PyMem_Free(file->f_setbuf);
+            file->f_setbuf = NULL;
+        } else {
+            file->f_setbuf = (char *)PyMem_Realloc(file->f_setbuf,
+                                                    bufsize);
+        }
+#ifdef HAVE_SETVBUF
+        setvbuf(file->f_fp, file->f_setbuf, type, bufsize);
+#else /* !HAVE_SETVBUF */
+        setbuf(file->f_fp, file->f_setbuf);
+#endif /* !HAVE_SETVBUF */
+    }
+}
+
+/* Set the encoding used to output Unicode strings.
+   Return 1 on success, 0 on failure. */
+
+int
+PyFile_SetEncoding(PyObject *f, const char *enc)
+{
+    return PyFile_SetEncodingAndErrors(f, enc, NULL);
+}
+
+int
+PyFile_SetEncodingAndErrors(PyObject *f, const char *enc, char* errors)
+{
+    PyFileObject *file = (PyFileObject*)f;
+    PyObject *str, *oerrors;
+
+    assert(PyFile_Check(f));
+    str = PyString_FromString(enc);
+    if (!str)
+        return 0;
+    if (errors) {
+        oerrors = PyString_FromString(errors);
+        if (!oerrors) {
+            Py_DECREF(str);
+            return 0;
+        }
+    } else {
+        oerrors = Py_None;
+        Py_INCREF(Py_None);
+    }
+    Py_DECREF(file->f_encoding);
+    file->f_encoding = str;
+    Py_DECREF(file->f_errors);
+    file->f_errors = oerrors;
+    return 1;
+}
+
+static PyObject *
+err_closed(void)
+{
+    PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
+    return NULL;
+}
+
+static PyObject *
+err_mode(char *action)
+{
+    PyErr_Format(PyExc_IOError, "File not open for %s", action);
+    return NULL;
+}
+
+/* Refuse regular file I/O if there's data in the iteration-buffer.
+ * Mixing them would cause data to arrive out of order, as the read*
+ * methods don't use the iteration buffer. */
+static PyObject *
+err_iterbuffered(void)
+{
+    PyErr_SetString(PyExc_ValueError,
+        "Mixing iteration and read methods would lose data");
+    return NULL;
+}
+
+static void drop_readahead(PyFileObject *);
+
+/* Methods */
+
+static void
+file_dealloc(PyFileObject *f)
+{
+    PyObject *ret;
+    if (f->weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) f);
+    ret = close_the_file(f);
+    if (!ret) {
+        PySys_WriteStderr("close failed in file object destructor:\n");
+        PyErr_Print();
+    }
+    else {
+        Py_DECREF(ret);
+    }
+    PyMem_Free(f->f_setbuf);
+    Py_XDECREF(f->f_name);
+    Py_XDECREF(f->f_mode);
+    Py_XDECREF(f->f_encoding);
+    Py_XDECREF(f->f_errors);
+    drop_readahead(f);
+    Py_TYPE(f)->tp_free((PyObject *)f);
+}
+
+static PyObject *
+file_repr(PyFileObject *f)
+{
+    PyObject *ret = NULL;
+    PyObject *name = NULL;
+    if (PyUnicode_Check(f->f_name)) {
+#ifdef Py_USING_UNICODE
+        const char *name_str;
+        name = PyUnicode_AsUnicodeEscapeString(f->f_name);
+        name_str = name ? PyString_AsString(name) : "?";
+        ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>",
+                           f->f_fp == NULL ? "closed" : "open",
+                           name_str,
+                           PyString_AsString(f->f_mode),
+                           f);
+        Py_XDECREF(name);
+        return ret;
+#endif
+    } else {
+        name = PyObject_Repr(f->f_name);
+        if (name == NULL)
+            return NULL;
+        ret = PyString_FromFormat("<%s file %s, mode '%s' at %p>",
+                           f->f_fp == NULL ? "closed" : "open",
+                           PyString_AsString(name),
+                           PyString_AsString(f->f_mode),
+                           f);
+        Py_XDECREF(name);
+        return ret;
+    }
+}
+
+static PyObject *
+file_close(PyFileObject *f)
+{
+    PyObject *sts = close_the_file(f);
+    if (sts) {
+        PyMem_Free(f->f_setbuf);
+        f->f_setbuf = NULL;
+    }
+    return sts;
+}
+
+
+/* Our very own off_t-like type, 64-bit if possible */
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+typedef off_t Py_off_t;
+#elif SIZEOF_OFF_T >= 8
+typedef off_t Py_off_t;
+#elif SIZEOF_FPOS_T >= 8
+typedef fpos_t Py_off_t;
+#else
+#error "Large file support, but neither off_t nor fpos_t is large enough."
+#endif
+
+
+/* a portable fseek() function
+   return 0 on success, non-zero on failure (with errno set) */
+static int
+_portable_fseek(FILE *fp, Py_off_t offset, int whence)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+    return fseek(fp, offset, whence);
+#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
+    return fseeko(fp, offset, whence);
+#elif defined(HAVE_FSEEK64)
+    return fseek64(fp, offset, whence);
+#elif defined(__BEOS__)
+    return _fseek(fp, offset, whence);
+#elif SIZEOF_FPOS_T >= 8
+    /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
+       and fgetpos() to implement fseek()*/
+    fpos_t pos;
+    switch (whence) {
+    case SEEK_END:
+#ifdef MS_WINDOWS
+        fflush(fp);
+        if (_lseeki64(fileno(fp), 0, 2) == -1)
+            return -1;
+#else
+        if (fseek(fp, 0, SEEK_END) != 0)
+            return -1;
+#endif
+        /* fall through */
+    case SEEK_CUR:
+        if (fgetpos(fp, &pos) != 0)
+            return -1;
+        offset += pos;
+        break;
+    /* case SEEK_SET: break; */
+    }
+    return fsetpos(fp, &offset);
+#else
+#error "Large file support, but no way to fseek."
+#endif
+}
+
+
+/* a portable ftell() function
+   Return -1 on failure with errno set appropriately, current file
+   position on success */
+static Py_off_t
+_portable_ftell(FILE* fp)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+    return ftell(fp);
+#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
+    return ftello(fp);
+#elif defined(HAVE_FTELL64)
+    return ftell64(fp);
+#elif SIZEOF_FPOS_T >= 8
+    fpos_t pos;
+    if (fgetpos(fp, &pos) != 0)
+        return -1;
+    return pos;
+#else
+#error "Large file support, but no way to ftell."
+#endif
+}
+
+
+static PyObject *
+file_seek(PyFileObject *f, PyObject *args)
+{
+    int whence;
+    int ret;
+    Py_off_t offset;
+    PyObject *offobj, *off_index;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    drop_readahead(f);
+    whence = 0;
+    if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
+        return NULL;
+    off_index = PyNumber_Index(offobj);
+    if (!off_index) {
+        if (!PyFloat_Check(offobj))
+            return NULL;
+        /* Deprecated in 2.6 */
+        PyErr_Clear();
+        if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                         "integer argument expected, got float",
+                         1) < 0)
+            return NULL;
+        off_index = offobj;
+        Py_INCREF(offobj);
+    }
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+    offset = PyInt_AsLong(off_index);
+#else
+    offset = PyLong_Check(off_index) ?
+        PyLong_AsLongLong(off_index) : PyInt_AsLong(off_index);
+#endif
+    Py_DECREF(off_index);
+    if (PyErr_Occurred())
+        return NULL;
+
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    ret = _portable_fseek(f->f_fp, offset, whence);
+    FILE_END_ALLOW_THREADS(f)
+
+    if (ret != 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        clearerr(f->f_fp);
+        return NULL;
+    }
+    f->f_skipnextlf = 0;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+#ifdef HAVE_FTRUNCATE
+static PyObject *
+file_truncate(PyFileObject *f, PyObject *args)
+{
+    Py_off_t newsize;
+    PyObject *newsizeobj = NULL;
+    Py_off_t initialpos;
+    int ret;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->writable)
+        return err_mode("writing");
+    if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj))
+        return NULL;
+
+    /* Get current file position.  If the file happens to be open for
+     * update and the last operation was an input operation, C doesn't
+     * define what the later fflush() will do, but we promise truncate()
+     * won't change the current position (and fflush() *does* change it
+     * then at least on Windows).  The easiest thing is to capture
+     * current pos now and seek back to it at the end.
+     */
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    initialpos = _portable_ftell(f->f_fp);
+    FILE_END_ALLOW_THREADS(f)
+    if (initialpos == -1)
+        goto onioerror;
+
+    /* Set newsize to current postion if newsizeobj NULL, else to the
+     * specified value.
+     */
+    if (newsizeobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+        newsize = PyInt_AsLong(newsizeobj);
+#else
+        newsize = PyLong_Check(newsizeobj) ?
+                        PyLong_AsLongLong(newsizeobj) :
+                PyInt_AsLong(newsizeobj);
+#endif
+        if (PyErr_Occurred())
+            return NULL;
+    }
+    else /* default to current position */
+        newsize = initialpos;
+
+    /* Flush the stream.  We're mixing stream-level I/O with lower-level
+     * I/O, and a flush may be necessary to synch both platform views
+     * of the current file state.
+     */
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    ret = fflush(f->f_fp);
+    FILE_END_ALLOW_THREADS(f)
+    if (ret != 0)
+        goto onioerror;
+
+#ifdef MS_WINDOWS
+    /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
+       so don't even try using it. */
+    {
+        HANDLE hFile;
+
+        /* Have to move current pos to desired endpoint on Windows. */
+        FILE_BEGIN_ALLOW_THREADS(f)
+        errno = 0;
+        ret = _portable_fseek(f->f_fp, newsize, SEEK_SET) != 0;
+        FILE_END_ALLOW_THREADS(f)
+        if (ret)
+            goto onioerror;
+
+        /* Truncate.  Note that this may grow the file! */
+        FILE_BEGIN_ALLOW_THREADS(f)
+        errno = 0;
+        hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
+        ret = hFile == (HANDLE)-1;
+        if (ret == 0) {
+            ret = SetEndOfFile(hFile) == 0;
+            if (ret)
+                errno = EACCES;
+        }
+        FILE_END_ALLOW_THREADS(f)
+        if (ret)
+            goto onioerror;
+    }
+#else
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    ret = ftruncate(fileno(f->f_fp), newsize);
+    FILE_END_ALLOW_THREADS(f)
+    if (ret != 0)
+        goto onioerror;
+#endif /* !MS_WINDOWS */
+
+    /* Restore original file position. */
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    ret = _portable_fseek(f->f_fp, initialpos, SEEK_SET) != 0;
+    FILE_END_ALLOW_THREADS(f)
+    if (ret)
+        goto onioerror;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+
+onioerror:
+    PyErr_SetFromErrno(PyExc_IOError);
+    clearerr(f->f_fp);
+    return NULL;
+}
+#endif /* HAVE_FTRUNCATE */
+
+static PyObject *
+file_tell(PyFileObject *f)
+{
+    Py_off_t pos;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    pos = _portable_ftell(f->f_fp);
+    FILE_END_ALLOW_THREADS(f)
+
+    if (pos == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        clearerr(f->f_fp);
+        return NULL;
+    }
+    if (f->f_skipnextlf) {
+        int c;
+        c = GETC(f->f_fp);
+        if (c == '\n') {
+            f->f_newlinetypes |= NEWLINE_CRLF;
+            pos++;
+            f->f_skipnextlf = 0;
+        } else if (c != EOF) ungetc(c, f->f_fp);
+    }
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+    return PyInt_FromLong(pos);
+#else
+    return PyLong_FromLongLong(pos);
+#endif
+}
+
+static PyObject *
+file_fileno(PyFileObject *f)
+{
+    if (f->f_fp == NULL)
+        return err_closed();
+    return PyInt_FromLong((long) fileno(f->f_fp));
+}
+
+static PyObject *
+file_flush(PyFileObject *f)
+{
+    int res;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    res = fflush(f->f_fp);
+    FILE_END_ALLOW_THREADS(f)
+    if (res != 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        clearerr(f->f_fp);
+        return NULL;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+file_isatty(PyFileObject *f)
+{
+    long res;
+    if (f->f_fp == NULL)
+        return err_closed();
+    FILE_BEGIN_ALLOW_THREADS(f)
+    res = isatty((int)fileno(f->f_fp));
+    FILE_END_ALLOW_THREADS(f)
+    return PyBool_FromLong(res);
+}
+
+
+#if BUFSIZ < 8192
+#define SMALLCHUNK 8192
+#else
+#define SMALLCHUNK BUFSIZ
+#endif
+
+static size_t
+new_buffersize(PyFileObject *f, size_t currentsize)
+{
+#ifdef HAVE_FSTAT
+    off_t pos, end;
+    struct stat st;
+    if (fstat(fileno(f->f_fp), &st) == 0) {
+        end = st.st_size;
+        /* The following is not a bug: we really need to call lseek()
+           *and* ftell().  The reason is that some stdio libraries
+           mistakenly flush their buffer when ftell() is called and
+           the lseek() call it makes fails, thereby throwing away
+           data that cannot be recovered in any way.  To avoid this,
+           we first test lseek(), and only call ftell() if lseek()
+           works.  We can't use the lseek() value either, because we
+           need to take the amount of buffered data into account.
+           (Yet another reason why stdio stinks. :-) */
+        pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
+        if (pos >= 0) {
+            pos = ftell(f->f_fp);
+        }
+        if (pos < 0)
+            clearerr(f->f_fp);
+        if (end > pos && pos >= 0)
+            return currentsize + end - pos + 1;
+        /* Add 1 so if the file were to grow we'd notice. */
+    }
+#endif
+    /* Expand the buffer by an amount proportional to the current size,
+       giving us amortized linear-time behavior. Use a less-than-double
+       growth factor to avoid excessive allocation. */
+    return currentsize + (currentsize >> 3) + 6;
+}
+
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK || (x) == EAGAIN)
+#else
+#ifdef EWOULDBLOCK
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EAGAIN)
+#else
+#define BLOCKED_ERRNO(x) 0
+#endif
+#endif
+#endif
+
+static PyObject *
+file_read(PyFileObject *f, PyObject *args)
+{
+    long bytesrequested = -1;
+    size_t bytesread, buffersize, chunksize;
+    PyObject *v;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->readable)
+        return err_mode("reading");
+    /* refuse to mix with f.next() */
+    if (f->f_buf != NULL &&
+        (f->f_bufend - f->f_bufptr) > 0 &&
+        f->f_buf[0] != '\0')
+        return err_iterbuffered();
+    if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
+        return NULL;
+    if (bytesrequested < 0)
+        buffersize = new_buffersize(f, (size_t)0);
+    else
+        buffersize = bytesrequested;
+    if (buffersize > PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+    "requested number of bytes is more than a Python string can hold");
+        return NULL;
+    }
+    v = PyString_FromStringAndSize((char *)NULL, buffersize);
+    if (v == NULL)
+        return NULL;
+    bytesread = 0;
+    for (;;) {
+        int interrupted;
+        FILE_BEGIN_ALLOW_THREADS(f)
+        errno = 0;
+        chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread,
+                  buffersize - bytesread, f->f_fp, (PyObject *)f);
+        interrupted = ferror(f->f_fp) && errno == EINTR;
+        FILE_END_ALLOW_THREADS(f)
+        if (interrupted) {
+            clearerr(f->f_fp);
+            if (PyErr_CheckSignals()) {
+                Py_DECREF(v);
+                return NULL;
+            }
+        }
+        if (chunksize == 0) {
+            if (interrupted)
+                continue;
+            if (!ferror(f->f_fp))
+                break;
+            clearerr(f->f_fp);
+            /* When in non-blocking mode, data shouldn't
+             * be discarded if a blocking signal was
+             * received. That will also happen if
+             * chunksize != 0, but bytesread < buffersize. */
+            if (bytesread > 0 && BLOCKED_ERRNO(errno))
+                break;
+            PyErr_SetFromErrno(PyExc_IOError);
+            Py_DECREF(v);
+            return NULL;
+        }
+        bytesread += chunksize;
+        if (bytesread < buffersize && !interrupted) {
+            clearerr(f->f_fp);
+            break;
+        }
+        if (bytesrequested < 0) {
+            buffersize = new_buffersize(f, buffersize);
+            if (_PyString_Resize(&v, buffersize) < 0)
+                return NULL;
+        } else {
+            /* Got what was requested. */
+            break;
+        }
+    }
+    if (bytesread != buffersize && _PyString_Resize(&v, bytesread))
+        return NULL;
+    return v;
+}
+
+static PyObject *
+file_readinto(PyFileObject *f, PyObject *args)
+{
+    char *ptr;
+    Py_ssize_t ntodo;
+    Py_ssize_t ndone, nnow;
+    Py_buffer pbuf;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->readable)
+        return err_mode("reading");
+    /* refuse to mix with f.next() */
+    if (f->f_buf != NULL &&
+        (f->f_bufend - f->f_bufptr) > 0 &&
+        f->f_buf[0] != '\0')
+        return err_iterbuffered();
+    if (!PyArg_ParseTuple(args, "w*", &pbuf))
+        return NULL;
+    ptr = pbuf.buf;
+    ntodo = pbuf.len;
+    ndone = 0;
+    while (ntodo > 0) {
+        int interrupted;
+        FILE_BEGIN_ALLOW_THREADS(f)
+        errno = 0;
+        nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp,
+                                        (PyObject *)f);
+        interrupted = ferror(f->f_fp) && errno == EINTR;
+        FILE_END_ALLOW_THREADS(f)
+        if (interrupted) {
+            clearerr(f->f_fp);
+            if (PyErr_CheckSignals()) {
+                PyBuffer_Release(&pbuf);
+                return NULL;
+            }
+        }
+        if (nnow == 0) {
+            if (interrupted)
+                continue;
+            if (!ferror(f->f_fp))
+                break;
+            PyErr_SetFromErrno(PyExc_IOError);
+            clearerr(f->f_fp);
+            PyBuffer_Release(&pbuf);
+            return NULL;
+        }
+        ndone += nnow;
+        ntodo -= nnow;
+    }
+    PyBuffer_Release(&pbuf);
+    return PyInt_FromSsize_t(ndone);
+}
+
+/**************************************************************************
+Routine to get next line using platform fgets().
+
+Under MSVC 6:
+
++ MS threadsafe getc is very slow (multiple layers of function calls before+
+  after each character, to lock+unlock the stream).
++ The stream-locking functions are MS-internal -- can't access them from user
+  code.
++ There's nothing Tim could find in the MS C or platform SDK libraries that
+  can worm around this.
++ MS fgets locks/unlocks only once per line; it's the only hook we have.
+
+So we use fgets for speed(!), despite that it's painful.
+
+MS realloc is also slow.
+
+Reports from other platforms on this method vs getc_unlocked (which MS doesn't
+have):
+    Linux               a wash
+    Solaris             a wash
+    Tru64 Unix          getline_via_fgets significantly faster
+
+CAUTION:  The C std isn't clear about this:  in those cases where fgets
+writes something into the buffer, can it write into any position beyond the
+required trailing null byte?  MSVC 6 fgets does not, and no platform is (yet)
+known on which it does; and it would be a strange way to code fgets. Still,
+getline_via_fgets may not work correctly if it does.  The std test
+test_bufio.py should fail if platform fgets() routinely writes beyond the
+trailing null byte.  #define DONT_USE_FGETS_IN_GETLINE to disable this code.
+**************************************************************************/
+
+/* Use this routine if told to, or by default on non-get_unlocked()
+ * platforms unless told not to.  Yikes!  Let's spell that out:
+ * On a platform with getc_unlocked():
+ *     By default, use getc_unlocked().
+ *     If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
+ * On a platform without getc_unlocked():
+ *     By default, use fgets().
+ *     If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
+ */
+#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
+#define USE_FGETS_IN_GETLINE
+#endif
+
+#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
+#undef USE_FGETS_IN_GETLINE
+#endif
+
+#ifdef USE_FGETS_IN_GETLINE
+static PyObject*
+getline_via_fgets(PyFileObject *f, FILE *fp)
+{
+/* INITBUFSIZE is the maximum line length that lets us get away with the fast
+ * no-realloc, one-fgets()-call path.  Boosting it isn't free, because we have
+ * to fill this much of the buffer with a known value in order to figure out
+ * how much of the buffer fgets() overwrites.  So if INITBUFSIZE is larger
+ * than "most" lines, we waste time filling unused buffer slots.  100 is
+ * surely adequate for most peoples' email archives, chewing over source code,
+ * etc -- "regular old text files".
+ * MAXBUFSIZE is the maximum line length that lets us get away with the less
+ * fast (but still zippy) no-realloc, two-fgets()-call path.  See above for
+ * cautions about boosting that.  300 was chosen because the worst real-life
+ * text-crunching job reported on Python-Dev was a mail-log crawler where over
+ * half the lines were 254 chars.
+ */
+#define INITBUFSIZE 100
+#define MAXBUFSIZE 300
+    char* p;            /* temp */
+    char buf[MAXBUFSIZE];
+    PyObject* v;        /* the string object result */
+    char* pvfree;       /* address of next free slot */
+    char* pvend;    /* address one beyond last free slot */
+    size_t nfree;       /* # of free buffer slots; pvend-pvfree */
+    size_t total_v_size;  /* total # of slots in buffer */
+    size_t increment;           /* amount to increment the buffer */
+    size_t prev_v_size;
+
+    /* Optimize for normal case:  avoid _PyString_Resize if at all
+     * possible via first reading into stack buffer "buf".
+     */
+    total_v_size = INITBUFSIZE;         /* start small and pray */
+    pvfree = buf;
+    for (;;) {
+        FILE_BEGIN_ALLOW_THREADS(f)
+        pvend = buf + total_v_size;
+        nfree = pvend - pvfree;
+        memset(pvfree, '\n', nfree);
+        assert(nfree < INT_MAX); /* Should be atmost MAXBUFSIZE */
+        p = fgets(pvfree, (int)nfree, fp);
+        FILE_END_ALLOW_THREADS(f)
+
+        if (p == NULL) {
+            clearerr(fp);
+            if (PyErr_CheckSignals())
+                return NULL;
+            v = PyString_FromStringAndSize(buf, pvfree - buf);
+            return v;
+        }
+        /* fgets read *something* */
+        p = memchr(pvfree, '\n', nfree);
+        if (p != NULL) {
+            /* Did the \n come from fgets or from us?
+             * Since fgets stops at the first \n, and then writes
+             * \0, if it's from fgets a \0 must be next.  But if
+             * that's so, it could not have come from us, since
+             * the \n's we filled the buffer with have only more
+             * \n's to the right.
+             */
+            if (p+1 < pvend && *(p+1) == '\0') {
+                /* It's from fgets:  we win!  In particular,
+                 * we haven't done any mallocs yet, and can
+                 * build the final result on the first try.
+                 */
+                ++p;                    /* include \n from fgets */
+            }
+            else {
+                /* Must be from us:  fgets didn't fill the
+                 * buffer and didn't find a newline, so it
+                 * must be the last and newline-free line of
+                 * the file.
+                 */
+                assert(p > pvfree && *(p-1) == '\0');
+                --p;                    /* don't include \0 from fgets */
+            }
+            v = PyString_FromStringAndSize(buf, p - buf);
+            return v;
+        }
+        /* yuck:  fgets overwrote all the newlines, i.e. the entire
+         * buffer.  So this line isn't over yet, or maybe it is but
+         * we're exactly at EOF.  If we haven't already, try using the
+         * rest of the stack buffer.
+         */
+        assert(*(pvend-1) == '\0');
+        if (pvfree == buf) {
+            pvfree = pvend - 1;                 /* overwrite trailing null */
+            total_v_size = MAXBUFSIZE;
+        }
+        else
+            break;
+    }
+
+    /* The stack buffer isn't big enough; malloc a string object and read
+     * into its buffer.
+     */
+    total_v_size = MAXBUFSIZE << 1;
+    v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
+    if (v == NULL)
+        return v;
+    /* copy over everything except the last null byte */
+    memcpy(BUF(v), buf, MAXBUFSIZE-1);
+    pvfree = BUF(v) + MAXBUFSIZE - 1;
+
+    /* Keep reading stuff into v; if it ever ends successfully, break
+     * after setting p one beyond the end of the line.  The code here is
+     * very much like the code above, except reads into v's buffer; see
+     * the code above for detailed comments about the logic.
+     */
+    for (;;) {
+        FILE_BEGIN_ALLOW_THREADS(f)
+        pvend = BUF(v) + total_v_size;
+        nfree = pvend - pvfree;
+        memset(pvfree, '\n', nfree);
+        assert(nfree < INT_MAX);
+        p = fgets(pvfree, (int)nfree, fp);
+        FILE_END_ALLOW_THREADS(f)
+
+        if (p == NULL) {
+            clearerr(fp);
+            if (PyErr_CheckSignals()) {
+                Py_DECREF(v);
+                return NULL;
+            }
+            p = pvfree;
+            break;
+        }
+        p = memchr(pvfree, '\n', nfree);
+        if (p != NULL) {
+            if (p+1 < pvend && *(p+1) == '\0') {
+                /* \n came from fgets */
+                ++p;
+                break;
+            }
+            /* \n came from us; last line of file, no newline */
+            assert(p > pvfree && *(p-1) == '\0');
+            --p;
+            break;
+        }
+        /* expand buffer and try again */
+        assert(*(pvend-1) == '\0');
+        increment = total_v_size >> 2;          /* mild exponential growth */
+        prev_v_size = total_v_size;
+        total_v_size += increment;
+        /* check for overflow */
+        if (total_v_size <= prev_v_size ||
+            total_v_size > PY_SSIZE_T_MAX) {
+            PyErr_SetString(PyExc_OverflowError,
+                "line is longer than a Python string can hold");
+            Py_DECREF(v);
+            return NULL;
+        }
+        if (_PyString_Resize(&v, (int)total_v_size) < 0)
+            return NULL;
+        /* overwrite the trailing null byte */
+        pvfree = BUF(v) + (prev_v_size - 1);
+    }
+    if (BUF(v) + total_v_size != p && _PyString_Resize(&v, p - BUF(v)))
+        return NULL;
+    return v;
+#undef INITBUFSIZE
+#undef MAXBUFSIZE
+}
+#endif  /* ifdef USE_FGETS_IN_GETLINE */
+
+/* Internal routine to get a line.
+   Size argument interpretation:
+   > 0: max length;
+   <= 0: read arbitrary line
+*/
+
+static PyObject *
+get_line(PyFileObject *f, int n)
+{
+    FILE *fp = f->f_fp;
+    int c;
+    char *buf, *end;
+    size_t total_v_size;        /* total # of slots in buffer */
+    size_t used_v_size;         /* # used slots in buffer */
+    size_t increment;       /* amount to increment the buffer */
+    PyObject *v;
+    int newlinetypes = f->f_newlinetypes;
+    int skipnextlf = f->f_skipnextlf;
+    int univ_newline = f->f_univ_newline;
+
+#if defined(USE_FGETS_IN_GETLINE)
+    if (n <= 0 && !univ_newline )
+        return getline_via_fgets(f, fp);
+#endif
+    total_v_size = n > 0 ? n : 100;
+    v = PyString_FromStringAndSize((char *)NULL, total_v_size);
+    if (v == NULL)
+        return NULL;
+    buf = BUF(v);
+    end = buf + total_v_size;
+
+    for (;;) {
+        FILE_BEGIN_ALLOW_THREADS(f)
+        FLOCKFILE(fp);
+        if (univ_newline) {
+            c = 'x'; /* Shut up gcc warning */
+            while ( buf != end && (c = GETC(fp)) != EOF ) {
+                if (skipnextlf ) {
+                    skipnextlf = 0;
+                    if (c == '\n') {
+                        /* Seeing a \n here with
+                         * skipnextlf true means we
+                         * saw a \r before.
+                         */
+                        newlinetypes |= NEWLINE_CRLF;
+                        c = GETC(fp);
+                        if (c == EOF) break;
+                    } else {
+                        newlinetypes |= NEWLINE_CR;
+                    }
+                }
+                if (c == '\r') {
+                    skipnextlf = 1;
+                    c = '\n';
+                } else if ( c == '\n')
+                    newlinetypes |= NEWLINE_LF;
+                *buf++ = c;
+                if (c == '\n') break;
+            }
+            if (c == EOF) {
+                if (ferror(fp) && errno == EINTR) {
+                    FUNLOCKFILE(fp);
+                    FILE_ABORT_ALLOW_THREADS(f)
+                    f->f_newlinetypes = newlinetypes;
+                    f->f_skipnextlf = skipnextlf;
+
+                    if (PyErr_CheckSignals()) {
+                        Py_DECREF(v);
+                        return NULL;
+                    }
+                    /* We executed Python signal handlers and got no exception.
+                     * Now back to reading the line where we left off. */
+                    clearerr(fp);
+                    continue;
+                }
+                if (skipnextlf)
+                    newlinetypes |= NEWLINE_CR;
+            }
+        } else /* If not universal newlines use the normal loop */
+        while ((c = GETC(fp)) != EOF &&
+               (*buf++ = c) != '\n' &&
+            buf != end)
+            ;
+        FUNLOCKFILE(fp);
+        FILE_END_ALLOW_THREADS(f)
+        f->f_newlinetypes = newlinetypes;
+        f->f_skipnextlf = skipnextlf;
+        if (c == '\n')
+            break;
+        if (c == EOF) {
+            if (ferror(fp)) {
+                if (errno == EINTR) {
+                    if (PyErr_CheckSignals()) {
+                        Py_DECREF(v);
+                        return NULL;
+                    }
+                    /* We executed Python signal handlers and got no exception.
+                     * Now back to reading the line where we left off. */
+                    clearerr(fp);
+                    continue;
+                }
+                PyErr_SetFromErrno(PyExc_IOError);
+                clearerr(fp);
+                Py_DECREF(v);
+                return NULL;
+            }
+            clearerr(fp);
+            if (PyErr_CheckSignals()) {
+                Py_DECREF(v);
+                return NULL;
+            }
+            break;
+        }
+        /* Must be because buf == end */
+        if (n > 0)
+            break;
+        used_v_size = total_v_size;
+        increment = total_v_size >> 2; /* mild exponential growth */
+        total_v_size += increment;
+        if (total_v_size > PY_SSIZE_T_MAX) {
+            PyErr_SetString(PyExc_OverflowError,
+                "line is longer than a Python string can hold");
+            Py_DECREF(v);
+            return NULL;
+        }
+        if (_PyString_Resize(&v, total_v_size) < 0)
+            return NULL;
+        buf = BUF(v) + used_v_size;
+        end = BUF(v) + total_v_size;
+    }
+
+    used_v_size = buf - BUF(v);
+    if (used_v_size != total_v_size && _PyString_Resize(&v, used_v_size))
+        return NULL;
+    return v;
+}
+
+/* External C interface */
+
+PyObject *
+PyFile_GetLine(PyObject *f, int n)
+{
+    PyObject *result;
+
+    if (f == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+
+    if (PyFile_Check(f)) {
+        PyFileObject *fo = (PyFileObject *)f;
+        if (fo->f_fp == NULL)
+            return err_closed();
+        if (!fo->readable)
+            return err_mode("reading");
+        /* refuse to mix with f.next() */
+        if (fo->f_buf != NULL &&
+            (fo->f_bufend - fo->f_bufptr) > 0 &&
+            fo->f_buf[0] != '\0')
+            return err_iterbuffered();
+        result = get_line(fo, n);
+    }
+    else {
+        PyObject *reader;
+        PyObject *args;
+
+        reader = PyObject_GetAttrString(f, "readline");
+        if (reader == NULL)
+            return NULL;
+        if (n <= 0)
+            args = PyTuple_New(0);
+        else
+            args = Py_BuildValue("(i)", n);
+        if (args == NULL) {
+            Py_DECREF(reader);
+            return NULL;
+        }
+        result = PyEval_CallObject(reader, args);
+        Py_DECREF(reader);
+        Py_DECREF(args);
+        if (result != NULL && !PyString_Check(result) &&
+            !PyUnicode_Check(result)) {
+            Py_DECREF(result);
+            result = NULL;
+            PyErr_SetString(PyExc_TypeError,
+                       "object.readline() returned non-string");
+        }
+    }
+
+    if (n < 0 && result != NULL && PyString_Check(result)) {
+        char *s = PyString_AS_STRING(result);
+        Py_ssize_t len = PyString_GET_SIZE(result);
+        if (len == 0) {
+            Py_DECREF(result);
+            result = NULL;
+            PyErr_SetString(PyExc_EOFError,
+                            "EOF when reading a line");
+        }
+        else if (s[len-1] == '\n') {
+            if (result->ob_refcnt == 1) {
+                if (_PyString_Resize(&result, len-1))
+                    return NULL;
+            }
+            else {
+                PyObject *v;
+                v = PyString_FromStringAndSize(s, len-1);
+                Py_DECREF(result);
+                result = v;
+            }
+        }
+    }
+#ifdef Py_USING_UNICODE
+    if (n < 0 && result != NULL && PyUnicode_Check(result)) {
+        Py_UNICODE *s = PyUnicode_AS_UNICODE(result);
+        Py_ssize_t len = PyUnicode_GET_SIZE(result);
+        if (len == 0) {
+            Py_DECREF(result);
+            result = NULL;
+            PyErr_SetString(PyExc_EOFError,
+                            "EOF when reading a line");
+        }
+        else if (s[len-1] == '\n') {
+            if (result->ob_refcnt == 1)
+                PyUnicode_Resize(&result, len-1);
+            else {
+                PyObject *v;
+                v = PyUnicode_FromUnicode(s, len-1);
+                Py_DECREF(result);
+                result = v;
+            }
+        }
+    }
+#endif
+    return result;
+}
+
+/* Python method */
+
+static PyObject *
+file_readline(PyFileObject *f, PyObject *args)
+{
+    int n = -1;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->readable)
+        return err_mode("reading");
+    /* refuse to mix with f.next() */
+    if (f->f_buf != NULL &&
+        (f->f_bufend - f->f_bufptr) > 0 &&
+        f->f_buf[0] != '\0')
+        return err_iterbuffered();
+    if (!PyArg_ParseTuple(args, "|i:readline", &n))
+        return NULL;
+    if (n == 0)
+        return PyString_FromString("");
+    if (n < 0)
+        n = 0;
+    return get_line(f, n);
+}
+
+static PyObject *
+file_readlines(PyFileObject *f, PyObject *args)
+{
+    long sizehint = 0;
+    PyObject *list = NULL;
+    PyObject *line;
+    char small_buffer[SMALLCHUNK];
+    char *buffer = small_buffer;
+    size_t buffersize = SMALLCHUNK;
+    PyObject *big_buffer = NULL;
+    size_t nfilled = 0;
+    size_t nread;
+    size_t totalread = 0;
+    char *p, *q, *end;
+    int err;
+    int shortread = 0;  /* bool, did the previous read come up short? */
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->readable)
+        return err_mode("reading");
+    /* refuse to mix with f.next() */
+    if (f->f_buf != NULL &&
+        (f->f_bufend - f->f_bufptr) > 0 &&
+        f->f_buf[0] != '\0')
+        return err_iterbuffered();
+    if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
+        return NULL;
+    if ((list = PyList_New(0)) == NULL)
+        return NULL;
+    for (;;) {
+        if (shortread)
+            nread = 0;
+        else {
+            FILE_BEGIN_ALLOW_THREADS(f)
+            errno = 0;
+            nread = Py_UniversalNewlineFread(buffer+nfilled,
+                buffersize-nfilled, f->f_fp, (PyObject *)f);
+            FILE_END_ALLOW_THREADS(f)
+            shortread = (nread < buffersize-nfilled);
+        }
+        if (nread == 0) {
+            sizehint = 0;
+            if (!ferror(f->f_fp))
+                break;
+            if (errno == EINTR) {
+                if (PyErr_CheckSignals()) {
+                    goto error;
+                }
+                clearerr(f->f_fp);
+                shortread = 0;
+                continue;
+            }
+            PyErr_SetFromErrno(PyExc_IOError);
+            clearerr(f->f_fp);
+            goto error;
+        }
+        totalread += nread;
+        p = (char *)memchr(buffer+nfilled, '\n', nread);
+        if (p == NULL) {
+            /* Need a larger buffer to fit this line */
+            nfilled += nread;
+            buffersize *= 2;
+            if (buffersize > PY_SSIZE_T_MAX) {
+                PyErr_SetString(PyExc_OverflowError,
+                "line is longer than a Python string can hold");
+                goto error;
+            }
+            if (big_buffer == NULL) {
+                /* Create the big buffer */
+                big_buffer = PyString_FromStringAndSize(
+                    NULL, buffersize);
+                if (big_buffer == NULL)
+                    goto error;
+                buffer = PyString_AS_STRING(big_buffer);
+                memcpy(buffer, small_buffer, nfilled);
+            }
+            else {
+                /* Grow the big buffer */
+                if ( _PyString_Resize(&big_buffer, buffersize) < 0 )
+                    goto error;
+                buffer = PyString_AS_STRING(big_buffer);
+            }
+            continue;
+        }
+        end = buffer+nfilled+nread;
+        q = buffer;
+        do {
+            /* Process complete lines */
+            p++;
+            line = PyString_FromStringAndSize(q, p-q);
+            if (line == NULL)
+                goto error;
+            err = PyList_Append(list, line);
+            Py_DECREF(line);
+            if (err != 0)
+                goto error;
+            q = p;
+            p = (char *)memchr(q, '\n', end-q);
+        } while (p != NULL);
+        /* Move the remaining incomplete line to the start */
+        nfilled = end-q;
+        memmove(buffer, q, nfilled);
+        if (sizehint > 0)
+            if (totalread >= (size_t)sizehint)
+                break;
+    }
+    if (nfilled != 0) {
+        /* Partial last line */
+        line = PyString_FromStringAndSize(buffer, nfilled);
+        if (line == NULL)
+            goto error;
+        if (sizehint > 0) {
+            /* Need to complete the last line */
+            PyObject *rest = get_line(f, 0);
+            if (rest == NULL) {
+                Py_DECREF(line);
+                goto error;
+            }
+            PyString_Concat(&line, rest);
+            Py_DECREF(rest);
+            if (line == NULL)
+                goto error;
+        }
+        err = PyList_Append(list, line);
+        Py_DECREF(line);
+        if (err != 0)
+            goto error;
+    }
+
+cleanup:
+    Py_XDECREF(big_buffer);
+    return list;
+
+error:
+    Py_CLEAR(list);
+    goto cleanup;
+}
+
+static PyObject *
+file_write(PyFileObject *f, PyObject *args)
+{
+    Py_buffer pbuf;
+    const char *s;
+    Py_ssize_t n, n2;
+    PyObject *encoded = NULL;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->writable)
+        return err_mode("writing");
+    if (f->f_binary) {
+        if (!PyArg_ParseTuple(args, "s*", &pbuf))
+            return NULL;
+        s = pbuf.buf;
+        n = pbuf.len;
+    }
+    else {
+        PyObject *text;
+        if (!PyArg_ParseTuple(args, "O", &text))
+            return NULL;
+
+        if (PyString_Check(text)) {
+            s = PyString_AS_STRING(text);
+            n = PyString_GET_SIZE(text);
+#ifdef Py_USING_UNICODE
+        } else if (PyUnicode_Check(text)) {
+            const char *encoding, *errors;
+            if (f->f_encoding != Py_None)
+                encoding = PyString_AS_STRING(f->f_encoding);
+            else
+                encoding = PyUnicode_GetDefaultEncoding();
+            if (f->f_errors != Py_None)
+                errors = PyString_AS_STRING(f->f_errors);
+            else
+                errors = "strict";
+            encoded = PyUnicode_AsEncodedString(text, encoding, errors);
+            if (encoded == NULL)
+                return NULL;
+            s = PyString_AS_STRING(encoded);
+            n = PyString_GET_SIZE(encoded);
+#endif
+        } else {
+            if (PyObject_AsCharBuffer(text, &s, &n))
+                return NULL;
+        }
+    }
+    f->f_softspace = 0;
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    n2 = fwrite(s, 1, n, f->f_fp);
+    FILE_END_ALLOW_THREADS(f)
+    Py_XDECREF(encoded);
+    if (f->f_binary)
+        PyBuffer_Release(&pbuf);
+    if (n2 != n) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        clearerr(f->f_fp);
+        return NULL;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+file_writelines(PyFileObject *f, PyObject *seq)
+{
+#define CHUNKSIZE 1000
+    PyObject *list, *line;
+    PyObject *it;       /* iter(seq) */
+    PyObject *result;
+    int index, islist;
+    Py_ssize_t i, j, nwritten, len;
+
+    assert(seq != NULL);
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->writable)
+        return err_mode("writing");
+
+    result = NULL;
+    list = NULL;
+    islist = PyList_Check(seq);
+    if  (islist)
+        it = NULL;
+    else {
+        it = PyObject_GetIter(seq);
+        if (it == NULL) {
+            PyErr_SetString(PyExc_TypeError,
+                "writelines() requires an iterable argument");
+            return NULL;
+        }
+        /* From here on, fail by going to error, to reclaim "it". */
+        list = PyList_New(CHUNKSIZE);
+        if (list == NULL)
+            goto error;
+    }
+
+    /* Strategy: slurp CHUNKSIZE lines into a private list,
+       checking that they are all strings, then write that list
+       without holding the interpreter lock, then come back for more. */
+    for (index = 0; ; index += CHUNKSIZE) {
+        if (islist) {
+            Py_XDECREF(list);
+            list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
+            if (list == NULL)
+                goto error;
+            j = PyList_GET_SIZE(list);
+        }
+        else {
+            for (j = 0; j < CHUNKSIZE; j++) {
+                line = PyIter_Next(it);
+                if (line == NULL) {
+                    if (PyErr_Occurred())
+                        goto error;
+                    break;
+                }
+                PyList_SetItem(list, j, line);
+            }
+            /* The iterator might have closed the file on us. */
+            if (f->f_fp == NULL) {
+                err_closed();
+                goto error;
+            }
+        }
+        if (j == 0)
+            break;
+
+        /* Check that all entries are indeed strings. If not,
+           apply the same rules as for file.write() and
+           convert the results to strings. This is slow, but
+           seems to be the only way since all conversion APIs
+           could potentially execute Python code. */
+        for (i = 0; i < j; i++) {
+            PyObject *v = PyList_GET_ITEM(list, i);
+            if (!PyString_Check(v)) {
+                const char *buffer;
+                if (((f->f_binary &&
+                      PyObject_AsReadBuffer(v,
+                          (const void**)&buffer,
+                                        &len)) ||
+                     PyObject_AsCharBuffer(v,
+                                           &buffer,
+                                           &len))) {
+                    PyErr_SetString(PyExc_TypeError,
+            "writelines() argument must be a sequence of strings");
+                            goto error;
+                }
+                line = PyString_FromStringAndSize(buffer,
+                                                  len);
+                if (line == NULL)
+                    goto error;
+                Py_DECREF(v);
+                PyList_SET_ITEM(list, i, line);
+            }
+        }
+
+        /* Since we are releasing the global lock, the
+           following code may *not* execute Python code. */
+        f->f_softspace = 0;
+        FILE_BEGIN_ALLOW_THREADS(f)
+        errno = 0;
+        for (i = 0; i < j; i++) {
+            line = PyList_GET_ITEM(list, i);
+            len = PyString_GET_SIZE(line);
+            nwritten = fwrite(PyString_AS_STRING(line),
+                              1, len, f->f_fp);
+            if (nwritten != len) {
+                FILE_ABORT_ALLOW_THREADS(f)
+                PyErr_SetFromErrno(PyExc_IOError);
+                clearerr(f->f_fp);
+                goto error;
+            }
+        }
+        FILE_END_ALLOW_THREADS(f)
+
+        if (j < CHUNKSIZE)
+            break;
+    }
+
+    Py_INCREF(Py_None);
+    result = Py_None;
+  error:
+    Py_XDECREF(list);
+    Py_XDECREF(it);
+    return result;
+#undef CHUNKSIZE
+}
+
+static PyObject *
+file_self(PyFileObject *f)
+{
+    if (f->f_fp == NULL)
+        return err_closed();
+    Py_INCREF(f);
+    return (PyObject *)f;
+}
+
+static PyObject *
+file_xreadlines(PyFileObject *f)
+{
+    if (PyErr_WarnPy3k("f.xreadlines() not supported in 3.x, "
+                       "try 'for line in f' instead", 1) < 0)
+           return NULL;
+    return file_self(f);
+}
+
+static PyObject *
+file_exit(PyObject *f, PyObject *args)
+{
+    PyObject *ret = PyObject_CallMethod(f, "close", NULL);
+    if (!ret)
+        /* If error occurred, pass through */
+        return NULL;
+    Py_DECREF(ret);
+    /* We cannot return the result of close since a true
+     * value will be interpreted as "yes, swallow the
+     * exception if one was raised inside the with block". */
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(readline_doc,
+"readline([size]) -> next line from the file, as a string.\n"
+"\n"
+"Retain newline.  A non-negative size argument limits the maximum\n"
+"number of bytes to return (an incomplete line may be returned then).\n"
+"Return an empty string at EOF.");
+
+PyDoc_STRVAR(read_doc,
+"read([size]) -> read at most size bytes, returned as a string.\n"
+"\n"
+"If the size argument is negative or omitted, read until EOF is reached.\n"
+"Notice that when in non-blocking mode, less data than what was requested\n"
+"may be returned, even if no size parameter was given.");
+
+PyDoc_STRVAR(write_doc,
+"write(str) -> None.  Write string str to file.\n"
+"\n"
+"Note that due to buffering, flush() or close() may be needed before\n"
+"the file on disk reflects the data written.");
+
+PyDoc_STRVAR(fileno_doc,
+"fileno() -> integer \"file descriptor\".\n"
+"\n"
+"This is needed for lower-level file interfaces, such os.read().");
+
+PyDoc_STRVAR(seek_doc,
+"seek(offset[, whence]) -> None.  Move to new file position.\n"
+"\n"
+"Argument offset is a byte count.  Optional argument whence defaults to\n"
+"0 (offset from start of file, offset should be >= 0); other values are 1\n"
+"(move relative to current position, positive or negative), and 2 (move\n"
+"relative to end of file, usually negative, although many platforms allow\n"
+"seeking beyond the end of a file).  If the file is opened in text mode,\n"
+"only offsets returned by tell() are legal.  Use of other offsets causes\n"
+"undefined behavior."
+"\n"
+"Note that not all file objects are seekable.");
+
+#ifdef HAVE_FTRUNCATE
+PyDoc_STRVAR(truncate_doc,
+"truncate([size]) -> None.  Truncate the file to at most size bytes.\n"
+"\n"
+"Size defaults to the current file position, as returned by tell().");
+#endif
+
+PyDoc_STRVAR(tell_doc,
+"tell() -> current file position, an integer (may be a long integer).");
+
+PyDoc_STRVAR(readinto_doc,
+"readinto() -> Undocumented.  Don't use this; it may go away.");
+
+PyDoc_STRVAR(readlines_doc,
+"readlines([size]) -> list of strings, each a line from the file.\n"
+"\n"
+"Call readline() repeatedly and return a list of the lines so read.\n"
+"The optional size argument, if given, is an approximate bound on the\n"
+"total number of bytes in the lines returned.");
+
+PyDoc_STRVAR(xreadlines_doc,
+"xreadlines() -> returns self.\n"
+"\n"
+"For backward compatibility. File objects now include the performance\n"
+"optimizations previously implemented in the xreadlines module.");
+
+PyDoc_STRVAR(writelines_doc,
+"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
+"\n"
+"Note that newlines are not added.  The sequence can be any iterable object\n"
+"producing strings. This is equivalent to calling write() for each string.");
+
+PyDoc_STRVAR(flush_doc,
+"flush() -> None.  Flush the internal I/O buffer.");
+
+PyDoc_STRVAR(close_doc,
+"close() -> None or (perhaps) an integer.  Close the file.\n"
+"\n"
+"Sets data attribute .closed to True.  A closed file cannot be used for\n"
+"further I/O operations.  close() may be called more than once without\n"
+"error.  Some kinds of file objects (for example, opened by popen())\n"
+"may return an exit status upon closing.");
+
+PyDoc_STRVAR(isatty_doc,
+"isatty() -> true or false.  True if the file is connected to a tty device.");
+
+PyDoc_STRVAR(enter_doc,
+             "__enter__() -> self.");
+
+PyDoc_STRVAR(exit_doc,
+             "__exit__(*excinfo) -> None.  Closes the file.");
+
+static PyMethodDef file_methods[] = {
+    {"readline",  (PyCFunction)file_readline, METH_VARARGS, readline_doc},
+    {"read",      (PyCFunction)file_read,     METH_VARARGS, read_doc},
+    {"write",     (PyCFunction)file_write,    METH_VARARGS, write_doc},
+    {"fileno",    (PyCFunction)file_fileno,   METH_NOARGS,  fileno_doc},
+    {"seek",      (PyCFunction)file_seek,     METH_VARARGS, seek_doc},
+#ifdef HAVE_FTRUNCATE
+    {"truncate",  (PyCFunction)file_truncate, METH_VARARGS, truncate_doc},
+#endif
+    {"tell",      (PyCFunction)file_tell,     METH_NOARGS,  tell_doc},
+    {"readinto",  (PyCFunction)file_readinto, METH_VARARGS, readinto_doc},
+    {"readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc},
+    {"xreadlines",(PyCFunction)file_xreadlines, METH_NOARGS, xreadlines_doc},
+    {"writelines",(PyCFunction)file_writelines, METH_O,     writelines_doc},
+    {"flush",     (PyCFunction)file_flush,    METH_NOARGS,  flush_doc},
+    {"close",     (PyCFunction)file_close,    METH_NOARGS,  close_doc},
+    {"isatty",    (PyCFunction)file_isatty,   METH_NOARGS,  isatty_doc},
+    {"__enter__", (PyCFunction)file_self,     METH_NOARGS,  enter_doc},
+    {"__exit__",  (PyCFunction)file_exit,     METH_VARARGS, exit_doc},
+    {NULL,            NULL}             /* sentinel */
+};
+
+#define OFF(x) offsetof(PyFileObject, x)
+
+static PyMemberDef file_memberlist[] = {
+    {"mode",            T_OBJECT,       OFF(f_mode),    RO,
+     "file mode ('r', 'U', 'w', 'a', possibly with 'b' or '+' added)"},
+    {"name",            T_OBJECT,       OFF(f_name),    RO,
+     "file name"},
+    {"encoding",        T_OBJECT,       OFF(f_encoding),        RO,
+     "file encoding"},
+    {"errors",          T_OBJECT,       OFF(f_errors),  RO,
+     "Unicode error handler"},
+    /* getattr(f, "closed") is implemented without this table */
+    {NULL}      /* Sentinel */
+};
+
+static PyObject *
+get_closed(PyFileObject *f, void *closure)
+{
+    return PyBool_FromLong((long)(f->f_fp == 0));
+}
+static PyObject *
+get_newlines(PyFileObject *f, void *closure)
+{
+    switch (f->f_newlinetypes) {
+    case NEWLINE_UNKNOWN:
+        Py_INCREF(Py_None);
+        return Py_None;
+    case NEWLINE_CR:
+        return PyString_FromString("\r");
+    case NEWLINE_LF:
+        return PyString_FromString("\n");
+    case NEWLINE_CR|NEWLINE_LF:
+        return Py_BuildValue("(ss)", "\r", "\n");
+    case NEWLINE_CRLF:
+        return PyString_FromString("\r\n");
+    case NEWLINE_CR|NEWLINE_CRLF:
+        return Py_BuildValue("(ss)", "\r", "\r\n");
+    case NEWLINE_LF|NEWLINE_CRLF:
+        return Py_BuildValue("(ss)", "\n", "\r\n");
+    case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
+        return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
+    default:
+        PyErr_Format(PyExc_SystemError,
+                     "Unknown newlines value 0x%x\n",
+                     f->f_newlinetypes);
+        return NULL;
+    }
+}
+
+static PyObject *
+get_softspace(PyFileObject *f, void *closure)
+{
+    if (PyErr_WarnPy3k("file.softspace not supported in 3.x", 1) < 0)
+        return NULL;
+    return PyInt_FromLong(f->f_softspace);
+}
+
+static int
+set_softspace(PyFileObject *f, PyObject *value)
+{
+    int new;
+    if (PyErr_WarnPy3k("file.softspace not supported in 3.x", 1) < 0)
+        return -1;
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "can't delete softspace attribute");
+        return -1;
+    }
+
+    new = PyInt_AsLong(value);
+    if (new == -1 && PyErr_Occurred())
+        return -1;
+    f->f_softspace = new;
+    return 0;
+}
+
+static PyGetSetDef file_getsetlist[] = {
+    {"closed", (getter)get_closed, NULL, "True if the file is closed"},
+    {"newlines", (getter)get_newlines, NULL,
+     "end-of-line convention used in this file"},
+    {"softspace", (getter)get_softspace, (setter)set_softspace,
+     "flag indicating that a space needs to be printed; used by print"},
+    {0},
+};
+
+static void
+drop_readahead(PyFileObject *f)
+{
+    if (f->f_buf != NULL) {
+        PyMem_Free(f->f_buf);
+        f->f_buf = NULL;
+    }
+}
+
+/* Make sure that file has a readahead buffer with at least one byte
+   (unless at EOF) and no more than bufsize.  Returns negative value on
+   error, will set MemoryError if bufsize bytes cannot be allocated. */
+static int
+readahead(PyFileObject *f, int bufsize)
+{
+    Py_ssize_t chunksize;
+
+    if (f->f_buf != NULL) {
+        if( (f->f_bufend - f->f_bufptr) >= 1)
+            return 0;
+        else
+            drop_readahead(f);
+    }
+    if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    FILE_BEGIN_ALLOW_THREADS(f)
+    errno = 0;
+    chunksize = Py_UniversalNewlineFread(
+        f->f_buf, bufsize, f->f_fp, (PyObject *)f);
+    FILE_END_ALLOW_THREADS(f)
+    if (chunksize == 0) {
+        if (ferror(f->f_fp)) {
+            PyErr_SetFromErrno(PyExc_IOError);
+            clearerr(f->f_fp);
+            drop_readahead(f);
+            return -1;
+        }
+    }
+    f->f_bufptr = f->f_buf;
+    f->f_bufend = f->f_buf + chunksize;
+    return 0;
+}
+
+/* Used by file_iternext.  The returned string will start with 'skip'
+   uninitialized bytes followed by the remainder of the line. Don't be
+   horrified by the recursive call: maximum recursion depth is limited by
+   logarithmic buffer growth to about 50 even when reading a 1gb line. */
+
+static PyStringObject *
+readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
+{
+    PyStringObject* s;
+    char *bufptr;
+    char *buf;
+    Py_ssize_t len;
+
+    if (f->f_buf == NULL)
+        if (readahead(f, bufsize) < 0)
+            return NULL;
+
+    len = f->f_bufend - f->f_bufptr;
+    if (len == 0)
+        return (PyStringObject *)
+            PyString_FromStringAndSize(NULL, skip);
+    bufptr = (char *)memchr(f->f_bufptr, '\n', len);
+    if (bufptr != NULL) {
+        bufptr++;                               /* Count the '\n' */
+        len = bufptr - f->f_bufptr;
+        s = (PyStringObject *)
+            PyString_FromStringAndSize(NULL, skip+len);
+        if (s == NULL)
+            return NULL;
+        memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
+        f->f_bufptr = bufptr;
+        if (bufptr == f->f_bufend)
+            drop_readahead(f);
+    } else {
+        bufptr = f->f_bufptr;
+        buf = f->f_buf;
+        f->f_buf = NULL;                /* Force new readahead buffer */
+        assert(skip+len < INT_MAX);
+        s = readahead_get_line_skip(
+            f, (int)(skip+len), bufsize + (bufsize>>2) );
+        if (s == NULL) {
+            PyMem_Free(buf);
+            return NULL;
+        }
+        memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
+        PyMem_Free(buf);
+    }
+    return s;
+}
+
+/* A larger buffer size may actually decrease performance. */
+#define READAHEAD_BUFSIZE 8192
+
+static PyObject *
+file_iternext(PyFileObject *f)
+{
+    PyStringObject* l;
+
+    if (f->f_fp == NULL)
+        return err_closed();
+    if (!f->readable)
+        return err_mode("reading");
+
+    l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
+    if (l == NULL || PyString_GET_SIZE(l) == 0) {
+        Py_XDECREF(l);
+        return NULL;
+    }
+    return (PyObject *)l;
+}
+
+
+static PyObject *
+file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *self;
+    static PyObject *not_yet_string;
+
+    assert(type != NULL && type->tp_alloc != NULL);
+
+    if (not_yet_string == NULL) {
+        not_yet_string = PyString_InternFromString("<uninitialized file>");
+        if (not_yet_string == NULL)
+            return NULL;
+    }
+
+    self = type->tp_alloc(type, 0);
+    if (self != NULL) {
+        /* Always fill in the name and mode, so that nobody else
+           needs to special-case NULLs there. */
+        Py_INCREF(not_yet_string);
+        ((PyFileObject *)self)->f_name = not_yet_string;
+        Py_INCREF(not_yet_string);
+        ((PyFileObject *)self)->f_mode = not_yet_string;
+        Py_INCREF(Py_None);
+        ((PyFileObject *)self)->f_encoding = Py_None;
+        Py_INCREF(Py_None);
+        ((PyFileObject *)self)->f_errors = Py_None;
+        ((PyFileObject *)self)->weakreflist = NULL;
+        ((PyFileObject *)self)->unlocked_count = 0;
+    }
+    return self;
+}
+
+static int
+file_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyFileObject *foself = (PyFileObject *)self;
+    int ret = 0;
+    static char *kwlist[] = {"name", "mode", "buffering", 0};
+    char *name = NULL;
+    char *mode = "r";
+    int bufsize = -1;
+    int wideargument = 0;
+#ifdef MS_WINDOWS
+    PyObject *po;
+#endif
+
+    assert(PyFile_Check(self));
+    if (foself->f_fp != NULL) {
+        /* Have to close the existing file first. */
+        PyObject *closeresult = file_close(foself);
+        if (closeresult == NULL)
+            return -1;
+        Py_DECREF(closeresult);
+    }
+
+#ifdef MS_WINDOWS
+    if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
+                                    kwlist, &po, &mode, &bufsize)) {
+        wideargument = 1;
+        if (fill_file_fields(foself, NULL, po, mode,
+                             fclose) == NULL)
+            goto Error;
+    } else {
+        /* Drop the argument parsing error as narrow
+           strings are also valid. */
+        PyErr_Clear();
+    }
+#endif
+
+    if (!wideargument) {
+        PyObject *o_name;
+
+        if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
+                                         Py_FileSystemDefaultEncoding,
+                                         &name,
+                                         &mode, &bufsize))
+            return -1;
+
+        /* We parse again to get the name as a PyObject */
+        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:file",
+                                         kwlist, &o_name, &mode,
+                                         &bufsize))
+            goto Error;
+
+        if (fill_file_fields(foself, NULL, o_name, mode,
+                             fclose) == NULL)
+            goto Error;
+    }
+    if (open_the_file(foself, name, mode) == NULL)
+        goto Error;
+    foself->f_setbuf = NULL;
+    PyFile_SetBufSize(self, bufsize);
+    goto Done;
+
+Error:
+    ret = -1;
+    /* fall through */
+Done:
+    PyMem_Free(name); /* free the encoded string */
+    return ret;
+}
+
+PyDoc_VAR(file_doc) =
+PyDoc_STR(
+"file(name[, mode[, buffering]]) -> file object\n"
+"\n"
+"Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),\n"
+"writing or appending.  The file will be created if it doesn't exist\n"
+"when opened for writing or appending; it will be truncated when\n"
+"opened for writing.  Add a 'b' to the mode for binary files.\n"
+"Add a '+' to the mode to allow simultaneous reading and writing.\n"
+"If the buffering argument is given, 0 means unbuffered, 1 means line\n"
+"buffered, and larger numbers specify the buffer size.  The preferred way\n"
+"to open a file is with the builtin open() function.\n"
+)
+PyDoc_STR(
+"Add a 'U' to mode to open the file for input with universal newline\n"
+"support.  Any line ending in the input file will be seen as a '\\n'\n"
+"in Python.  Also, a file so opened gains the attribute 'newlines';\n"
+"the value for this attribute is one of None (no newline read yet),\n"
+"'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n"
+"\n"
+"'U' cannot be combined with 'w' or '+' mode.\n"
+);
+
+PyTypeObject PyFile_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "file",
+    sizeof(PyFileObject),
+    0,
+    (destructor)file_dealloc,                   /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)file_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    /* softspace is writable:  we must supply tp_setattro */
+    PyObject_GenericSetAttr,                    /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+    file_doc,                                   /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(PyFileObject, weakreflist),        /* tp_weaklistoffset */
+    (getiterfunc)file_self,                     /* tp_iter */
+    (iternextfunc)file_iternext,                /* tp_iternext */
+    file_methods,                               /* tp_methods */
+    file_memberlist,                            /* tp_members */
+    file_getsetlist,                            /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    file_init,                                  /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    file_new,                                   /* tp_new */
+    PyObject_Del,                           /* tp_free */
+};
+
+/* Interface for the 'soft space' between print items. */
+
+int
+PyFile_SoftSpace(PyObject *f, int newflag)
+{
+    long oldflag = 0;
+    if (f == NULL) {
+        /* Do nothing */
+    }
+    else if (PyFile_Check(f)) {
+        oldflag = ((PyFileObject *)f)->f_softspace;
+        ((PyFileObject *)f)->f_softspace = newflag;
+    }
+    else {
+        PyObject *v;
+        v = PyObject_GetAttrString(f, "softspace");
+        if (v == NULL)
+            PyErr_Clear();
+        else {
+            if (PyInt_Check(v))
+                oldflag = PyInt_AsLong(v);
+            assert(oldflag < INT_MAX);
+            Py_DECREF(v);
+        }
+        v = PyInt_FromLong((long)newflag);
+        if (v == NULL)
+            PyErr_Clear();
+        else {
+            if (PyObject_SetAttrString(f, "softspace", v) != 0)
+                PyErr_Clear();
+            Py_DECREF(v);
+        }
+    }
+    return (int)oldflag;
+}
+
+/* Interfaces to write objects/strings to file-like objects */
+
+int
+PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
+{
+    PyObject *writer, *value, *args, *result;
+    if (f == NULL) {
+        PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
+        return -1;
+    }
+    else if (PyFile_Check(f)) {
+        PyFileObject *fobj = (PyFileObject *) f;
+#ifdef Py_USING_UNICODE
+        PyObject *enc = fobj->f_encoding;
+        int result;
+#endif
+        if (fobj->f_fp == NULL) {
+            err_closed();
+            return -1;
+        }
+#ifdef Py_USING_UNICODE
+        if ((flags & Py_PRINT_RAW) &&
+            PyUnicode_Check(v) && enc != Py_None) {
+            char *cenc = PyString_AS_STRING(enc);
+            char *errors = fobj->f_errors == Py_None ?
+              "strict" : PyString_AS_STRING(fobj->f_errors);
+            value = PyUnicode_AsEncodedString(v, cenc, errors);
+            if (value == NULL)
+                return -1;
+        } else {
+            value = v;
+            Py_INCREF(value);
+        }
+        result = file_PyObject_Print(value, fobj, flags);
+        Py_DECREF(value);
+        return result;
+#else
+        return file_PyObject_Print(v, fobj, flags);
+#endif
+    }
+    writer = PyObject_GetAttrString(f, "write");
+    if (writer == NULL)
+        return -1;
+    if (flags & Py_PRINT_RAW) {
+        if (PyUnicode_Check(v)) {
+            value = v;
+            Py_INCREF(value);
+        } else
+            value = PyObject_Str(v);
+    }
+    else
+        value = PyObject_Repr(v);
+    if (value == NULL) {
+        Py_DECREF(writer);
+        return -1;
+    }
+    args = PyTuple_Pack(1, value);
+    if (args == NULL) {
+        Py_DECREF(value);
+        Py_DECREF(writer);
+        return -1;
+    }
+    result = PyEval_CallObject(writer, args);
+    Py_DECREF(args);
+    Py_DECREF(value);
+    Py_DECREF(writer);
+    if (result == NULL)
+        return -1;
+    Py_DECREF(result);
+    return 0;
+}
+
+int
+PyFile_WriteString(const char *s, PyObject *f)
+{
+
+    if (f == NULL) {
+        /* Should be caused by a pre-existing error */
+        if (!PyErr_Occurred())
+            PyErr_SetString(PyExc_SystemError,
+                            "null file for PyFile_WriteString");
+        return -1;
+    }
+    else if (PyFile_Check(f)) {
+        PyFileObject *fobj = (PyFileObject *) f;
+        FILE *fp = PyFile_AsFile(f);
+        if (fp == NULL) {
+            err_closed();
+            return -1;
+        }
+        FILE_BEGIN_ALLOW_THREADS(fobj)
+        fputs(s, fp);
+        FILE_END_ALLOW_THREADS(fobj)
+        return 0;
+    }
+    else if (!PyErr_Occurred()) {
+        PyObject *v = PyString_FromString(s);
+        int err;
+        if (v == NULL)
+            return -1;
+        err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
+        Py_DECREF(v);
+        return err;
+    }
+    else
+        return -1;
+}
+
+/* Try to get a file-descriptor from a Python object.  If the object
+   is an integer or long integer, its value is returned.  If not, the
+   object's fileno() method is called if it exists; the method must return
+   an integer or long integer, which is returned as the file descriptor value.
+   -1 is returned on failure.
+*/
+
+int PyObject_AsFileDescriptor(PyObject *o)
+{
+    int fd;
+    PyObject *meth;
+
+    if (PyInt_Check(o)) {
+        fd = _PyInt_AsInt(o);
+    }
+    else if (PyLong_Check(o)) {
+        fd = _PyLong_AsInt(o);
+    }
+    else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
+    {
+        PyObject *fno = PyEval_CallObject(meth, NULL);
+        Py_DECREF(meth);
+        if (fno == NULL)
+            return -1;
+
+        if (PyInt_Check(fno)) {
+            fd = _PyInt_AsInt(fno);
+            Py_DECREF(fno);
+        }
+        else if (PyLong_Check(fno)) {
+            fd = _PyLong_AsInt(fno);
+            Py_DECREF(fno);
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError,
+                            "fileno() returned a non-integer");
+            Py_DECREF(fno);
+            return -1;
+        }
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "argument must be an int, or have a fileno() method.");
+        return -1;
+    }
+
+    if (fd < 0) {
+        PyErr_Format(PyExc_ValueError,
+                     "file descriptor cannot be a negative integer (%i)",
+                     fd);
+        return -1;
+    }
+    return fd;
+}
+
+/* From here on we need access to the real fgets and fread */
+#undef fgets
+#undef fread
+
+/*
+** Py_UniversalNewlineFgets is an fgets variation that understands
+** all of \r, \n and \r\n conventions.
+** The stream should be opened in binary mode.
+** If fobj is NULL the routine always does newline conversion, and
+** it may peek one char ahead to gobble the second char in \r\n.
+** If fobj is non-NULL it must be a PyFileObject. In this case there
+** is no readahead but in stead a flag is used to skip a following
+** \n on the next read. Also, if the file is open in binary mode
+** the whole conversion is skipped. Finally, the routine keeps track of
+** the different types of newlines seen.
+** Note that we need no error handling: fgets() treats error and eof
+** identically.
+*/
+char *
+Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
+{
+    char *p = buf;
+    int c;
+    int newlinetypes = 0;
+    int skipnextlf = 0;
+    int univ_newline = 1;
+
+    if (fobj) {
+        if (!PyFile_Check(fobj)) {
+            errno = ENXIO;              /* What can you do... */
+            return NULL;
+        }
+        univ_newline = ((PyFileObject *)fobj)->f_univ_newline;
+        if ( !univ_newline )
+            return fgets(buf, n, stream);
+        newlinetypes = ((PyFileObject *)fobj)->f_newlinetypes;
+        skipnextlf = ((PyFileObject *)fobj)->f_skipnextlf;
+    }
+    FLOCKFILE(stream);
+    c = 'x'; /* Shut up gcc warning */
+    while (--n > 0 && (c = GETC(stream)) != EOF ) {
+        if (skipnextlf ) {
+            skipnextlf = 0;
+            if (c == '\n') {
+                /* Seeing a \n here with skipnextlf true
+                ** means we saw a \r before.
+                */
+                newlinetypes |= NEWLINE_CRLF;
+                c = GETC(stream);
+                if (c == EOF) break;
+            } else {
+                /*
+                ** Note that c == EOF also brings us here,
+                ** so we're okay if the last char in the file
+                ** is a CR.
+                */
+                newlinetypes |= NEWLINE_CR;
+            }
+        }
+        if (c == '\r') {
+            /* A \r is translated into a \n, and we skip
+            ** an adjacent \n, if any. We don't set the
+            ** newlinetypes flag until we've seen the next char.
+            */
+            skipnextlf = 1;
+            c = '\n';
+        } else if ( c == '\n') {
+            newlinetypes |= NEWLINE_LF;
+        }
+        *p++ = c;
+        if (c == '\n') break;
+    }
+    if ( c == EOF && skipnextlf )
+        newlinetypes |= NEWLINE_CR;
+    FUNLOCKFILE(stream);
+    *p = '\0';
+    if (fobj) {
+        ((PyFileObject *)fobj)->f_newlinetypes = newlinetypes;
+        ((PyFileObject *)fobj)->f_skipnextlf = skipnextlf;
+    } else if ( skipnextlf ) {
+        /* If we have no file object we cannot save the
+        ** skipnextlf flag. We have to readahead, which
+        ** will cause a pause if we're reading from an
+        ** interactive stream, but that is very unlikely
+        ** unless we're doing something silly like
+        ** execfile("/dev/tty").
+        */
+        c = GETC(stream);
+        if ( c != '\n' )
+            ungetc(c, stream);
+    }
+    if (p == buf)
+        return NULL;
+    return buf;
+}
+
+/*
+** Py_UniversalNewlineFread is an fread variation that understands
+** all of \r, \n and \r\n conventions.
+** The stream should be opened in binary mode.
+** fobj must be a PyFileObject. In this case there
+** is no readahead but in stead a flag is used to skip a following
+** \n on the next read. Also, if the file is open in binary mode
+** the whole conversion is skipped. Finally, the routine keeps track of
+** the different types of newlines seen.
+*/
+size_t
+Py_UniversalNewlineFread(char *buf, size_t n,
+                         FILE *stream, PyObject *fobj)
+{
+    char *dst = buf;
+    PyFileObject *f = (PyFileObject *)fobj;
+    int newlinetypes, skipnextlf;
+
+    assert(buf != NULL);
+    assert(stream != NULL);
+
+    if (!fobj || !PyFile_Check(fobj)) {
+        errno = ENXIO;          /* What can you do... */
+        return 0;
+    }
+    if (!f->f_univ_newline)
+        return fread(buf, 1, n, stream);
+    newlinetypes = f->f_newlinetypes;
+    skipnextlf = f->f_skipnextlf;
+    /* Invariant:  n is the number of bytes remaining to be filled
+     * in the buffer.
+     */
+    while (n) {
+        size_t nread;
+        int shortread;
+        char *src = dst;
+
+        nread = fread(dst, 1, n, stream);
+        assert(nread <= n);
+        if (nread == 0)
+            break;
+
+        n -= nread; /* assuming 1 byte out for each in; will adjust */
+        shortread = n != 0;             /* true iff EOF or error */
+        while (nread--) {
+            char c = *src++;
+            if (c == '\r') {
+                /* Save as LF and set flag to skip next LF. */
+                *dst++ = '\n';
+                skipnextlf = 1;
+            }
+            else if (skipnextlf && c == '\n') {
+                /* Skip LF, and remember we saw CR LF. */
+                skipnextlf = 0;
+                newlinetypes |= NEWLINE_CRLF;
+                ++n;
+            }
+            else {
+                /* Normal char to be stored in buffer.  Also
+                 * update the newlinetypes flag if either this
+                 * is an LF or the previous char was a CR.
+                 */
+                if (c == '\n')
+                    newlinetypes |= NEWLINE_LF;
+                else if (skipnextlf)
+                    newlinetypes |= NEWLINE_CR;
+                *dst++ = c;
+                skipnextlf = 0;
+            }
+        }
+        if (shortread) {
+            /* If this is EOF, update type flags. */
+            if (skipnextlf && feof(stream))
+                newlinetypes |= NEWLINE_CR;
+            break;
+        }
+    }
+    f->f_newlinetypes = newlinetypes;
+    f->f_skipnextlf = skipnextlf;
+    return dst - buf;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Python-2.7.5/Objects/floatobject.c b/Python-2.7.5/Objects/floatobject.c
new file mode 100644
index 0000000..ba867ef
--- /dev/null
+++ b/Python-2.7.5/Objects/floatobject.c
@@ -0,0 +1,2707 @@
+
+/* Float object implementation */
+
+/* XXX There should be overflow checks here, but it's hard to check
+   for any kind of float exception without losing portability. */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <ctype.h>
+#include <float.h>
+
+#undef MAX
+#undef MIN
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#ifdef _OSF_SOURCE
+/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
+extern int finite(double);
+#endif
+
+/* Special free list -- see comments for same code in intobject.c. */
+#define BLOCK_SIZE      1000    /* 1K less typical malloc overhead */
+#define BHEAD_SIZE      8       /* Enough for a 64-bit pointer */
+#define N_FLOATOBJECTS  ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
+
+struct _floatblock {
+    struct _floatblock *next;
+    PyFloatObject objects[N_FLOATOBJECTS];
+};
+
+typedef struct _floatblock PyFloatBlock;
+
+static PyFloatBlock *block_list = NULL;
+static PyFloatObject *free_list = NULL;
+
+static PyFloatObject *
+fill_free_list(void)
+{
+    PyFloatObject *p, *q;
+    /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
+    p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
+    if (p == NULL)
+        return (PyFloatObject *) PyErr_NoMemory();
+    ((PyFloatBlock *)p)->next = block_list;
+    block_list = (PyFloatBlock *)p;
+    p = &((PyFloatBlock *)p)->objects[0];
+    q = p + N_FLOATOBJECTS;
+    while (--q > p)
+        Py_TYPE(q) = (struct _typeobject *)(q-1);
+    Py_TYPE(q) = NULL;
+    return p + N_FLOATOBJECTS - 1;
+}
+
+double
+PyFloat_GetMax(void)
+{
+    return DBL_MAX;
+}
+
+double
+PyFloat_GetMin(void)
+{
+    return DBL_MIN;
+}
+
+static PyTypeObject FloatInfoType = {0, 0, 0, 0, 0, 0};
+
+PyDoc_STRVAR(floatinfo__doc__,
+"sys.float_info\n\
+\n\
+A structseq holding information about the float type. It contains low level\n\
+information about the precision and internal representation. Please study\n\
+your system's :file:`float.h` for more information.");
+
+static PyStructSequence_Field floatinfo_fields[] = {
+    {"max",             "DBL_MAX -- maximum representable finite float"},
+    {"max_exp",         "DBL_MAX_EXP -- maximum int e such that radix**(e-1) "
+                    "is representable"},
+    {"max_10_exp",      "DBL_MAX_10_EXP -- maximum int e such that 10**e "
+                    "is representable"},
+    {"min",             "DBL_MIN -- Minimum positive normalizer float"},
+    {"min_exp",         "DBL_MIN_EXP -- minimum int e such that radix**(e-1) "
+                    "is a normalized float"},
+    {"min_10_exp",      "DBL_MIN_10_EXP -- minimum int e such that 10**e is "
+                    "a normalized"},
+    {"dig",             "DBL_DIG -- digits"},
+    {"mant_dig",        "DBL_MANT_DIG -- mantissa digits"},
+    {"epsilon",         "DBL_EPSILON -- Difference between 1 and the next "
+                    "representable float"},
+    {"radix",           "FLT_RADIX -- radix of exponent"},
+    {"rounds",          "FLT_ROUNDS -- addition rounds"},
+    {0}
+};
+
+static PyStructSequence_Desc floatinfo_desc = {
+    "sys.float_info",           /* name */
+    floatinfo__doc__,           /* doc */
+    floatinfo_fields,           /* fields */
+    11
+};
+
+PyObject *
+PyFloat_GetInfo(void)
+{
+    PyObject* floatinfo;
+    int pos = 0;
+
+    floatinfo = PyStructSequence_New(&FloatInfoType);
+    if (floatinfo == NULL) {
+        return NULL;
+    }
+
+#define SetIntFlag(flag) \
+    PyStructSequence_SET_ITEM(floatinfo, pos++, PyInt_FromLong(flag))
+#define SetDblFlag(flag) \
+    PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag))
+
+    SetDblFlag(DBL_MAX);
+    SetIntFlag(DBL_MAX_EXP);
+    SetIntFlag(DBL_MAX_10_EXP);
+    SetDblFlag(DBL_MIN);
+    SetIntFlag(DBL_MIN_EXP);
+    SetIntFlag(DBL_MIN_10_EXP);
+    SetIntFlag(DBL_DIG);
+    SetIntFlag(DBL_MANT_DIG);
+    SetDblFlag(DBL_EPSILON);
+    SetIntFlag(FLT_RADIX);
+    SetIntFlag(FLT_ROUNDS);
+#undef SetIntFlag
+#undef SetDblFlag
+
+    if (PyErr_Occurred()) {
+        Py_CLEAR(floatinfo);
+        return NULL;
+    }
+    return floatinfo;
+}
+
+PyObject *
+PyFloat_FromDouble(double fval)
+{
+    register PyFloatObject *op;
+    if (free_list == NULL) {
+        if ((free_list = fill_free_list()) == NULL)
+            return NULL;
+    }
+    /* Inline PyObject_New */
+    op = free_list;
+    free_list = (PyFloatObject *)Py_TYPE(op);
+    PyObject_INIT(op, &PyFloat_Type);
+    op->ob_fval = fval;
+    return (PyObject *) op;
+}
+
+/**************************************************************************
+RED_FLAG 22-Sep-2000 tim
+PyFloat_FromString's pend argument is braindead.  Prior to this RED_FLAG,
+
+1.  If v was a regular string, *pend was set to point to its terminating
+    null byte.  That's useless (the caller can find that without any
+    help from this function!).
+
+2.  If v was a Unicode string, or an object convertible to a character
+    buffer, *pend was set to point into stack trash (the auto temp
+    vector holding the character buffer).  That was downright dangerous.
+
+Since we can't change the interface of a public API function, pend is
+still supported but now *officially* useless:  if pend is not NULL,
+*pend is set to NULL.
+**************************************************************************/
+PyObject *
+PyFloat_FromString(PyObject *v, char **pend)
+{
+    const char *s, *last, *end;
+    double x;
+    char buffer[256]; /* for errors */
+#ifdef Py_USING_UNICODE
+    char *s_buffer = NULL;
+#endif
+    Py_ssize_t len;
+    PyObject *result = NULL;
+
+    if (pend)
+        *pend = NULL;
+    if (PyString_Check(v)) {
+        s = PyString_AS_STRING(v);
+        len = PyString_GET_SIZE(v);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(v)) {
+        s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+        if (s_buffer == NULL)
+            return PyErr_NoMemory();
+        if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
+                                    PyUnicode_GET_SIZE(v),
+                                    s_buffer,
+                                    NULL))
+            goto error;
+        s = s_buffer;
+        len = strlen(s);
+    }
+#endif
+    else if (PyObject_AsCharBuffer(v, &s, &len)) {
+        PyErr_SetString(PyExc_TypeError,
+            "float() argument must be a string or a number");
+        return NULL;
+    }
+    last = s + len;
+
+    while (Py_ISSPACE(*s))
+        s++;
+    /* We don't care about overflow or underflow.  If the platform
+     * supports them, infinities and signed zeroes (on underflow) are
+     * fine. */
+    x = PyOS_string_to_double(s, (char **)&end, NULL);
+    if (x == -1.0 && PyErr_Occurred())
+        goto error;
+    while (Py_ISSPACE(*end))
+        end++;
+    if (end == last)
+        result = PyFloat_FromDouble(x);
+    else {
+        PyOS_snprintf(buffer, sizeof(buffer),
+                      "invalid literal for float(): %.200s", s);
+        PyErr_SetString(PyExc_ValueError, buffer);
+        result = NULL;
+    }
+
+  error:
+#ifdef Py_USING_UNICODE
+    if (s_buffer)
+        PyMem_FREE(s_buffer);
+#endif
+    return result;
+}
+
+static void
+float_dealloc(PyFloatObject *op)
+{
+    if (PyFloat_CheckExact(op)) {
+        Py_TYPE(op) = (struct _typeobject *)free_list;
+        free_list = op;
+    }
+    else
+        Py_TYPE(op)->tp_free((PyObject *)op);
+}
+
+double
+PyFloat_AsDouble(PyObject *op)
+{
+    PyNumberMethods *nb;
+    PyFloatObject *fo;
+    double val;
+
+    if (op && PyFloat_Check(op))
+        return PyFloat_AS_DOUBLE((PyFloatObject*) op);
+
+    if (op == NULL) {
+        PyErr_BadArgument();
+        return -1;
+    }
+
+    if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) {
+        PyErr_SetString(PyExc_TypeError, "a float is required");
+        return -1;
+    }
+
+    fo = (PyFloatObject*) (*nb->nb_float) (op);
+    if (fo == NULL)
+        return -1;
+    if (!PyFloat_Check(fo)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "nb_float should return float object");
+        return -1;
+    }
+
+    val = PyFloat_AS_DOUBLE(fo);
+    Py_DECREF(fo);
+
+    return val;
+}
+
+/* Methods */
+
+/* Macro and helper that convert PyObject obj to a C double and store
+   the value in dbl; this replaces the functionality of the coercion
+   slot function.  If conversion to double raises an exception, obj is
+   set to NULL, and the function invoking this macro returns NULL.  If
+   obj is not of float, int or long type, Py_NotImplemented is incref'ed,
+   stored in obj, and returned from the function invoking this macro.
+*/
+#define CONVERT_TO_DOUBLE(obj, dbl)                     \
+    if (PyFloat_Check(obj))                             \
+        dbl = PyFloat_AS_DOUBLE(obj);                   \
+    else if (convert_to_double(&(obj), &(dbl)) < 0)     \
+        return obj;
+
+static int
+convert_to_double(PyObject **v, double *dbl)
+{
+    register PyObject *obj = *v;
+
+    if (PyInt_Check(obj)) {
+        *dbl = (double)PyInt_AS_LONG(obj);
+    }
+    else if (PyLong_Check(obj)) {
+        *dbl = PyLong_AsDouble(obj);
+        if (*dbl == -1.0 && PyErr_Occurred()) {
+            *v = NULL;
+            return -1;
+        }
+    }
+    else {
+        Py_INCREF(Py_NotImplemented);
+        *v = Py_NotImplemented;
+        return -1;
+    }
+    return 0;
+}
+
+/* XXX PyFloat_AsString and PyFloat_AsReprString are deprecated:
+   XXX they pass a char buffer without passing a length.
+*/
+void
+PyFloat_AsString(char *buf, PyFloatObject *v)
+{
+    char *tmp = PyOS_double_to_string(v->ob_fval, 'g',
+                    PyFloat_STR_PRECISION,
+                    Py_DTSF_ADD_DOT_0, NULL);
+    strcpy(buf, tmp);
+    PyMem_Free(tmp);
+}
+
+void
+PyFloat_AsReprString(char *buf, PyFloatObject *v)
+{
+    char * tmp = PyOS_double_to_string(v->ob_fval, 'r', 0,
+                    Py_DTSF_ADD_DOT_0, NULL);
+    strcpy(buf, tmp);
+    PyMem_Free(tmp);
+}
+
+/* ARGSUSED */
+static int
+float_print(PyFloatObject *v, FILE *fp, int flags)
+{
+    char *buf;
+    if (flags & Py_PRINT_RAW)
+        buf = PyOS_double_to_string(v->ob_fval,
+                                    'g', PyFloat_STR_PRECISION,
+                                    Py_DTSF_ADD_DOT_0, NULL);
+    else
+        buf = PyOS_double_to_string(v->ob_fval,
+                            'r', 0, Py_DTSF_ADD_DOT_0, NULL);
+    Py_BEGIN_ALLOW_THREADS
+    fputs(buf, fp);
+    Py_END_ALLOW_THREADS
+    PyMem_Free(buf);
+    return 0;
+}
+
+static PyObject *
+float_str_or_repr(PyFloatObject *v, int precision, char format_code)
+{
+    PyObject *result;
+    char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
+                                  format_code, precision,
+                                  Py_DTSF_ADD_DOT_0,
+                                  NULL);
+    if (!buf)
+        return PyErr_NoMemory();
+    result = PyString_FromString(buf);
+    PyMem_Free(buf);
+    return result;
+}
+
+static PyObject *
+float_repr(PyFloatObject *v)
+{
+    return float_str_or_repr(v, 0, 'r');
+}
+
+static PyObject *
+float_str(PyFloatObject *v)
+{
+    return float_str_or_repr(v, PyFloat_STR_PRECISION, 'g');
+}
+
+/* Comparison is pretty much a nightmare.  When comparing float to float,
+ * we do it as straightforwardly (and long-windedly) as conceivable, so
+ * that, e.g., Python x == y delivers the same result as the platform
+ * C x == y when x and/or y is a NaN.
+ * When mixing float with an integer type, there's no good *uniform* approach.
+ * Converting the double to an integer obviously doesn't work, since we
+ * may lose info from fractional bits.  Converting the integer to a double
+ * also has two failure modes:  (1) a long int may trigger overflow (too
+ * large to fit in the dynamic range of a C double); (2) even a C long may have
+ * more bits than fit in a C double (e.g., on a a 64-bit box long may have
+ * 63 bits of precision, but a C double probably has only 53), and then
+ * we can falsely claim equality when low-order integer bits are lost by
+ * coercion to double.  So this part is painful too.
+ */
+
+static PyObject*
+float_richcompare(PyObject *v, PyObject *w, int op)
+{
+    double i, j;
+    int r = 0;
+
+    assert(PyFloat_Check(v));
+    i = PyFloat_AS_DOUBLE(v);
+
+    /* Switch on the type of w.  Set i and j to doubles to be compared,
+     * and op to the richcomp to use.
+     */
+    if (PyFloat_Check(w))
+        j = PyFloat_AS_DOUBLE(w);
+
+    else if (!Py_IS_FINITE(i)) {
+        if (PyInt_Check(w) || PyLong_Check(w))
+            /* If i is an infinity, its magnitude exceeds any
+             * finite integer, so it doesn't matter which int we
+             * compare i with.  If i is a NaN, similarly.
+             */
+            j = 0.0;
+        else
+            goto Unimplemented;
+    }
+
+    else if (PyInt_Check(w)) {
+        long jj = PyInt_AS_LONG(w);
+        /* In the worst realistic case I can imagine, C double is a
+         * Cray single with 48 bits of precision, and long has 64
+         * bits.
+         */
+#if SIZEOF_LONG > 6
+        unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj);
+        if (abs >> 48) {
+            /* Needs more than 48 bits.  Make it take the
+             * PyLong path.
+             */
+            PyObject *result;
+            PyObject *ww = PyLong_FromLong(jj);
+
+            if (ww == NULL)
+                return NULL;
+            result = float_richcompare(v, ww, op);
+            Py_DECREF(ww);
+            return result;
+        }
+#endif
+        j = (double)jj;
+        assert((long)j == jj);
+    }
+
+    else if (PyLong_Check(w)) {
+        int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;
+        int wsign = _PyLong_Sign(w);
+        size_t nbits;
+        int exponent;
+
+        if (vsign != wsign) {
+            /* Magnitudes are irrelevant -- the signs alone
+             * determine the outcome.
+             */
+            i = (double)vsign;
+            j = (double)wsign;
+            goto Compare;
+        }
+        /* The signs are the same. */
+        /* Convert w to a double if it fits.  In particular, 0 fits. */
+        nbits = _PyLong_NumBits(w);
+        if (nbits == (size_t)-1 && PyErr_Occurred()) {
+            /* This long is so large that size_t isn't big enough
+             * to hold the # of bits.  Replace with little doubles
+             * that give the same outcome -- w is so large that
+             * its magnitude must exceed the magnitude of any
+             * finite float.
+             */
+            PyErr_Clear();
+            i = (double)vsign;
+            assert(wsign != 0);
+            j = wsign * 2.0;
+            goto Compare;
+        }
+        if (nbits <= 48) {
+            j = PyLong_AsDouble(w);
+            /* It's impossible that <= 48 bits overflowed. */
+            assert(j != -1.0 || ! PyErr_Occurred());
+            goto Compare;
+        }
+        assert(wsign != 0); /* else nbits was 0 */
+        assert(vsign != 0); /* if vsign were 0, then since wsign is
+                             * not 0, we would have taken the
+                             * vsign != wsign branch at the start */
+        /* We want to work with non-negative numbers. */
+        if (vsign < 0) {
+            /* "Multiply both sides" by -1; this also swaps the
+             * comparator.
+             */
+            i = -i;
+            op = _Py_SwappedOp[op];
+        }
+        assert(i > 0.0);
+        (void) frexp(i, &exponent);
+        /* exponent is the # of bits in v before the radix point;
+         * we know that nbits (the # of bits in w) > 48 at this point
+         */
+        if (exponent < 0 || (size_t)exponent < nbits) {
+            i = 1.0;
+            j = 2.0;
+            goto Compare;
+        }
+        if ((size_t)exponent > nbits) {
+            i = 2.0;
+            j = 1.0;
+            goto Compare;
+        }
+        /* v and w have the same number of bits before the radix
+         * point.  Construct two longs that have the same comparison
+         * outcome.
+         */
+        {
+            double fracpart;
+            double intpart;
+            PyObject *result = NULL;
+            PyObject *one = NULL;
+            PyObject *vv = NULL;
+            PyObject *ww = w;
+
+            if (wsign < 0) {
+                ww = PyNumber_Negative(w);
+                if (ww == NULL)
+                    goto Error;
+            }
+            else
+                Py_INCREF(ww);
+
+            fracpart = modf(i, &intpart);
+            vv = PyLong_FromDouble(intpart);
+            if (vv == NULL)
+                goto Error;
+
+            if (fracpart != 0.0) {
+                /* Shift left, and or a 1 bit into vv
+                 * to represent the lost fraction.
+                 */
+                PyObject *temp;
+
+                one = PyInt_FromLong(1);
+                if (one == NULL)
+                    goto Error;
+
+                temp = PyNumber_Lshift(ww, one);
+                if (temp == NULL)
+                    goto Error;
+                Py_DECREF(ww);
+                ww = temp;
+
+                temp = PyNumber_Lshift(vv, one);
+                if (temp == NULL)
+                    goto Error;
+                Py_DECREF(vv);
+                vv = temp;
+
+                temp = PyNumber_Or(vv, one);
+                if (temp == NULL)
+                    goto Error;
+                Py_DECREF(vv);
+                vv = temp;
+            }
+
+            r = PyObject_RichCompareBool(vv, ww, op);
+            if (r < 0)
+                goto Error;
+            result = PyBool_FromLong(r);
+         Error:
+            Py_XDECREF(vv);
+            Py_XDECREF(ww);
+            Py_XDECREF(one);
+            return result;
+        }
+    } /* else if (PyLong_Check(w)) */
+
+    else        /* w isn't float, int, or long */
+        goto Unimplemented;
+
+ Compare:
+    PyFPE_START_PROTECT("richcompare", return NULL)
+    switch (op) {
+    case Py_EQ:
+        r = i == j;
+        break;
+    case Py_NE:
+        r = i != j;
+        break;
+    case Py_LE:
+        r = i <= j;
+        break;
+    case Py_GE:
+        r = i >= j;
+        break;
+    case Py_LT:
+        r = i < j;
+        break;
+    case Py_GT:
+        r = i > j;
+        break;
+    }
+    PyFPE_END_PROTECT(r)
+    return PyBool_FromLong(r);
+
+ Unimplemented:
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+static long
+float_hash(PyFloatObject *v)
+{
+    return _Py_HashDouble(v->ob_fval);
+}
+
+static PyObject *
+float_add(PyObject *v, PyObject *w)
+{
+    double a,b;
+    CONVERT_TO_DOUBLE(v, a);
+    CONVERT_TO_DOUBLE(w, b);
+    PyFPE_START_PROTECT("add", return 0)
+    a = a + b;
+    PyFPE_END_PROTECT(a)
+    return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_sub(PyObject *v, PyObject *w)
+{
+    double a,b;
+    CONVERT_TO_DOUBLE(v, a);
+    CONVERT_TO_DOUBLE(w, b);
+    PyFPE_START_PROTECT("subtract", return 0)
+    a = a - b;
+    PyFPE_END_PROTECT(a)
+    return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_mul(PyObject *v, PyObject *w)
+{
+    double a,b;
+    CONVERT_TO_DOUBLE(v, a);
+    CONVERT_TO_DOUBLE(w, b);
+    PyFPE_START_PROTECT("multiply", return 0)
+    a = a * b;
+    PyFPE_END_PROTECT(a)
+    return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_div(PyObject *v, PyObject *w)
+{
+    double a,b;
+    CONVERT_TO_DOUBLE(v, a);
+    CONVERT_TO_DOUBLE(w, b);
+#ifdef Py_NAN
+    if (b == 0.0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "float division by zero");
+        return NULL;
+    }
+#endif
+    PyFPE_START_PROTECT("divide", return 0)
+    a = a / b;
+    PyFPE_END_PROTECT(a)
+    return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_classic_div(PyObject *v, PyObject *w)
+{
+    double a,b;
+    CONVERT_TO_DOUBLE(v, a);
+    CONVERT_TO_DOUBLE(w, b);
+    if (Py_DivisionWarningFlag >= 2 &&
+        PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0)
+        return NULL;
+#ifdef Py_NAN
+    if (b == 0.0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "float division by zero");
+        return NULL;
+    }
+#endif
+    PyFPE_START_PROTECT("divide", return 0)
+    a = a / b;
+    PyFPE_END_PROTECT(a)
+    return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_rem(PyObject *v, PyObject *w)
+{
+    double vx, wx;
+    double mod;
+    CONVERT_TO_DOUBLE(v, vx);
+    CONVERT_TO_DOUBLE(w, wx);
+#ifdef Py_NAN
+    if (wx == 0.0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "float modulo");
+        return NULL;
+    }
+#endif
+    PyFPE_START_PROTECT("modulo", return 0)
+    mod = fmod(vx, wx);
+    if (mod) {
+        /* ensure the remainder has the same sign as the denominator */
+        if ((wx < 0) != (mod < 0)) {
+            mod += wx;
+        }
+    }
+    else {
+        /* the remainder is zero, and in the presence of signed zeroes
+           fmod returns different results across platforms; ensure
+           it has the same sign as the denominator; we'd like to do
+           "mod = wx * 0.0", but that may get optimized away */
+        mod *= mod;  /* hide "mod = +0" from optimizer */
+        if (wx < 0.0)
+            mod = -mod;
+    }
+    PyFPE_END_PROTECT(mod)
+    return PyFloat_FromDouble(mod);
+}
+
+static PyObject *
+float_divmod(PyObject *v, PyObject *w)
+{
+    double vx, wx;
+    double div, mod, floordiv;
+    CONVERT_TO_DOUBLE(v, vx);
+    CONVERT_TO_DOUBLE(w, wx);
+    if (wx == 0.0) {
+        PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
+        return NULL;
+    }
+    PyFPE_START_PROTECT("divmod", return 0)
+    mod = fmod(vx, wx);
+    /* fmod is typically exact, so vx-mod is *mathematically* an
+       exact multiple of wx.  But this is fp arithmetic, and fp
+       vx - mod is an approximation; the result is that div may
+       not be an exact integral value after the division, although
+       it will always be very close to one.
+    */
+    div = (vx - mod) / wx;
+    if (mod) {
+        /* ensure the remainder has the same sign as the denominator */
+        if ((wx < 0) != (mod < 0)) {
+            mod += wx;
+            div -= 1.0;
+        }
+    }
+    else {
+        /* the remainder is zero, and in the presence of signed zeroes
+           fmod returns different results across platforms; ensure
+           it has the same sign as the denominator; we'd like to do
+           "mod = wx * 0.0", but that may get optimized away */
+        mod *= mod;  /* hide "mod = +0" from optimizer */
+        if (wx < 0.0)
+            mod = -mod;
+    }
+    /* snap quotient to nearest integral value */
+    if (div) {
+        floordiv = floor(div);
+        if (div - floordiv > 0.5)
+            floordiv += 1.0;
+    }
+    else {
+        /* div is zero - get the same sign as the true quotient */
+        div *= div;             /* hide "div = +0" from optimizers */
+        floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
+    }
+    PyFPE_END_PROTECT(floordiv)
+    return Py_BuildValue("(dd)", floordiv, mod);
+}
+
+static PyObject *
+float_floor_div(PyObject *v, PyObject *w)
+{
+    PyObject *t, *r;
+
+    t = float_divmod(v, w);
+    if (t == NULL || t == Py_NotImplemented)
+        return t;
+    assert(PyTuple_CheckExact(t));
+    r = PyTuple_GET_ITEM(t, 0);
+    Py_INCREF(r);
+    Py_DECREF(t);
+    return r;
+}
+
+/* determine whether x is an odd integer or not;  assumes that
+   x is not an infinity or nan. */
+#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0)
+
+static PyObject *
+float_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+    double iv, iw, ix;
+    int negate_result = 0;
+
+    if ((PyObject *)z != Py_None) {
+        PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "
+            "allowed unless all arguments are integers");
+        return NULL;
+    }
+
+    CONVERT_TO_DOUBLE(v, iv);
+    CONVERT_TO_DOUBLE(w, iw);
+
+    /* Sort out special cases here instead of relying on pow() */
+    if (iw == 0) {              /* v**0 is 1, even 0**0 */
+        return PyFloat_FromDouble(1.0);
+    }
+    if (Py_IS_NAN(iv)) {        /* nan**w = nan, unless w == 0 */
+        return PyFloat_FromDouble(iv);
+    }
+    if (Py_IS_NAN(iw)) {        /* v**nan = nan, unless v == 1; 1**nan = 1 */
+        return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw);
+    }
+    if (Py_IS_INFINITY(iw)) {
+        /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if
+         *     abs(v) > 1 (including case where v infinite)
+         *
+         * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if
+         *     abs(v) > 1 (including case where v infinite)
+         */
+        iv = fabs(iv);
+        if (iv == 1.0)
+            return PyFloat_FromDouble(1.0);
+        else if ((iw > 0.0) == (iv > 1.0))
+            return PyFloat_FromDouble(fabs(iw)); /* return inf */
+        else
+            return PyFloat_FromDouble(0.0);
+    }
+    if (Py_IS_INFINITY(iv)) {
+        /* (+-inf)**w is: inf for w positive, 0 for w negative; in
+         *     both cases, we need to add the appropriate sign if w is
+         *     an odd integer.
+         */
+        int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);
+        if (iw > 0.0)
+            return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv));
+        else
+            return PyFloat_FromDouble(iw_is_odd ?
+                                      copysign(0.0, iv) : 0.0);
+    }
+    if (iv == 0.0) {  /* 0**w is: 0 for w positive, 1 for w zero
+                         (already dealt with above), and an error
+                         if w is negative. */
+        int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);
+        if (iw < 0.0) {
+            PyErr_SetString(PyExc_ZeroDivisionError,
+                            "0.0 cannot be raised to a "
+                            "negative power");
+            return NULL;
+        }
+        /* use correct sign if iw is odd */
+        return PyFloat_FromDouble(iw_is_odd ? iv : 0.0);
+    }
+
+    if (iv < 0.0) {
+        /* Whether this is an error is a mess, and bumps into libm
+         * bugs so we have to figure it out ourselves.
+         */
+        if (iw != floor(iw)) {
+            PyErr_SetString(PyExc_ValueError, "negative number "
+                "cannot be raised to a fractional power");
+            return NULL;
+        }
+        /* iw is an exact integer, albeit perhaps a very large
+         * one.  Replace iv by its absolute value and remember
+         * to negate the pow result if iw is odd.
+         */
+        iv = -iv;
+        negate_result = DOUBLE_IS_ODD_INTEGER(iw);
+    }
+
+    if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */
+        /* (-1) ** large_integer also ends up here.  Here's an
+         * extract from the comments for the previous
+         * implementation explaining why this special case is
+         * necessary:
+         *
+         * -1 raised to an exact integer should never be exceptional.
+         * Alas, some libms (chiefly glibc as of early 2003) return
+         * NaN and set EDOM on pow(-1, large_int) if the int doesn't
+         * happen to be representable in a *C* integer.  That's a
+         * bug.
+         */
+        return PyFloat_FromDouble(negate_result ? -1.0 : 1.0);
+    }
+
+    /* Now iv and iw are finite, iw is nonzero, and iv is
+     * positive and not equal to 1.0.  We finally allow
+     * the platform pow to step in and do the rest.
+     */
+    errno = 0;
+    PyFPE_START_PROTECT("pow", return NULL)
+    ix = pow(iv, iw);
+    PyFPE_END_PROTECT(ix)
+    Py_ADJUST_ERANGE1(ix);
+    if (negate_result)
+        ix = -ix;
+
+    if (errno != 0) {
+        /* We don't expect any errno value other than ERANGE, but
+         * the range of libm bugs appears unbounded.
+         */
+        PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
+                             PyExc_ValueError);
+        return NULL;
+    }
+    return PyFloat_FromDouble(ix);
+}
+
+#undef DOUBLE_IS_ODD_INTEGER
+
+static PyObject *
+float_neg(PyFloatObject *v)
+{
+    return PyFloat_FromDouble(-v->ob_fval);
+}
+
+static PyObject *
+float_abs(PyFloatObject *v)
+{
+    return PyFloat_FromDouble(fabs(v->ob_fval));
+}
+
+static int
+float_nonzero(PyFloatObject *v)
+{
+    return v->ob_fval != 0.0;
+}
+
+static int
+float_coerce(PyObject **pv, PyObject **pw)
+{
+    if (PyInt_Check(*pw)) {
+        long x = PyInt_AsLong(*pw);
+        *pw = PyFloat_FromDouble((double)x);
+        Py_INCREF(*pv);
+        return 0;
+    }
+    else if (PyLong_Check(*pw)) {
+        double x = PyLong_AsDouble(*pw);
+        if (x == -1.0 && PyErr_Occurred())
+            return -1;
+        *pw = PyFloat_FromDouble(x);
+        Py_INCREF(*pv);
+        return 0;
+    }
+    else if (PyFloat_Check(*pw)) {
+        Py_INCREF(*pv);
+        Py_INCREF(*pw);
+        return 0;
+    }
+    return 1; /* Can't do it */
+}
+
+static PyObject *
+float_is_integer(PyObject *v)
+{
+    double x = PyFloat_AsDouble(v);
+    PyObject *o;
+
+    if (x == -1.0 && PyErr_Occurred())
+        return NULL;
+    if (!Py_IS_FINITE(x))
+        Py_RETURN_FALSE;
+    errno = 0;
+    PyFPE_START_PROTECT("is_integer", return NULL)
+    o = (floor(x) == x) ? Py_True : Py_False;
+    PyFPE_END_PROTECT(x)
+    if (errno != 0) {
+        PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
+                             PyExc_ValueError);
+        return NULL;
+    }
+    Py_INCREF(o);
+    return o;
+}
+
+#if 0
+static PyObject *
+float_is_inf(PyObject *v)
+{
+    double x = PyFloat_AsDouble(v);
+    if (x == -1.0 && PyErr_Occurred())
+        return NULL;
+    return PyBool_FromLong((long)Py_IS_INFINITY(x));
+}
+
+static PyObject *
+float_is_nan(PyObject *v)
+{
+    double x = PyFloat_AsDouble(v);
+    if (x == -1.0 && PyErr_Occurred())
+        return NULL;
+    return PyBool_FromLong((long)Py_IS_NAN(x));
+}
+
+static PyObject *
+float_is_finite(PyObject *v)
+{
+    double x = PyFloat_AsDouble(v);
+    if (x == -1.0 && PyErr_Occurred())
+        return NULL;
+    return PyBool_FromLong((long)Py_IS_FINITE(x));
+}
+#endif
+
+static PyObject *
+float_trunc(PyObject *v)
+{
+    double x = PyFloat_AsDouble(v);
+    double wholepart;           /* integral portion of x, rounded toward 0 */
+
+    (void)modf(x, &wholepart);
+    /* Try to get out cheap if this fits in a Python int.  The attempt
+     * to cast to long must be protected, as C doesn't define what
+     * happens if the double is too big to fit in a long.  Some rare
+     * systems raise an exception then (RISCOS was mentioned as one,
+     * and someone using a non-default option on Sun also bumped into
+     * that).  Note that checking for <= LONG_MAX is unsafe: if a long
+     * has more bits of precision than a double, casting LONG_MAX to
+     * double may yield an approximation, and if that's rounded up,
+     * then, e.g., wholepart=LONG_MAX+1 would yield true from the C
+     * expression wholepart<=LONG_MAX, despite that wholepart is
+     * actually greater than LONG_MAX.  However, assuming a two's complement
+     * machine with no trap representation, LONG_MIN will be a power of 2 (and
+     * hence exactly representable as a double), and LONG_MAX = -1-LONG_MIN, so
+     * the comparisons with (double)LONG_MIN below should be safe.
+     */
+    if ((double)LONG_MIN <= wholepart && wholepart < -(double)LONG_MIN) {
+        const long aslong = (long)wholepart;
+        return PyInt_FromLong(aslong);
+    }
+    return PyLong_FromDouble(wholepart);
+}
+
+static PyObject *
+float_long(PyObject *v)
+{
+    double x = PyFloat_AsDouble(v);
+    return PyLong_FromDouble(x);
+}
+
+/* _Py_double_round: rounds a finite nonzero double to the closest multiple of
+   10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
+   ndigits <= 323).  Returns a Python float, or sets a Python error and
+   returns NULL on failure (OverflowError and memory errors are possible). */
+
+#ifndef PY_NO_SHORT_FLOAT_REPR
+/* version of _Py_double_round that uses the correctly-rounded string<->double
+   conversions from Python/dtoa.c */
+
+/* FIVE_POW_LIMIT is the largest k such that 5**k is exactly representable as
+   a double.  Since we're using the code in Python/dtoa.c, it should be safe
+   to assume that C doubles are IEEE 754 binary64 format.  To be on the safe
+   side, we check this. */
+#if DBL_MANT_DIG == 53
+#define FIVE_POW_LIMIT 22
+#else
+#error "C doubles do not appear to be IEEE 754 binary64 format"
+#endif
+
+PyObject *
+_Py_double_round(double x, int ndigits) {
+
+    double rounded, m;
+    Py_ssize_t buflen, mybuflen=100;
+    char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;
+    int decpt, sign, val, halfway_case;
+    PyObject *result = NULL;
+    _Py_SET_53BIT_PRECISION_HEADER;
+
+    /* Easy path for the common case ndigits == 0. */
+    if (ndigits == 0) {
+        rounded = round(x);
+        if (fabs(rounded - x) == 0.5)
+            /* halfway between two integers; use round-away-from-zero */
+            rounded = x + (x > 0.0 ? 0.5 : -0.5);
+        return PyFloat_FromDouble(rounded);
+    }
+
+    /* The basic idea is very simple: convert and round the double to a
+       decimal string using _Py_dg_dtoa, then convert that decimal string
+       back to a double with _Py_dg_strtod.  There's one minor difficulty:
+       Python 2.x expects round to do round-half-away-from-zero, while
+       _Py_dg_dtoa does round-half-to-even.  So we need some way to detect
+       and correct the halfway cases.
+
+       Detection: a halfway value has the form k * 0.5 * 10**-ndigits for
+       some odd integer k.  Or in other words, a rational number x is
+       exactly halfway between two multiples of 10**-ndigits if its
+       2-valuation is exactly -ndigits-1 and its 5-valuation is at least
+       -ndigits.  For ndigits >= 0 the latter condition is automatically
+       satisfied for a binary float x, since any such float has
+       nonnegative 5-valuation.  For 0 > ndigits >= -22, x needs to be an
+       integral multiple of 5**-ndigits; we can check this using fmod.
+       For -22 > ndigits, there are no halfway cases: 5**23 takes 54 bits
+       to represent exactly, so any odd multiple of 0.5 * 10**n for n >=
+       23 takes at least 54 bits of precision to represent exactly.
+
+       Correction: a simple strategy for dealing with halfway cases is to
+       (for the halfway cases only) call _Py_dg_dtoa with an argument of
+       ndigits+1 instead of ndigits (thus doing an exact conversion to
+       decimal), round the resulting string manually, and then convert
+       back using _Py_dg_strtod.
+    */
+
+    /* nans, infinities and zeros should have already been dealt
+       with by the caller (in this case, builtin_round) */
+    assert(Py_IS_FINITE(x) && x != 0.0);
+
+    /* find 2-valuation val of x */
+    m = frexp(x, &val);
+    while (m != floor(m)) {
+        m *= 2.0;
+        val--;
+    }
+
+    /* determine whether this is a halfway case */
+    if (val == -ndigits-1) {
+        if (ndigits >= 0)
+            halfway_case = 1;
+        else if (ndigits >= -FIVE_POW_LIMIT) {
+            double five_pow = 1.0;
+            int i;
+            for (i=0; i < -ndigits; i++)
+                five_pow *= 5.0;
+            halfway_case = fmod(x, five_pow) == 0.0;
+        }
+        else
+            halfway_case = 0;
+    }
+    else
+        halfway_case = 0;
+
+    /* round to a decimal string; use an extra place for halfway case */
+    _Py_SET_53BIT_PRECISION_START;
+    buf = _Py_dg_dtoa(x, 3, ndigits+halfway_case, &decpt, &sign, &buf_end);
+    _Py_SET_53BIT_PRECISION_END;
+    if (buf == NULL) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+    buflen = buf_end - buf;
+
+    /* in halfway case, do the round-half-away-from-zero manually */
+    if (halfway_case) {
+        int i, carry;
+        /* sanity check: _Py_dg_dtoa should not have stripped
+           any zeros from the result: there should be exactly
+           ndigits+1 places following the decimal point, and
+           the last digit in the buffer should be a '5'.*/
+        assert(buflen - decpt == ndigits+1);
+        assert(buf[buflen-1] == '5');
+
+        /* increment and shift right at the same time. */
+        decpt += 1;
+        carry = 1;
+        for (i=buflen-1; i-- > 0;) {
+            carry += buf[i] - '0';
+            buf[i+1] = carry % 10 + '0';
+            carry /= 10;
+        }
+        buf[0] = carry + '0';
+    }
+
+    /* Get new buffer if shortbuf is too small.  Space needed <= buf_end -
+       buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */
+    if (buflen + 8 > mybuflen) {
+        mybuflen = buflen+8;
+        mybuf = (char *)PyMem_Malloc(mybuflen);
+        if (mybuf == NULL) {
+            PyErr_NoMemory();
+            goto exit;
+        }
+    }
+    /* copy buf to mybuf, adding exponent, sign and leading 0 */
+    PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""),
+                  buf, decpt - (int)buflen);
+
+    /* and convert the resulting string back to a double */
+    errno = 0;
+    _Py_SET_53BIT_PRECISION_START;
+    rounded = _Py_dg_strtod(mybuf, NULL);
+    _Py_SET_53BIT_PRECISION_END;
+    if (errno == ERANGE && fabs(rounded) >= 1.)
+        PyErr_SetString(PyExc_OverflowError,
+                        "rounded value too large to represent");
+    else
+        result = PyFloat_FromDouble(rounded);
+
+    /* done computing value;  now clean up */
+    if (mybuf != shortbuf)
+        PyMem_Free(mybuf);
+  exit:
+    _Py_dg_freedtoa(buf);
+    return result;
+}
+
+#undef FIVE_POW_LIMIT
+
+#else /* PY_NO_SHORT_FLOAT_REPR */
+
+/* fallback version, to be used when correctly rounded binary<->decimal
+   conversions aren't available */
+
+PyObject *
+_Py_double_round(double x, int ndigits) {
+    double pow1, pow2, y, z;
+    if (ndigits >= 0) {
+        if (ndigits > 22) {
+            /* pow1 and pow2 are each safe from overflow, but
+               pow1*pow2 ~= pow(10.0, ndigits) might overflow */
+            pow1 = pow(10.0, (double)(ndigits-22));
+            pow2 = 1e22;
+        }
+        else {
+            pow1 = pow(10.0, (double)ndigits);
+            pow2 = 1.0;
+        }
+        y = (x*pow1)*pow2;
+        /* if y overflows, then rounded value is exactly x */
+        if (!Py_IS_FINITE(y))
+            return PyFloat_FromDouble(x);
+    }
+    else {
+        pow1 = pow(10.0, (double)-ndigits);
+        pow2 = 1.0; /* unused; silences a gcc compiler warning */
+        y = x / pow1;
+    }
+
+    z = round(y);
+    if (fabs(y-z) == 0.5)
+        /* halfway between two integers; use round-away-from-zero */
+        z = y + copysign(0.5, y);
+
+    if (ndigits >= 0)
+        z = (z / pow2) / pow1;
+    else
+        z *= pow1;
+
+    /* if computation resulted in overflow, raise OverflowError */
+    if (!Py_IS_FINITE(z)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "overflow occurred during round");
+        return NULL;
+    }
+
+    return PyFloat_FromDouble(z);
+}
+
+#endif /* PY_NO_SHORT_FLOAT_REPR */
+
+static PyObject *
+float_float(PyObject *v)
+{
+    if (PyFloat_CheckExact(v))
+        Py_INCREF(v);
+    else
+        v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
+    return v;
+}
+
+/* turn ASCII hex characters into integer values and vice versa */
+
+static char
+char_from_hex(int x)
+{
+    assert(0 <= x && x < 16);
+    return "0123456789abcdef"[x];
+}
+
+static int
+hex_from_char(char c) {
+    int x;
+    switch(c) {
+    case '0':
+        x = 0;
+        break;
+    case '1':
+        x = 1;
+        break;
+    case '2':
+        x = 2;
+        break;
+    case '3':
+        x = 3;
+        break;
+    case '4':
+        x = 4;
+        break;
+    case '5':
+        x = 5;
+        break;
+    case '6':
+        x = 6;
+        break;
+    case '7':
+        x = 7;
+        break;
+    case '8':
+        x = 8;
+        break;
+    case '9':
+        x = 9;
+        break;
+    case 'a':
+    case 'A':
+        x = 10;
+        break;
+    case 'b':
+    case 'B':
+        x = 11;
+        break;
+    case 'c':
+    case 'C':
+        x = 12;
+        break;
+    case 'd':
+    case 'D':
+        x = 13;
+        break;
+    case 'e':
+    case 'E':
+        x = 14;
+        break;
+    case 'f':
+    case 'F':
+        x = 15;
+        break;
+    default:
+        x = -1;
+        break;
+    }
+    return x;
+}
+
+/* convert a float to a hexadecimal string */
+
+/* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer
+   of the form 4k+1. */
+#define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4
+
+static PyObject *
+float_hex(PyObject *v)
+{
+    double x, m;
+    int e, shift, i, si, esign;
+    /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the
+       trailing NUL byte. */
+    char s[(TOHEX_NBITS-1)/4+3];
+
+    CONVERT_TO_DOUBLE(v, x);
+
+    if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
+        return float_str((PyFloatObject *)v);
+
+    if (x == 0.0) {
+        if (copysign(1.0, x) == -1.0)
+            return PyString_FromString("-0x0.0p+0");
+        else
+            return PyString_FromString("0x0.0p+0");
+    }
+
+    m = frexp(fabs(x), &e);
+    shift = 1 - MAX(DBL_MIN_EXP - e, 0);
+    m = ldexp(m, shift);
+    e -= shift;
+
+    si = 0;
+    s[si] = char_from_hex((int)m);
+    si++;
+    m -= (int)m;
+    s[si] = '.';
+    si++;
+    for (i=0; i < (TOHEX_NBITS-1)/4; i++) {
+        m *= 16.0;
+        s[si] = char_from_hex((int)m);
+        si++;
+        m -= (int)m;
+    }
+    s[si] = '\0';
+
+    if (e < 0) {
+        esign = (int)'-';
+        e = -e;
+    }
+    else
+        esign = (int)'+';
+
+    if (x < 0.0)
+        return PyString_FromFormat("-0x%sp%c%d", s, esign, e);
+    else
+        return PyString_FromFormat("0x%sp%c%d", s, esign, e);
+}
+
+PyDoc_STRVAR(float_hex_doc,
+"float.hex() -> string\n\
+\n\
+Return a hexadecimal representation of a floating-point number.\n\
+>>> (-0.1).hex()\n\
+'-0x1.999999999999ap-4'\n\
+>>> 3.14159.hex()\n\
+'0x1.921f9f01b866ep+1'");
+
+/* Case-insensitive locale-independent string match used for nan and inf
+   detection. t should be lower-case and null-terminated.  Return a nonzero
+   result if the first strlen(t) characters of s match t and 0 otherwise. */
+
+static int
+case_insensitive_match(const char *s, const char *t)
+{
+    while(*t && Py_TOLOWER(*s) == *t) {
+        s++;
+        t++;
+    }
+    return *t ? 0 : 1;
+}
+
+/* Convert a hexadecimal string to a float. */
+
+static PyObject *
+float_fromhex(PyObject *cls, PyObject *arg)
+{
+    PyObject *result_as_float, *result;
+    double x;
+    long exp, top_exp, lsb, key_digit;
+    char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end;
+    int half_eps, digit, round_up, sign=1;
+    Py_ssize_t length, ndigits, fdigits, i;
+
+    /*
+     * For the sake of simplicity and correctness, we impose an artificial
+     * limit on ndigits, the total number of hex digits in the coefficient
+     * The limit is chosen to ensure that, writing exp for the exponent,
+     *
+     *   (1) if exp > LONG_MAX/2 then the value of the hex string is
+     *   guaranteed to overflow (provided it's nonzero)
+     *
+     *   (2) if exp < LONG_MIN/2 then the value of the hex string is
+     *   guaranteed to underflow to 0.
+     *
+     *   (3) if LONG_MIN/2 <= exp <= LONG_MAX/2 then there's no danger of
+     *   overflow in the calculation of exp and top_exp below.
+     *
+     * More specifically, ndigits is assumed to satisfy the following
+     * inequalities:
+     *
+     *   4*ndigits <= DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2
+     *   4*ndigits <= LONG_MAX/2 + 1 - DBL_MAX_EXP
+     *
+     * If either of these inequalities is not satisfied, a ValueError is
+     * raised.  Otherwise, write x for the value of the hex string, and
+     * assume x is nonzero.  Then
+     *
+     *   2**(exp-4*ndigits) <= |x| < 2**(exp+4*ndigits).
+     *
+     * Now if exp > LONG_MAX/2 then:
+     *
+     *   exp - 4*ndigits >= LONG_MAX/2 + 1 - (LONG_MAX/2 + 1 - DBL_MAX_EXP)
+     *                    = DBL_MAX_EXP
+     *
+     * so |x| >= 2**DBL_MAX_EXP, which is too large to be stored in C
+     * double, so overflows.  If exp < LONG_MIN/2, then
+     *
+     *   exp + 4*ndigits <= LONG_MIN/2 - 1 + (
+     *                      DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2)
+     *                    = DBL_MIN_EXP - DBL_MANT_DIG - 1
+     *
+     * and so |x| < 2**(DBL_MIN_EXP-DBL_MANT_DIG-1), hence underflows to 0
+     * when converted to a C double.
+     *
+     * It's easy to show that if LONG_MIN/2 <= exp <= LONG_MAX/2 then both
+     * exp+4*ndigits and exp-4*ndigits are within the range of a long.
+     */
+
+    if (PyString_AsStringAndSize(arg, &s, &length))
+        return NULL;
+    s_end = s + length;
+
+    /********************
+     * Parse the string *
+     ********************/
+
+    /* leading whitespace and optional sign */
+    while (Py_ISSPACE(*s))
+        s++;
+    if (*s == '-') {
+        s++;
+        sign = -1;
+    }
+    else if (*s == '+')
+        s++;
+
+    /* infinities and nans */
+    if (*s == 'i' || *s == 'I') {
+        if (!case_insensitive_match(s+1, "nf"))
+            goto parse_error;
+        s += 3;
+        x = Py_HUGE_VAL;
+        if (case_insensitive_match(s, "inity"))
+            s += 5;
+        goto finished;
+    }
+    if (*s == 'n' || *s == 'N') {
+        if (!case_insensitive_match(s+1, "an"))
+            goto parse_error;
+        s += 3;
+        x = Py_NAN;
+        goto finished;
+    }
+
+    /* [0x] */
+    s_store = s;
+    if (*s == '0') {
+        s++;
+        if (*s == 'x' || *s == 'X')
+            s++;
+        else
+            s = s_store;
+    }
+
+    /* coefficient: <integer> [. <fraction>] */
+    coeff_start = s;
+    while (hex_from_char(*s) >= 0)
+        s++;
+    s_store = s;
+    if (*s == '.') {
+        s++;
+        while (hex_from_char(*s) >= 0)
+            s++;
+        coeff_end = s-1;
+    }
+    else
+        coeff_end = s;
+
+    /* ndigits = total # of hex digits; fdigits = # after point */
+    ndigits = coeff_end - coeff_start;
+    fdigits = coeff_end - s_store;
+    if (ndigits == 0)
+        goto parse_error;
+    if (ndigits > MIN(DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2,
+                      LONG_MAX/2 + 1 - DBL_MAX_EXP)/4)
+        goto insane_length_error;
+
+    /* [p <exponent>] */
+    if (*s == 'p' || *s == 'P') {
+        s++;
+        exp_start = s;
+        if (*s == '-' || *s == '+')
+            s++;
+        if (!('0' <= *s && *s <= '9'))
+            goto parse_error;
+        s++;
+        while ('0' <= *s && *s <= '9')
+            s++;
+        exp = strtol(exp_start, NULL, 10);
+    }
+    else
+        exp = 0;
+
+/* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */
+#define HEX_DIGIT(j) hex_from_char(*((j) < fdigits ?            \
+                     coeff_end-(j) :                                    \
+                     coeff_end-1-(j)))
+
+    /*******************************************
+     * Compute rounded value of the hex string *
+     *******************************************/
+
+    /* Discard leading zeros, and catch extreme overflow and underflow */
+    while (ndigits > 0 && HEX_DIGIT(ndigits-1) == 0)
+        ndigits--;
+    if (ndigits == 0 || exp < LONG_MIN/2) {
+        x = 0.0;
+        goto finished;
+    }
+    if (exp > LONG_MAX/2)
+        goto overflow_error;
+
+    /* Adjust exponent for fractional part. */
+    exp = exp - 4*((long)fdigits);
+
+    /* top_exp = 1 more than exponent of most sig. bit of coefficient */
+    top_exp = exp + 4*((long)ndigits - 1);
+    for (digit = HEX_DIGIT(ndigits-1); digit != 0; digit /= 2)
+        top_exp++;
+
+    /* catch almost all nonextreme cases of overflow and underflow here */
+    if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG) {
+        x = 0.0;
+        goto finished;
+    }
+    if (top_exp > DBL_MAX_EXP)
+        goto overflow_error;
+
+    /* lsb = exponent of least significant bit of the *rounded* value.
+       This is top_exp - DBL_MANT_DIG unless result is subnormal. */
+    lsb = MAX(top_exp, (long)DBL_MIN_EXP) - DBL_MANT_DIG;
+
+    x = 0.0;
+    if (exp >= lsb) {
+        /* no rounding required */
+        for (i = ndigits-1; i >= 0; i--)
+            x = 16.0*x + HEX_DIGIT(i);
+        x = ldexp(x, (int)(exp));
+        goto finished;
+    }
+    /* rounding required.  key_digit is the index of the hex digit
+       containing the first bit to be rounded away. */
+    half_eps = 1 << (int)((lsb - exp - 1) % 4);
+    key_digit = (lsb - exp - 1) / 4;
+    for (i = ndigits-1; i > key_digit; i--)
+        x = 16.0*x + HEX_DIGIT(i);
+    digit = HEX_DIGIT(key_digit);
+    x = 16.0*x + (double)(digit & (16-2*half_eps));
+
+    /* round-half-even: round up if bit lsb-1 is 1 and at least one of
+       bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. */
+    if ((digit & half_eps) != 0) {
+        round_up = 0;
+        if ((digit & (3*half_eps-1)) != 0 ||
+            (half_eps == 8 && (HEX_DIGIT(key_digit+1) & 1) != 0))
+            round_up = 1;
+        else
+            for (i = key_digit-1; i >= 0; i--)
+                if (HEX_DIGIT(i) != 0) {
+                    round_up = 1;
+                    break;
+                }
+        if (round_up == 1) {
+            x += 2*half_eps;
+            if (top_exp == DBL_MAX_EXP &&
+                x == ldexp((double)(2*half_eps), DBL_MANT_DIG))
+                /* overflow corner case: pre-rounded value <
+                   2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP. */
+                goto overflow_error;
+        }
+    }
+    x = ldexp(x, (int)(exp+4*key_digit));
+
+  finished:
+    /* optional trailing whitespace leading to the end of the string */
+    while (Py_ISSPACE(*s))
+        s++;
+    if (s != s_end)
+        goto parse_error;
+    result_as_float = Py_BuildValue("(d)", sign * x);
+    if (result_as_float == NULL)
+        return NULL;
+    result = PyObject_CallObject(cls, result_as_float);
+    Py_DECREF(result_as_float);
+    return result;
+
+  overflow_error:
+    PyErr_SetString(PyExc_OverflowError,
+                    "hexadecimal value too large to represent as a float");
+    return NULL;
+
+  parse_error:
+    PyErr_SetString(PyExc_ValueError,
+                    "invalid hexadecimal floating-point string");
+    return NULL;
+
+  insane_length_error:
+    PyErr_SetString(PyExc_ValueError,
+                    "hexadecimal string too long to convert");
+    return NULL;
+}
+
+PyDoc_STRVAR(float_fromhex_doc,
+"float.fromhex(string) -> float\n\
+\n\
+Create a floating-point number from a hexadecimal string.\n\
+>>> float.fromhex('0x1.ffffp10')\n\
+2047.984375\n\
+>>> float.fromhex('-0x1p-1074')\n\
+-4.9406564584124654e-324");
+
+
+static PyObject *
+float_as_integer_ratio(PyObject *v, PyObject *unused)
+{
+    double self;
+    double float_part;
+    int exponent;
+    int i;
+
+    PyObject *prev;
+    PyObject *py_exponent = NULL;
+    PyObject *numerator = NULL;
+    PyObject *denominator = NULL;
+    PyObject *result_pair = NULL;
+    PyNumberMethods *long_methods = PyLong_Type.tp_as_number;
+
+#define INPLACE_UPDATE(obj, call) \
+    prev = obj; \
+    obj = call; \
+    Py_DECREF(prev); \
+
+    CONVERT_TO_DOUBLE(v, self);
+
+    if (Py_IS_INFINITY(self)) {
+      PyErr_SetString(PyExc_OverflowError,
+                      "Cannot pass infinity to float.as_integer_ratio.");
+      return NULL;
+    }
+#ifdef Py_NAN
+    if (Py_IS_NAN(self)) {
+      PyErr_SetString(PyExc_ValueError,
+                      "Cannot pass NaN to float.as_integer_ratio.");
+      return NULL;
+    }
+#endif
+
+    PyFPE_START_PROTECT("as_integer_ratio", goto error);
+    float_part = frexp(self, &exponent);        /* self == float_part * 2**exponent exactly */
+    PyFPE_END_PROTECT(float_part);
+
+    for (i=0; i<300 && float_part != floor(float_part) ; i++) {
+        float_part *= 2.0;
+        exponent--;
+    }
+    /* self == float_part * 2**exponent exactly and float_part is integral.
+       If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part
+       to be truncated by PyLong_FromDouble(). */
+
+    numerator = PyLong_FromDouble(float_part);
+    if (numerator == NULL) goto error;
+
+    /* fold in 2**exponent */
+    denominator = PyLong_FromLong(1);
+    py_exponent = PyLong_FromLong(labs((long)exponent));
+    if (py_exponent == NULL) goto error;
+    INPLACE_UPDATE(py_exponent,
+                   long_methods->nb_lshift(denominator, py_exponent));
+    if (py_exponent == NULL) goto error;
+    if (exponent > 0) {
+        INPLACE_UPDATE(numerator,
+                       long_methods->nb_multiply(numerator, py_exponent));
+        if (numerator == NULL) goto error;
+    }
+    else {
+        Py_DECREF(denominator);
+        denominator = py_exponent;
+        py_exponent = NULL;
+    }
+
+    /* Returns ints instead of longs where possible */
+    INPLACE_UPDATE(numerator, PyNumber_Int(numerator));
+    if (numerator == NULL) goto error;
+    INPLACE_UPDATE(denominator, PyNumber_Int(denominator));
+    if (denominator == NULL) goto error;
+
+    result_pair = PyTuple_Pack(2, numerator, denominator);
+
+#undef INPLACE_UPDATE
+error:
+    Py_XDECREF(py_exponent);
+    Py_XDECREF(denominator);
+    Py_XDECREF(numerator);
+    return result_pair;
+}
+
+PyDoc_STRVAR(float_as_integer_ratio_doc,
+"float.as_integer_ratio() -> (int, int)\n"
+"\n"
+"Returns a pair of integers, whose ratio is exactly equal to the original\n"
+"float and with a positive denominator.\n"
+"Raises OverflowError on infinities and a ValueError on NaNs.\n"
+"\n"
+">>> (10.0).as_integer_ratio()\n"
+"(10, 1)\n"
+">>> (0.0).as_integer_ratio()\n"
+"(0, 1)\n"
+">>> (-.25).as_integer_ratio()\n"
+"(-1, 4)");
+
+
+static PyObject *
+float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *x = Py_False; /* Integer zero */
+    static char *kwlist[] = {"x", 0};
+
+    if (type != &PyFloat_Type)
+        return float_subtype_new(type, args, kwds); /* Wimp out */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
+        return NULL;
+    /* If it's a string, but not a string subclass, use
+       PyFloat_FromString. */
+    if (PyString_CheckExact(x))
+        return PyFloat_FromString(x, NULL);
+    return PyNumber_Float(x);
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of float:
+   first create a regular float from whatever arguments we got,
+   then allocate a subtype instance and initialize its ob_fval
+   from the regular float.  The regular float is then thrown away.
+*/
+static PyObject *
+float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *tmp, *newobj;
+
+    assert(PyType_IsSubtype(type, &PyFloat_Type));
+    tmp = float_new(&PyFloat_Type, args, kwds);
+    if (tmp == NULL)
+        return NULL;
+    assert(PyFloat_CheckExact(tmp));
+    newobj = type->tp_alloc(type, 0);
+    if (newobj == NULL) {
+        Py_DECREF(tmp);
+        return NULL;
+    }
+    ((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;
+    Py_DECREF(tmp);
+    return newobj;
+}
+
+static PyObject *
+float_getnewargs(PyFloatObject *v)
+{
+    return Py_BuildValue("(d)", v->ob_fval);
+}
+
+/* this is for the benefit of the pack/unpack routines below */
+
+typedef enum {
+    unknown_format, ieee_big_endian_format, ieee_little_endian_format
+} float_format_type;
+
+static float_format_type double_format, float_format;
+static float_format_type detected_double_format, detected_float_format;
+
+static PyObject *
+float_getformat(PyTypeObject *v, PyObject* arg)
+{
+    char* s;
+    float_format_type r;
+
+    if (!PyString_Check(arg)) {
+        PyErr_Format(PyExc_TypeError,
+         "__getformat__() argument must be string, not %.500s",
+                         Py_TYPE(arg)->tp_name);
+        return NULL;
+    }
+    s = PyString_AS_STRING(arg);
+    if (strcmp(s, "double") == 0) {
+        r = double_format;
+    }
+    else if (strcmp(s, "float") == 0) {
+        r = float_format;
+    }
+    else {
+        PyErr_SetString(PyExc_ValueError,
+                        "__getformat__() argument 1 must be "
+                        "'double' or 'float'");
+        return NULL;
+    }
+
+    switch (r) {
+    case unknown_format:
+        return PyString_FromString("unknown");
+    case ieee_little_endian_format:
+        return PyString_FromString("IEEE, little-endian");
+    case ieee_big_endian_format:
+        return PyString_FromString("IEEE, big-endian");
+    default:
+        Py_FatalError("insane float_format or double_format");
+        return NULL;
+    }
+}
+
+PyDoc_STRVAR(float_getformat_doc,
+"float.__getformat__(typestr) -> string\n"
+"\n"
+"You probably don't want to use this function.  It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'.  This function returns whichever of\n"
+"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
+"format of floating point numbers used by the C type named by typestr.");
+
+static PyObject *
+float_setformat(PyTypeObject *v, PyObject* args)
+{
+    char* typestr;
+    char* format;
+    float_format_type f;
+    float_format_type detected;
+    float_format_type *p;
+
+    if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
+        return NULL;
+
+    if (strcmp(typestr, "double") == 0) {
+        p = &double_format;
+        detected = detected_double_format;
+    }
+    else if (strcmp(typestr, "float") == 0) {
+        p = &float_format;
+        detected = detected_float_format;
+    }
+    else {
+        PyErr_SetString(PyExc_ValueError,
+                        "__setformat__() argument 1 must "
+                        "be 'double' or 'float'");
+        return NULL;
+    }
+
+    if (strcmp(format, "unknown") == 0) {
+        f = unknown_format;
+    }
+    else if (strcmp(format, "IEEE, little-endian") == 0) {
+        f = ieee_little_endian_format;
+    }
+    else if (strcmp(format, "IEEE, big-endian") == 0) {
+        f = ieee_big_endian_format;
+    }
+    else {
+        PyErr_SetString(PyExc_ValueError,
+                        "__setformat__() argument 2 must be "
+                        "'unknown', 'IEEE, little-endian' or "
+                        "'IEEE, big-endian'");
+        return NULL;
+
+    }
+
+    if (f != unknown_format && f != detected) {
+        PyErr_Format(PyExc_ValueError,
+                     "can only set %s format to 'unknown' or the "
+                     "detected platform value", typestr);
+        return NULL;
+    }
+
+    *p = f;
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(float_setformat_doc,
+"float.__setformat__(typestr, fmt) -> None\n"
+"\n"
+"You probably don't want to use this function.  It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'.  fmt must be one of 'unknown',\n"
+"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"
+"one of the latter two if it appears to match the underlying C reality.\n"
+"\n"
+"Overrides the automatic determination of C-level floating point type.\n"
+"This affects how floats are converted to and from binary strings.");
+
+static PyObject *
+float_getzero(PyObject *v, void *closure)
+{
+    return PyFloat_FromDouble(0.0);
+}
+
+static PyObject *
+float__format__(PyObject *self, PyObject *args)
+{
+    PyObject *format_spec;
+
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+        return NULL;
+    if (PyBytes_Check(format_spec))
+        return _PyFloat_FormatAdvanced(self,
+                                       PyBytes_AS_STRING(format_spec),
+                                       PyBytes_GET_SIZE(format_spec));
+    if (PyUnicode_Check(format_spec)) {
+        /* Convert format_spec to a str */
+        PyObject *result;
+        PyObject *str_spec = PyObject_Str(format_spec);
+
+        if (str_spec == NULL)
+            return NULL;
+
+        result = _PyFloat_FormatAdvanced(self,
+                                         PyBytes_AS_STRING(str_spec),
+                                         PyBytes_GET_SIZE(str_spec));
+
+        Py_DECREF(str_spec);
+        return result;
+    }
+    PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+    return NULL;
+}
+
+PyDoc_STRVAR(float__format__doc,
+"float.__format__(format_spec) -> string\n"
+"\n"
+"Formats the float according to format_spec.");
+
+
+static PyMethodDef float_methods[] = {
+    {"conjugate",       (PyCFunction)float_float,       METH_NOARGS,
+     "Returns self, the complex conjugate of any float."},
+    {"__trunc__",       (PyCFunction)float_trunc, METH_NOARGS,
+     "Returns the Integral closest to x between 0 and x."},
+    {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS,
+     float_as_integer_ratio_doc},
+    {"fromhex", (PyCFunction)float_fromhex,
+     METH_O|METH_CLASS, float_fromhex_doc},
+    {"hex", (PyCFunction)float_hex,
+     METH_NOARGS, float_hex_doc},
+    {"is_integer",      (PyCFunction)float_is_integer,  METH_NOARGS,
+     "Returns True if the float is an integer."},
+#if 0
+    {"is_inf",          (PyCFunction)float_is_inf,      METH_NOARGS,
+     "Returns True if the float is positive or negative infinite."},
+    {"is_finite",       (PyCFunction)float_is_finite,   METH_NOARGS,
+     "Returns True if the float is finite, neither infinite nor NaN."},
+    {"is_nan",          (PyCFunction)float_is_nan,      METH_NOARGS,
+     "Returns True if the float is not a number (NaN)."},
+#endif
+    {"__getnewargs__",          (PyCFunction)float_getnewargs,  METH_NOARGS},
+    {"__getformat__",           (PyCFunction)float_getformat,
+     METH_O|METH_CLASS,                 float_getformat_doc},
+    {"__setformat__",           (PyCFunction)float_setformat,
+     METH_VARARGS|METH_CLASS,           float_setformat_doc},
+    {"__format__",          (PyCFunction)float__format__,
+     METH_VARARGS,                  float__format__doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyGetSetDef float_getset[] = {
+    {"real",
+     (getter)float_float, (setter)NULL,
+     "the real part of a complex number",
+     NULL},
+    {"imag",
+     (getter)float_getzero, (setter)NULL,
+     "the imaginary part of a complex number",
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(float_doc,
+"float(x) -> floating point number\n\
+\n\
+Convert a string or number to a floating point number, if possible.");
+
+
+static PyNumberMethods float_as_number = {
+    float_add,          /*nb_add*/
+    float_sub,          /*nb_subtract*/
+    float_mul,          /*nb_multiply*/
+    float_classic_div, /*nb_divide*/
+    float_rem,          /*nb_remainder*/
+    float_divmod,       /*nb_divmod*/
+    float_pow,          /*nb_power*/
+    (unaryfunc)float_neg, /*nb_negative*/
+    (unaryfunc)float_float, /*nb_positive*/
+    (unaryfunc)float_abs, /*nb_absolute*/
+    (inquiry)float_nonzero, /*nb_nonzero*/
+    0,                  /*nb_invert*/
+    0,                  /*nb_lshift*/
+    0,                  /*nb_rshift*/
+    0,                  /*nb_and*/
+    0,                  /*nb_xor*/
+    0,                  /*nb_or*/
+    float_coerce,       /*nb_coerce*/
+    float_trunc,        /*nb_int*/
+    float_long,         /*nb_long*/
+    float_float,        /*nb_float*/
+    0,                  /* nb_oct */
+    0,                  /* nb_hex */
+    0,                  /* nb_inplace_add */
+    0,                  /* nb_inplace_subtract */
+    0,                  /* nb_inplace_multiply */
+    0,                  /* nb_inplace_divide */
+    0,                  /* nb_inplace_remainder */
+    0,                  /* nb_inplace_power */
+    0,                  /* nb_inplace_lshift */
+    0,                  /* nb_inplace_rshift */
+    0,                  /* nb_inplace_and */
+    0,                  /* nb_inplace_xor */
+    0,                  /* nb_inplace_or */
+    float_floor_div, /* nb_floor_divide */
+    float_div,          /* nb_true_divide */
+    0,                  /* nb_inplace_floor_divide */
+    0,                  /* nb_inplace_true_divide */
+};
+
+PyTypeObject PyFloat_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "float",
+    sizeof(PyFloatObject),
+    0,
+    (destructor)float_dealloc,                  /* tp_dealloc */
+    (printfunc)float_print,                     /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)float_repr,                       /* tp_repr */
+    &float_as_number,                           /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)float_hash,                       /* tp_hash */
+    0,                                          /* tp_call */
+    (reprfunc)float_str,                        /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    float_doc,                                  /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    float_richcompare,                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    float_methods,                              /* tp_methods */
+    0,                                          /* tp_members */
+    float_getset,                               /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    float_new,                                  /* tp_new */
+};
+
+void
+_PyFloat_Init(void)
+{
+    /* We attempt to determine if this machine is using IEEE
+       floating point formats by peering at the bits of some
+       carefully chosen values.  If it looks like we are on an
+       IEEE platform, the float packing/unpacking routines can
+       just copy bits, if not they resort to arithmetic & shifts
+       and masks.  The shifts & masks approach works on all finite
+       values, but what happens to infinities, NaNs and signed
+       zeroes on packing is an accident, and attempting to unpack
+       a NaN or an infinity will raise an exception.
+
+       Note that if we're on some whacked-out platform which uses
+       IEEE formats but isn't strictly little-endian or big-
+       endian, we will fall back to the portable shifts & masks
+       method. */
+
+#if SIZEOF_DOUBLE == 8
+    {
+        double x = 9006104071832581.0;
+        if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
+            detected_double_format = ieee_big_endian_format;
+        else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
+            detected_double_format = ieee_little_endian_format;
+        else
+            detected_double_format = unknown_format;
+    }
+#else
+    detected_double_format = unknown_format;
+#endif
+
+#if SIZEOF_FLOAT == 4
+    {
+        float y = 16711938.0;
+        if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
+            detected_float_format = ieee_big_endian_format;
+        else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
+            detected_float_format = ieee_little_endian_format;
+        else
+            detected_float_format = unknown_format;
+    }
+#else
+    detected_float_format = unknown_format;
+#endif
+
+    double_format = detected_double_format;
+    float_format = detected_float_format;
+
+    /* Init float info */
+    if (FloatInfoType.tp_name == 0)
+        PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
+}
+
+int
+PyFloat_ClearFreeList(void)
+{
+    PyFloatObject *p;
+    PyFloatBlock *list, *next;
+    int i;
+    int u;                      /* remaining unfreed ints per block */
+    int freelist_size = 0;
+
+    list = block_list;
+    block_list = NULL;
+    free_list = NULL;
+    while (list != NULL) {
+        u = 0;
+        for (i = 0, p = &list->objects[0];
+             i < N_FLOATOBJECTS;
+             i++, p++) {
+            if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
+                u++;
+        }
+        next = list->next;
+        if (u) {
+            list->next = block_list;
+            block_list = list;
+            for (i = 0, p = &list->objects[0];
+                 i < N_FLOATOBJECTS;
+                 i++, p++) {
+                if (!PyFloat_CheckExact(p) ||
+                    Py_REFCNT(p) == 0) {
+                    Py_TYPE(p) = (struct _typeobject *)
+                        free_list;
+                    free_list = p;
+                }
+            }
+        }
+        else {
+            PyMem_FREE(list);
+        }
+        freelist_size += u;
+        list = next;
+    }
+    return freelist_size;
+}
+
+void
+PyFloat_Fini(void)
+{
+    PyFloatObject *p;
+    PyFloatBlock *list;
+    int i;
+    int u;                      /* total unfreed floats per block */
+
+    u = PyFloat_ClearFreeList();
+
+    if (!Py_VerboseFlag)
+        return;
+    fprintf(stderr, "# cleanup floats");
+    if (!u) {
+        fprintf(stderr, "\n");
+    }
+    else {
+        fprintf(stderr,
+            ": %d unfreed float%s\n",
+            u, u == 1 ? "" : "s");
+    }
+    if (Py_VerboseFlag > 1) {
+        list = block_list;
+        while (list != NULL) {
+            for (i = 0, p = &list->objects[0];
+                 i < N_FLOATOBJECTS;
+                 i++, p++) {
+                if (PyFloat_CheckExact(p) &&
+                    Py_REFCNT(p) != 0) {
+                    char *buf = PyOS_double_to_string(
+                        PyFloat_AS_DOUBLE(p), 'r',
+                        0, 0, NULL);
+                    if (buf) {
+                        /* XXX(twouters) cast
+                           refcount to long
+                           until %zd is
+                           universally
+                           available
+                        */
+                        fprintf(stderr,
+                 "#   <float at %p, refcnt=%ld, val=%s>\n",
+                                    p, (long)Py_REFCNT(p), buf);
+                                    PyMem_Free(buf);
+                            }
+                }
+            }
+            list = list->next;
+        }
+    }
+}
+
+/*----------------------------------------------------------------------------
+ * _PyFloat_{Pack,Unpack}{4,8}.  See floatobject.h.
+ */
+int
+_PyFloat_Pack4(double x, unsigned char *p, int le)
+{
+    if (float_format == unknown_format) {
+        unsigned char sign;
+        int e;
+        double f;
+        unsigned int fbits;
+        int incr = 1;
+
+        if (le) {
+            p += 3;
+            incr = -1;
+        }
+
+        if (x < 0) {
+            sign = 1;
+            x = -x;
+        }
+        else
+            sign = 0;
+
+        f = frexp(x, &e);
+
+        /* Normalize f to be in the range [1.0, 2.0) */
+        if (0.5 <= f && f < 1.0) {
+            f *= 2.0;
+            e--;
+        }
+        else if (f == 0.0)
+            e = 0;
+        else {
+            PyErr_SetString(PyExc_SystemError,
+                            "frexp() result out of range");
+            return -1;
+        }
+
+        if (e >= 128)
+            goto Overflow;
+        else if (e < -126) {
+            /* Gradual underflow */
+            f = ldexp(f, 126 + e);
+            e = 0;
+        }
+        else if (!(e == 0 && f == 0.0)) {
+            e += 127;
+            f -= 1.0; /* Get rid of leading 1 */
+        }
+
+        f *= 8388608.0; /* 2**23 */
+        fbits = (unsigned int)(f + 0.5); /* Round */
+        assert(fbits <= 8388608);
+        if (fbits >> 23) {
+            /* The carry propagated out of a string of 23 1 bits. */
+            fbits = 0;
+            ++e;
+            if (e >= 255)
+                goto Overflow;
+        }
+
+        /* First byte */
+        *p = (sign << 7) | (e >> 1);
+        p += incr;
+
+        /* Second byte */
+        *p = (char) (((e & 1) << 7) | (fbits >> 16));
+        p += incr;
+
+        /* Third byte */
+        *p = (fbits >> 8) & 0xFF;
+        p += incr;
+
+        /* Fourth byte */
+        *p = fbits & 0xFF;
+
+        /* Done */
+        return 0;
+
+    }
+    else {
+        float y = (float)x;
+        const char *s = (char*)&y;
+        int i, incr = 1;
+
+        if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))
+            goto Overflow;
+
+        if ((float_format == ieee_little_endian_format && !le)
+            || (float_format == ieee_big_endian_format && le)) {
+            p += 3;
+            incr = -1;
+        }
+
+        for (i = 0; i < 4; i++) {
+            *p = *s++;
+            p += incr;
+        }
+        return 0;
+    }
+  Overflow:
+    PyErr_SetString(PyExc_OverflowError,
+                    "float too large to pack with f format");
+    return -1;
+}
+
+int
+_PyFloat_Pack8(double x, unsigned char *p, int le)
+{
+    if (double_format == unknown_format) {
+        unsigned char sign;
+        int e;
+        double f;
+        unsigned int fhi, flo;
+        int incr = 1;
+
+        if (le) {
+            p += 7;
+            incr = -1;
+        }
+
+        if (x < 0) {
+            sign = 1;
+            x = -x;
+        }
+        else
+            sign = 0;
+
+        f = frexp(x, &e);
+
+        /* Normalize f to be in the range [1.0, 2.0) */
+        if (0.5 <= f && f < 1.0) {
+            f *= 2.0;
+            e--;
+        }
+        else if (f == 0.0)
+            e = 0;
+        else {
+            PyErr_SetString(PyExc_SystemError,
+                            "frexp() result out of range");
+            return -1;
+        }
+
+        if (e >= 1024)
+            goto Overflow;
+        else if (e < -1022) {
+            /* Gradual underflow */
+            f = ldexp(f, 1022 + e);
+            e = 0;
+        }
+        else if (!(e == 0 && f == 0.0)) {
+            e += 1023;
+            f -= 1.0; /* Get rid of leading 1 */
+        }
+
+        /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
+        f *= 268435456.0; /* 2**28 */
+        fhi = (unsigned int)f; /* Truncate */
+        assert(fhi < 268435456);
+
+        f -= (double)fhi;
+        f *= 16777216.0; /* 2**24 */
+        flo = (unsigned int)(f + 0.5); /* Round */
+        assert(flo <= 16777216);
+        if (flo >> 24) {
+            /* The carry propagated out of a string of 24 1 bits. */
+            flo = 0;
+            ++fhi;
+            if (fhi >> 28) {
+                /* And it also progagated out of the next 28 bits. */
+                fhi = 0;
+                ++e;
+                if (e >= 2047)
+                    goto Overflow;
+            }
+        }
+
+        /* First byte */
+        *p = (sign << 7) | (e >> 4);
+        p += incr;
+
+        /* Second byte */
+        *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
+        p += incr;
+
+        /* Third byte */
+        *p = (fhi >> 16) & 0xFF;
+        p += incr;
+
+        /* Fourth byte */
+        *p = (fhi >> 8) & 0xFF;
+        p += incr;
+
+        /* Fifth byte */
+        *p = fhi & 0xFF;
+        p += incr;
+
+        /* Sixth byte */
+        *p = (flo >> 16) & 0xFF;
+        p += incr;
+
+        /* Seventh byte */
+        *p = (flo >> 8) & 0xFF;
+        p += incr;
+
+        /* Eighth byte */
+        *p = flo & 0xFF;
+        /* p += incr; Unneeded (for now) */
+
+        /* Done */
+        return 0;
+
+      Overflow:
+        PyErr_SetString(PyExc_OverflowError,
+                        "float too large to pack with d format");
+        return -1;
+    }
+    else {
+        const char *s = (char*)&x;
+        int i, incr = 1;
+
+        if ((double_format == ieee_little_endian_format && !le)
+            || (double_format == ieee_big_endian_format && le)) {
+            p += 7;
+            incr = -1;
+        }
+
+        for (i = 0; i < 8; i++) {
+            *p = *s++;
+            p += incr;
+        }
+        return 0;
+    }
+}
+
+double
+_PyFloat_Unpack4(const unsigned char *p, int le)
+{
+    if (float_format == unknown_format) {
+        unsigned char sign;
+        int e;
+        unsigned int f;
+        double x;
+        int incr = 1;
+
+        if (le) {
+            p += 3;
+            incr = -1;
+        }
+
+        /* First byte */
+        sign = (*p >> 7) & 1;
+        e = (*p & 0x7F) << 1;
+        p += incr;
+
+        /* Second byte */
+        e |= (*p >> 7) & 1;
+        f = (*p & 0x7F) << 16;
+        p += incr;
+
+        if (e == 255) {
+            PyErr_SetString(
+                PyExc_ValueError,
+                "can't unpack IEEE 754 special value "
+                "on non-IEEE platform");
+            return -1;
+        }
+
+        /* Third byte */
+        f |= *p << 8;
+        p += incr;
+
+        /* Fourth byte */
+        f |= *p;
+
+        x = (double)f / 8388608.0;
+
+        /* XXX This sadly ignores Inf/NaN issues */
+        if (e == 0)
+            e = -126;
+        else {
+            x += 1.0;
+            e -= 127;
+        }
+        x = ldexp(x, e);
+
+        if (sign)
+            x = -x;
+
+        return x;
+    }
+    else {
+        float x;
+
+        if ((float_format == ieee_little_endian_format && !le)
+            || (float_format == ieee_big_endian_format && le)) {
+            char buf[4];
+            char *d = &buf[3];
+            int i;
+
+            for (i = 0; i < 4; i++) {
+                *d-- = *p++;
+            }
+            memcpy(&x, buf, 4);
+        }
+        else {
+            memcpy(&x, p, 4);
+        }
+
+        return x;
+    }
+}
+
+double
+_PyFloat_Unpack8(const unsigned char *p, int le)
+{
+    if (double_format == unknown_format) {
+        unsigned char sign;
+        int e;
+        unsigned int fhi, flo;
+        double x;
+        int incr = 1;
+
+        if (le) {
+            p += 7;
+            incr = -1;
+        }
+
+        /* First byte */
+        sign = (*p >> 7) & 1;
+        e = (*p & 0x7F) << 4;
+
+        p += incr;
+
+        /* Second byte */
+        e |= (*p >> 4) & 0xF;
+        fhi = (*p & 0xF) << 24;
+        p += incr;
+
+        if (e == 2047) {
+            PyErr_SetString(
+                PyExc_ValueError,
+                "can't unpack IEEE 754 special value "
+                "on non-IEEE platform");
+            return -1.0;
+        }
+
+        /* Third byte */
+        fhi |= *p << 16;
+        p += incr;
+
+        /* Fourth byte */
+        fhi |= *p  << 8;
+        p += incr;
+
+        /* Fifth byte */
+        fhi |= *p;
+        p += incr;
+
+        /* Sixth byte */
+        flo = *p << 16;
+        p += incr;
+
+        /* Seventh byte */
+        flo |= *p << 8;
+        p += incr;
+
+        /* Eighth byte */
+        flo |= *p;
+
+        x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
+        x /= 268435456.0; /* 2**28 */
+
+        if (e == 0)
+            e = -1022;
+        else {
+            x += 1.0;
+            e -= 1023;
+        }
+        x = ldexp(x, e);
+
+        if (sign)
+            x = -x;
+
+        return x;
+    }
+    else {
+        double x;
+
+        if ((double_format == ieee_little_endian_format && !le)
+            || (double_format == ieee_big_endian_format && le)) {
+            char buf[8];
+            char *d = &buf[7];
+            int i;
+
+            for (i = 0; i < 8; i++) {
+                *d-- = *p++;
+            }
+            memcpy(&x, buf, 8);
+        }
+        else {
+            memcpy(&x, p, 8);
+        }
+
+        return x;
+    }
+}
diff --git a/Python-2.7.5/Objects/frameobject.c b/Python-2.7.5/Objects/frameobject.c
new file mode 100644
index 0000000..f9e4a0e
--- /dev/null
+++ b/Python-2.7.5/Objects/frameobject.c
@@ -0,0 +1,984 @@
+/* Frame object implementation */
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#undef MIN
+#undef MAX
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define OFF(x) offsetof(PyFrameObject, x)
+
+static PyMemberDef frame_memberlist[] = {
+    {"f_back",          T_OBJECT,       OFF(f_back),    RO},
+    {"f_code",          T_OBJECT,       OFF(f_code),    RO},
+    {"f_builtins",      T_OBJECT,       OFF(f_builtins),RO},
+    {"f_globals",       T_OBJECT,       OFF(f_globals), RO},
+    {"f_lasti",         T_INT,          OFF(f_lasti),   RO},
+    {NULL}      /* Sentinel */
+};
+
+#define WARN_GET_SET(NAME) \
+static PyObject * frame_get_ ## NAME(PyFrameObject *f) { \
+    if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
+        return NULL; \
+    if (f->NAME) { \
+        Py_INCREF(f->NAME); \
+        return f->NAME; \
+    } \
+    Py_RETURN_NONE;     \
+} \
+static int frame_set_ ## NAME(PyFrameObject *f, PyObject *new) { \
+    if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
+        return -1; \
+    if (f->NAME) { \
+        Py_CLEAR(f->NAME); \
+    } \
+    if (new == Py_None) \
+        new = NULL; \
+    Py_XINCREF(new); \
+    f->NAME = new; \
+    return 0; \
+}
+
+
+WARN_GET_SET(f_exc_traceback)
+WARN_GET_SET(f_exc_type)
+WARN_GET_SET(f_exc_value)
+
+
+static PyObject *
+frame_getlocals(PyFrameObject *f, void *closure)
+{
+    PyFrame_FastToLocals(f);
+    Py_INCREF(f->f_locals);
+    return f->f_locals;
+}
+
+int
+PyFrame_GetLineNumber(PyFrameObject *f)
+{
+    if (f->f_trace)
+        return f->f_lineno;
+    else
+        return PyCode_Addr2Line(f->f_code, f->f_lasti);
+}
+
+static PyObject *
+frame_getlineno(PyFrameObject *f, void *closure)
+{
+    return PyInt_FromLong(PyFrame_GetLineNumber(f));
+}
+
+/* Setter for f_lineno - you can set f_lineno from within a trace function in
+ * order to jump to a given line of code, subject to some restrictions.  Most
+ * lines are OK to jump to because they don't make any assumptions about the
+ * state of the stack (obvious because you could remove the line and the code
+ * would still work without any stack errors), but there are some constructs
+ * that limit jumping:
+ *
+ *  o Lines with an 'except' statement on them can't be jumped to, because
+ *    they expect an exception to be on the top of the stack.
+ *  o Lines that live in a 'finally' block can't be jumped from or to, since
+ *    the END_FINALLY expects to clean up the stack after the 'try' block.
+ *  o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
+ *    needs to be set up before their code runs, and for 'for' loops the
+ *    iterator needs to be on the stack.
+ */
+static int
+frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
+{
+    int new_lineno = 0;                 /* The new value of f_lineno */
+    int new_lasti = 0;                  /* The new value of f_lasti */
+    int new_iblock = 0;                 /* The new value of f_iblock */
+    unsigned char *code = NULL;         /* The bytecode for the frame... */
+    Py_ssize_t code_len = 0;            /* ...and its length */
+    unsigned char *lnotab = NULL;       /* Iterating over co_lnotab */
+    Py_ssize_t lnotab_len = 0;          /* (ditto) */
+    int offset = 0;                     /* (ditto) */
+    int line = 0;                       /* (ditto) */
+    int addr = 0;                       /* (ditto) */
+    int min_addr = 0;                   /* Scanning the SETUPs and POPs */
+    int max_addr = 0;                   /* (ditto) */
+    int delta_iblock = 0;               /* (ditto) */
+    int min_delta_iblock = 0;           /* (ditto) */
+    int min_iblock = 0;                 /* (ditto) */
+    int f_lasti_setup_addr = 0;         /* Policing no-jump-into-finally */
+    int new_lasti_setup_addr = 0;       /* (ditto) */
+    int blockstack[CO_MAXBLOCKS];       /* Walking the 'finally' blocks */
+    int in_finally[CO_MAXBLOCKS];       /* (ditto) */
+    int blockstack_top = 0;             /* (ditto) */
+    unsigned char setup_op = 0;         /* (ditto) */
+
+    /* f_lineno must be an integer. */
+    if (!PyInt_Check(p_new_lineno)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "lineno must be an integer");
+        return -1;
+    }
+
+    /* You can only do this from within a trace function, not via
+     * _getframe or similar hackery. */
+    if (!f->f_trace)
+    {
+        PyErr_Format(PyExc_ValueError,
+                     "f_lineno can only be set by a"
+                     " line trace function");
+        return -1;
+    }
+
+    /* Fail if the line comes before the start of the code block. */
+    new_lineno = (int) PyInt_AsLong(p_new_lineno);
+    if (new_lineno < f->f_code->co_firstlineno) {
+        PyErr_Format(PyExc_ValueError,
+                     "line %d comes before the current code block",
+                     new_lineno);
+        return -1;
+    }
+    else if (new_lineno == f->f_code->co_firstlineno) {
+        new_lasti = 0;
+        new_lineno = f->f_code->co_firstlineno;
+    }
+    else {
+        /* Find the bytecode offset for the start of the given
+         * line, or the first code-owning line after it. */
+        char *tmp;
+        PyString_AsStringAndSize(f->f_code->co_lnotab,
+                                 &tmp, &lnotab_len);
+        lnotab = (unsigned char *) tmp;
+        addr = 0;
+        line = f->f_code->co_firstlineno;
+        new_lasti = -1;
+        for (offset = 0; offset < lnotab_len; offset += 2) {
+            addr += lnotab[offset];
+            line += lnotab[offset+1];
+            if (line >= new_lineno) {
+                new_lasti = addr;
+                new_lineno = line;
+                break;
+            }
+        }
+    }
+
+    /* If we didn't reach the requested line, return an error. */
+    if (new_lasti == -1) {
+        PyErr_Format(PyExc_ValueError,
+                     "line %d comes after the current code block",
+                     new_lineno);
+        return -1;
+    }
+
+    /* We're now ready to look at the bytecode. */
+    PyString_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len);
+    min_addr = MIN(new_lasti, f->f_lasti);
+    max_addr = MAX(new_lasti, f->f_lasti);
+
+    /* You can't jump onto a line with an 'except' statement on it -
+     * they expect to have an exception on the top of the stack, which
+     * won't be true if you jump to them.  They always start with code
+     * that either pops the exception using POP_TOP (plain 'except:'
+     * lines do this) or duplicates the exception on the stack using
+     * DUP_TOP (if there's an exception type specified).  See compile.c,
+     * 'com_try_except' for the full details.  There aren't any other
+     * cases (AFAIK) where a line's code can start with DUP_TOP or
+     * POP_TOP, but if any ever appear, they'll be subject to the same
+     * restriction (but with a different error message). */
+    if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
+        PyErr_SetString(PyExc_ValueError,
+            "can't jump to 'except' line as there's no exception");
+        return -1;
+    }
+
+    /* You can't jump into or out of a 'finally' block because the 'try'
+     * block leaves something on the stack for the END_FINALLY to clean
+     * up.      So we walk the bytecode, maintaining a simulated blockstack.
+     * When we reach the old or new address and it's in a 'finally' block
+     * we note the address of the corresponding SETUP_FINALLY.  The jump
+     * is only legal if neither address is in a 'finally' block or
+     * they're both in the same one.  'blockstack' is a stack of the
+     * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
+     * whether we're in a 'finally' block at each blockstack level. */
+    f_lasti_setup_addr = -1;
+    new_lasti_setup_addr = -1;
+    memset(blockstack, '\0', sizeof(blockstack));
+    memset(in_finally, '\0', sizeof(in_finally));
+    blockstack_top = 0;
+    for (addr = 0; addr < code_len; addr++) {
+        unsigned char op = code[addr];
+        switch (op) {
+        case SETUP_LOOP:
+        case SETUP_EXCEPT:
+        case SETUP_FINALLY:
+        case SETUP_WITH:
+            blockstack[blockstack_top++] = addr;
+            in_finally[blockstack_top-1] = 0;
+            break;
+
+        case POP_BLOCK:
+            assert(blockstack_top > 0);
+            setup_op = code[blockstack[blockstack_top-1]];
+            if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
+                in_finally[blockstack_top-1] = 1;
+            }
+            else {
+                blockstack_top--;
+            }
+            break;
+
+        case END_FINALLY:
+            /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
+             * in the bytecode but don't correspond to an actual
+             * 'finally' block.  (If blockstack_top is 0, we must
+             * be seeing such an END_FINALLY.) */
+            if (blockstack_top > 0) {
+                setup_op = code[blockstack[blockstack_top-1]];
+                if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
+                    blockstack_top--;
+                }
+            }
+            break;
+        }
+
+        /* For the addresses we're interested in, see whether they're
+         * within a 'finally' block and if so, remember the address
+         * of the SETUP_FINALLY. */
+        if (addr == new_lasti || addr == f->f_lasti) {
+            int i = 0;
+            int setup_addr = -1;
+            for (i = blockstack_top-1; i >= 0; i--) {
+                if (in_finally[i]) {
+                    setup_addr = blockstack[i];
+                    break;
+                }
+            }
+
+            if (setup_addr != -1) {
+                if (addr == new_lasti) {
+                    new_lasti_setup_addr = setup_addr;
+                }
+
+                if (addr == f->f_lasti) {
+                    f_lasti_setup_addr = setup_addr;
+                }
+            }
+        }
+
+        if (op >= HAVE_ARGUMENT) {
+            addr += 2;
+        }
+    }
+
+    /* Verify that the blockstack tracking code didn't get lost. */
+    assert(blockstack_top == 0);
+
+    /* After all that, are we jumping into / out of a 'finally' block? */
+    if (new_lasti_setup_addr != f_lasti_setup_addr) {
+        PyErr_SetString(PyExc_ValueError,
+                    "can't jump into or out of a 'finally' block");
+        return -1;
+    }
+
+
+    /* Police block-jumping (you can't jump into the middle of a block)
+     * and ensure that the blockstack finishes up in a sensible state (by
+     * popping any blocks we're jumping out of).  We look at all the
+     * blockstack operations between the current position and the new
+     * one, and keep track of how many blocks we drop out of on the way.
+     * By also keeping track of the lowest blockstack position we see, we
+     * can tell whether the jump goes into any blocks without coming out
+     * again - in that case we raise an exception below. */
+    delta_iblock = 0;
+    for (addr = min_addr; addr < max_addr; addr++) {
+        unsigned char op = code[addr];
+        switch (op) {
+        case SETUP_LOOP:
+        case SETUP_EXCEPT:
+        case SETUP_FINALLY:
+        case SETUP_WITH:
+            delta_iblock++;
+            break;
+
+        case POP_BLOCK:
+            delta_iblock--;
+            break;
+        }
+
+        min_delta_iblock = MIN(min_delta_iblock, delta_iblock);
+
+        if (op >= HAVE_ARGUMENT) {
+            addr += 2;
+        }
+    }
+
+    /* Derive the absolute iblock values from the deltas. */
+    min_iblock = f->f_iblock + min_delta_iblock;
+    if (new_lasti > f->f_lasti) {
+        /* Forwards jump. */
+        new_iblock = f->f_iblock + delta_iblock;
+    }
+    else {
+        /* Backwards jump. */
+        new_iblock = f->f_iblock - delta_iblock;
+    }
+
+    /* Are we jumping into a block? */
+    if (new_iblock > min_iblock) {
+        PyErr_SetString(PyExc_ValueError,
+                        "can't jump into the middle of a block");
+        return -1;
+    }
+
+    /* Pop any blocks that we're jumping out of. */
+    while (f->f_iblock > new_iblock) {
+        PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
+        while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
+            PyObject *v = (*--f->f_stacktop);
+            Py_DECREF(v);
+        }
+    }
+
+    /* Finally set the new f_lineno and f_lasti and return OK. */
+    f->f_lineno = new_lineno;
+    f->f_lasti = new_lasti;
+    return 0;
+}
+
+static PyObject *
+frame_gettrace(PyFrameObject *f, void *closure)
+{
+    PyObject* trace = f->f_trace;
+
+    if (trace == NULL)
+        trace = Py_None;
+
+    Py_INCREF(trace);
+
+    return trace;
+}
+
+static int
+frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
+{
+    PyObject* old_value;
+
+    /* We rely on f_lineno being accurate when f_trace is set. */
+    f->f_lineno = PyFrame_GetLineNumber(f);
+
+    old_value = f->f_trace;
+    Py_XINCREF(v);
+    f->f_trace = v;
+    Py_XDECREF(old_value);
+
+    return 0;
+}
+
+static PyObject *
+frame_getrestricted(PyFrameObject *f, void *closure)
+{
+    return PyBool_FromLong(PyFrame_IsRestricted(f));
+}
+
+static PyGetSetDef frame_getsetlist[] = {
+    {"f_locals",        (getter)frame_getlocals, NULL, NULL},
+    {"f_lineno",        (getter)frame_getlineno,
+                    (setter)frame_setlineno, NULL},
+    {"f_trace",         (getter)frame_gettrace, (setter)frame_settrace, NULL},
+    {"f_restricted",(getter)frame_getrestricted,NULL, NULL},
+    {"f_exc_traceback", (getter)frame_get_f_exc_traceback,
+                    (setter)frame_set_f_exc_traceback, NULL},
+    {"f_exc_type",  (getter)frame_get_f_exc_type,
+                    (setter)frame_set_f_exc_type, NULL},
+    {"f_exc_value", (getter)frame_get_f_exc_value,
+                    (setter)frame_set_f_exc_value, NULL},
+    {0}
+};
+
+/* Stack frames are allocated and deallocated at a considerable rate.
+   In an attempt to improve the speed of function calls, we:
+
+   1. Hold a single "zombie" frame on each code object. This retains
+   the allocated and initialised frame object from an invocation of
+   the code object. The zombie is reanimated the next time we need a
+   frame object for that code object. Doing this saves the malloc/
+   realloc required when using a free_list frame that isn't the
+   correct size. It also saves some field initialisation.
+
+   In zombie mode, no field of PyFrameObject holds a reference, but
+   the following fields are still valid:
+
+     * ob_type, ob_size, f_code, f_valuestack;
+
+     * f_locals, f_trace,
+       f_exc_type, f_exc_value, f_exc_traceback are NULL;
+
+     * f_localsplus does not require re-allocation and
+       the local variables in f_localsplus are NULL.
+
+   2. We also maintain a separate free list of stack frames (just like
+   integers are allocated in a special way -- see intobject.c).  When
+   a stack frame is on the free list, only the following members have
+   a meaning:
+    ob_type             == &Frametype
+    f_back              next item on free list, or NULL
+    f_stacksize         size of value stack
+    ob_size             size of localsplus
+   Note that the value and block stacks are preserved -- this can save
+   another malloc() call or two (and two free() calls as well!).
+   Also note that, unlike for integers, each frame object is a
+   malloc'ed object in its own right -- it is only the actual calls to
+   malloc() that we are trying to save here, not the administration.
+   After all, while a typical program may make millions of calls, a
+   call depth of more than 20 or 30 is probably already exceptional
+   unless the program contains run-away recursion.  I hope.
+
+   Later, PyFrame_MAXFREELIST was added to bound the # of frames saved on
+   free_list.  Else programs creating lots of cyclic trash involving
+   frames could provoke free_list into growing without bound.
+*/
+
+static PyFrameObject *free_list = NULL;
+static int numfree = 0;         /* number of frames currently in free_list */
+/* max value for numfree */
+#define PyFrame_MAXFREELIST 200
+
+static void
+frame_dealloc(PyFrameObject *f)
+{
+    PyObject **p, **valuestack;
+    PyCodeObject *co;
+
+    PyObject_GC_UnTrack(f);
+    Py_TRASHCAN_SAFE_BEGIN(f)
+    /* Kill all local variables */
+    valuestack = f->f_valuestack;
+    for (p = f->f_localsplus; p < valuestack; p++)
+        Py_CLEAR(*p);
+
+    /* Free stack */
+    if (f->f_stacktop != NULL) {
+        for (p = valuestack; p < f->f_stacktop; p++)
+            Py_XDECREF(*p);
+    }
+
+    Py_XDECREF(f->f_back);
+    Py_DECREF(f->f_builtins);
+    Py_DECREF(f->f_globals);
+    Py_CLEAR(f->f_locals);
+    Py_CLEAR(f->f_trace);
+    Py_CLEAR(f->f_exc_type);
+    Py_CLEAR(f->f_exc_value);
+    Py_CLEAR(f->f_exc_traceback);
+
+    co = f->f_code;
+    if (co->co_zombieframe == NULL)
+        co->co_zombieframe = f;
+    else if (numfree < PyFrame_MAXFREELIST) {
+        ++numfree;
+        f->f_back = free_list;
+        free_list = f;
+    }
+    else
+        PyObject_GC_Del(f);
+
+    Py_DECREF(co);
+    Py_TRASHCAN_SAFE_END(f)
+}
+
+static int
+frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
+{
+    PyObject **fastlocals, **p;
+    int i, slots;
+
+    Py_VISIT(f->f_back);
+    Py_VISIT(f->f_code);
+    Py_VISIT(f->f_builtins);
+    Py_VISIT(f->f_globals);
+    Py_VISIT(f->f_locals);
+    Py_VISIT(f->f_trace);
+    Py_VISIT(f->f_exc_type);
+    Py_VISIT(f->f_exc_value);
+    Py_VISIT(f->f_exc_traceback);
+
+    /* locals */
+    slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
+    fastlocals = f->f_localsplus;
+    for (i = slots; --i >= 0; ++fastlocals)
+        Py_VISIT(*fastlocals);
+
+    /* stack */
+    if (f->f_stacktop != NULL) {
+        for (p = f->f_valuestack; p < f->f_stacktop; p++)
+            Py_VISIT(*p);
+    }
+    return 0;
+}
+
+static void
+frame_clear(PyFrameObject *f)
+{
+    PyObject **fastlocals, **p, **oldtop;
+    int i, slots;
+
+    /* Before anything else, make sure that this frame is clearly marked
+     * as being defunct!  Else, e.g., a generator reachable from this
+     * frame may also point to this frame, believe itself to still be
+     * active, and try cleaning up this frame again.
+     */
+    oldtop = f->f_stacktop;
+    f->f_stacktop = NULL;
+
+    Py_CLEAR(f->f_exc_type);
+    Py_CLEAR(f->f_exc_value);
+    Py_CLEAR(f->f_exc_traceback);
+    Py_CLEAR(f->f_trace);
+
+    /* locals */
+    slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
+    fastlocals = f->f_localsplus;
+    for (i = slots; --i >= 0; ++fastlocals)
+        Py_CLEAR(*fastlocals);
+
+    /* stack */
+    if (oldtop != NULL) {
+        for (p = f->f_valuestack; p < oldtop; p++)
+            Py_CLEAR(*p);
+    }
+}
+
+static PyObject *
+frame_sizeof(PyFrameObject *f)
+{
+    Py_ssize_t res, extras, ncells, nfrees;
+
+    ncells = PyTuple_GET_SIZE(f->f_code->co_cellvars);
+    nfrees = PyTuple_GET_SIZE(f->f_code->co_freevars);
+    extras = f->f_code->co_stacksize + f->f_code->co_nlocals +
+             ncells + nfrees;
+    /* subtract one as it is already included in PyFrameObject */
+    res = sizeof(PyFrameObject) + (extras-1) * sizeof(PyObject *);
+
+    return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+"F.__sizeof__() -> size of F in memory, in bytes");
+
+static PyMethodDef frame_methods[] = {
+    {"__sizeof__",      (PyCFunction)frame_sizeof,      METH_NOARGS,
+     sizeof__doc__},
+    {NULL,              NULL}   /* sentinel */
+};
+
+PyTypeObject PyFrame_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "frame",
+    sizeof(PyFrameObject),
+    sizeof(PyObject *),
+    (destructor)frame_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    PyObject_GenericSetAttr,                    /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)frame_traverse,               /* tp_traverse */
+    (inquiry)frame_clear,                       /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    frame_methods,                              /* tp_methods */
+    frame_memberlist,                           /* tp_members */
+    frame_getsetlist,                           /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+};
+
+static PyObject *builtin_object;
+
+int _PyFrame_Init()
+{
+    builtin_object = PyString_InternFromString("__builtins__");
+    if (builtin_object == NULL)
+        return 0;
+    return 1;
+}
+
+PyFrameObject *
+PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
+            PyObject *locals)
+{
+    PyFrameObject *back = tstate->frame;
+    PyFrameObject *f;
+    PyObject *builtins;
+    Py_ssize_t i;
+
+#ifdef Py_DEBUG
+    if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
+        (locals != NULL && !PyMapping_Check(locals))) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+#endif
+    if (back == NULL || back->f_globals != globals) {
+        builtins = PyDict_GetItem(globals, builtin_object);
+        if (builtins) {
+            if (PyModule_Check(builtins)) {
+                builtins = PyModule_GetDict(builtins);
+                assert(!builtins || PyDict_Check(builtins));
+            }
+            else if (!PyDict_Check(builtins))
+                builtins = NULL;
+        }
+        if (builtins == NULL) {
+            /* No builtins!              Make up a minimal one
+               Give them 'None', at least. */
+            builtins = PyDict_New();
+            if (builtins == NULL ||
+                PyDict_SetItemString(
+                    builtins, "None", Py_None) < 0)
+                return NULL;
+        }
+        else
+            Py_INCREF(builtins);
+
+    }
+    else {
+        /* If we share the globals, we share the builtins.
+           Save a lookup and a call. */
+        builtins = back->f_builtins;
+        assert(builtins != NULL && PyDict_Check(builtins));
+        Py_INCREF(builtins);
+    }
+    if (code->co_zombieframe != NULL) {
+        f = code->co_zombieframe;
+        code->co_zombieframe = NULL;
+        _Py_NewReference((PyObject *)f);
+        assert(f->f_code == code);
+    }
+    else {
+        Py_ssize_t extras, ncells, nfrees;
+        ncells = PyTuple_GET_SIZE(code->co_cellvars);
+        nfrees = PyTuple_GET_SIZE(code->co_freevars);
+        extras = code->co_stacksize + code->co_nlocals + ncells +
+            nfrees;
+        if (free_list == NULL) {
+            f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type,
+            extras);
+            if (f == NULL) {
+                Py_DECREF(builtins);
+                return NULL;
+            }
+        }
+        else {
+            assert(numfree > 0);
+            --numfree;
+            f = free_list;
+            free_list = free_list->f_back;
+            if (Py_SIZE(f) < extras) {
+                f = PyObject_GC_Resize(PyFrameObject, f, extras);
+                if (f == NULL) {
+                    Py_DECREF(builtins);
+                    return NULL;
+                }
+            }
+            _Py_NewReference((PyObject *)f);
+        }
+
+        f->f_code = code;
+        extras = code->co_nlocals + ncells + nfrees;
+        f->f_valuestack = f->f_localsplus + extras;
+        for (i=0; i<extras; i++)
+            f->f_localsplus[i] = NULL;
+        f->f_locals = NULL;
+        f->f_trace = NULL;
+        f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
+    }
+    f->f_stacktop = f->f_valuestack;
+    f->f_builtins = builtins;
+    Py_XINCREF(back);
+    f->f_back = back;
+    Py_INCREF(code);
+    Py_INCREF(globals);
+    f->f_globals = globals;
+    /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */
+    if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) ==
+        (CO_NEWLOCALS | CO_OPTIMIZED))
+        ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */
+    else if (code->co_flags & CO_NEWLOCALS) {
+        locals = PyDict_New();
+        if (locals == NULL) {
+            Py_DECREF(f);
+            return NULL;
+        }
+        f->f_locals = locals;
+    }
+    else {
+        if (locals == NULL)
+            locals = globals;
+        Py_INCREF(locals);
+        f->f_locals = locals;
+    }
+    f->f_tstate = tstate;
+
+    f->f_lasti = -1;
+    f->f_lineno = code->co_firstlineno;
+    f->f_iblock = 0;
+
+    _PyObject_GC_TRACK(f);
+    return f;
+}
+
+/* Block management */
+
+void
+PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
+{
+    PyTryBlock *b;
+    if (f->f_iblock >= CO_MAXBLOCKS)
+        Py_FatalError("XXX block stack overflow");
+    b = &f->f_blockstack[f->f_iblock++];
+    b->b_type = type;
+    b->b_level = level;
+    b->b_handler = handler;
+}
+
+PyTryBlock *
+PyFrame_BlockPop(PyFrameObject *f)
+{
+    PyTryBlock *b;
+    if (f->f_iblock <= 0)
+        Py_FatalError("XXX block stack underflow");
+    b = &f->f_blockstack[--f->f_iblock];
+    return b;
+}
+
+/* Convert between "fast" version of locals and dictionary version.
+
+   map and values are input arguments.  map is a tuple of strings.
+   values is an array of PyObject*.  At index i, map[i] is the name of
+   the variable with value values[i].  The function copies the first
+   nmap variable from map/values into dict.  If values[i] is NULL,
+   the variable is deleted from dict.
+
+   If deref is true, then the values being copied are cell variables
+   and the value is extracted from the cell variable before being put
+   in dict.
+
+   Exceptions raised while modifying the dict are silently ignored,
+   because there is no good way to report them.
+ */
+
+static void
+map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
+            int deref)
+{
+    Py_ssize_t j;
+    assert(PyTuple_Check(map));
+    assert(PyDict_Check(dict));
+    assert(PyTuple_Size(map) >= nmap);
+    for (j = nmap; --j >= 0; ) {
+        PyObject *key = PyTuple_GET_ITEM(map, j);
+        PyObject *value = values[j];
+        assert(PyString_Check(key));
+        if (deref) {
+            assert(PyCell_Check(value));
+            value = PyCell_GET(value);
+        }
+        if (value == NULL) {
+            if (PyObject_DelItem(dict, key) != 0)
+                PyErr_Clear();
+        }
+        else {
+            if (PyObject_SetItem(dict, key, value) != 0)
+                PyErr_Clear();
+        }
+    }
+}
+
+/* Copy values from the "locals" dict into the fast locals.
+
+   dict is an input argument containing string keys representing
+   variables names and arbitrary PyObject* as values.
+
+   map and values are input arguments.  map is a tuple of strings.
+   values is an array of PyObject*.  At index i, map[i] is the name of
+   the variable with value values[i].  The function copies the first
+   nmap variable from map/values into dict.  If values[i] is NULL,
+   the variable is deleted from dict.
+
+   If deref is true, then the values being copied are cell variables
+   and the value is extracted from the cell variable before being put
+   in dict.  If clear is true, then variables in map but not in dict
+   are set to NULL in map; if clear is false, variables missing in
+   dict are ignored.
+
+   Exceptions raised while modifying the dict are silently ignored,
+   because there is no good way to report them.
+*/
+
+static void
+dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
+            int deref, int clear)
+{
+    Py_ssize_t j;
+    assert(PyTuple_Check(map));
+    assert(PyDict_Check(dict));
+    assert(PyTuple_Size(map) >= nmap);
+    for (j = nmap; --j >= 0; ) {
+        PyObject *key = PyTuple_GET_ITEM(map, j);
+        PyObject *value = PyObject_GetItem(dict, key);
+        assert(PyString_Check(key));
+        /* We only care about NULLs if clear is true. */
+        if (value == NULL) {
+            PyErr_Clear();
+            if (!clear)
+                continue;
+        }
+        if (deref) {
+            assert(PyCell_Check(values[j]));
+            if (PyCell_GET(values[j]) != value) {
+                if (PyCell_Set(values[j], value) < 0)
+                    PyErr_Clear();
+            }
+        } else if (values[j] != value) {
+            Py_XINCREF(value);
+            Py_XDECREF(values[j]);
+            values[j] = value;
+        }
+        Py_XDECREF(value);
+    }
+}
+
+void
+PyFrame_FastToLocals(PyFrameObject *f)
+{
+    /* Merge fast locals into f->f_locals */
+    PyObject *locals, *map;
+    PyObject **fast;
+    PyObject *error_type, *error_value, *error_traceback;
+    PyCodeObject *co;
+    Py_ssize_t j;
+    int ncells, nfreevars;
+    if (f == NULL)
+        return;
+    locals = f->f_locals;
+    if (locals == NULL) {
+        locals = f->f_locals = PyDict_New();
+        if (locals == NULL) {
+            PyErr_Clear(); /* Can't report it :-( */
+            return;
+        }
+    }
+    co = f->f_code;
+    map = co->co_varnames;
+    if (!PyTuple_Check(map))
+        return;
+    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    fast = f->f_localsplus;
+    j = PyTuple_GET_SIZE(map);
+    if (j > co->co_nlocals)
+        j = co->co_nlocals;
+    if (co->co_nlocals)
+        map_to_dict(map, j, locals, fast, 0);
+    ncells = PyTuple_GET_SIZE(co->co_cellvars);
+    nfreevars = PyTuple_GET_SIZE(co->co_freevars);
+    if (ncells || nfreevars) {
+        map_to_dict(co->co_cellvars, ncells,
+                    locals, fast + co->co_nlocals, 1);
+        /* If the namespace is unoptimized, then one of the
+           following cases applies:
+           1. It does not contain free variables, because it
+              uses import * or is a top-level namespace.
+           2. It is a class namespace.
+           We don't want to accidentally copy free variables
+           into the locals dict used by the class.
+        */
+        if (co->co_flags & CO_OPTIMIZED) {
+            map_to_dict(co->co_freevars, nfreevars,
+                        locals, fast + co->co_nlocals + ncells, 1);
+        }
+    }
+    PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+void
+PyFrame_LocalsToFast(PyFrameObject *f, int clear)
+{
+    /* Merge f->f_locals into fast locals */
+    PyObject *locals, *map;
+    PyObject **fast;
+    PyObject *error_type, *error_value, *error_traceback;
+    PyCodeObject *co;
+    Py_ssize_t j;
+    int ncells, nfreevars;
+    if (f == NULL)
+        return;
+    locals = f->f_locals;
+    co = f->f_code;
+    map = co->co_varnames;
+    if (locals == NULL)
+        return;
+    if (!PyTuple_Check(map))
+        return;
+    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    fast = f->f_localsplus;
+    j = PyTuple_GET_SIZE(map);
+    if (j > co->co_nlocals)
+        j = co->co_nlocals;
+    if (co->co_nlocals)
+        dict_to_map(co->co_varnames, j, locals, fast, 0, clear);
+    ncells = PyTuple_GET_SIZE(co->co_cellvars);
+    nfreevars = PyTuple_GET_SIZE(co->co_freevars);
+    if (ncells || nfreevars) {
+        dict_to_map(co->co_cellvars, ncells,
+                    locals, fast + co->co_nlocals, 1, clear);
+        /* Same test as in PyFrame_FastToLocals() above. */
+        if (co->co_flags & CO_OPTIMIZED) {
+            dict_to_map(co->co_freevars, nfreevars,
+                locals, fast + co->co_nlocals + ncells, 1,
+                clear);
+        }
+    }
+    PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+/* Clear out the free list */
+int
+PyFrame_ClearFreeList(void)
+{
+    int freelist_size = numfree;
+
+    while (free_list != NULL) {
+        PyFrameObject *f = free_list;
+        free_list = free_list->f_back;
+        PyObject_GC_Del(f);
+        --numfree;
+    }
+    assert(numfree == 0);
+    return freelist_size;
+}
+
+void
+PyFrame_Fini(void)
+{
+    (void)PyFrame_ClearFreeList();
+    Py_XDECREF(builtin_object);
+    builtin_object = NULL;
+}
diff --git a/Python-2.7.5/Objects/funcobject.c b/Python-2.7.5/Objects/funcobject.c
new file mode 100644
index 0000000..51b6c9d
--- /dev/null
+++ b/Python-2.7.5/Objects/funcobject.c
@@ -0,0 +1,895 @@
+
+/* Function object implementation */
+
+#include "Python.h"
+#include "code.h"
+#include "eval.h"
+#include "structmember.h"
+
+PyObject *
+PyFunction_New(PyObject *code, PyObject *globals)
+{
+    PyFunctionObject *op = PyObject_GC_New(PyFunctionObject,
+                                        &PyFunction_Type);
+    static PyObject *__name__ = 0;
+    if (op != NULL) {
+        PyObject *doc;
+        PyObject *consts;
+        PyObject *module;
+        op->func_weakreflist = NULL;
+        Py_INCREF(code);
+        op->func_code = code;
+        Py_INCREF(globals);
+        op->func_globals = globals;
+        op->func_name = ((PyCodeObject *)code)->co_name;
+        Py_INCREF(op->func_name);
+        op->func_defaults = NULL; /* No default arguments */
+        op->func_closure = NULL;
+        consts = ((PyCodeObject *)code)->co_consts;
+        if (PyTuple_Size(consts) >= 1) {
+            doc = PyTuple_GetItem(consts, 0);
+            if (!PyString_Check(doc) && !PyUnicode_Check(doc))
+                doc = Py_None;
+        }
+        else
+            doc = Py_None;
+        Py_INCREF(doc);
+        op->func_doc = doc;
+        op->func_dict = NULL;
+        op->func_module = NULL;
+
+        /* __module__: If module name is in globals, use it.
+           Otherwise, use None.
+        */
+        if (!__name__) {
+            __name__ = PyString_InternFromString("__name__");
+            if (!__name__) {
+                Py_DECREF(op);
+                return NULL;
+            }
+        }
+        module = PyDict_GetItem(globals, __name__);
+        if (module) {
+            Py_INCREF(module);
+            op->func_module = module;
+        }
+    }
+    else
+        return NULL;
+    _PyObject_GC_TRACK(op);
+    return (PyObject *)op;
+}
+
+PyObject *
+PyFunction_GetCode(PyObject *op)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyFunctionObject *) op) -> func_code;
+}
+
+PyObject *
+PyFunction_GetGlobals(PyObject *op)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyFunctionObject *) op) -> func_globals;
+}
+
+PyObject *
+PyFunction_GetModule(PyObject *op)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyFunctionObject *) op) -> func_module;
+}
+
+PyObject *
+PyFunction_GetDefaults(PyObject *op)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyFunctionObject *) op) -> func_defaults;
+}
+
+int
+PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (defaults == Py_None)
+        defaults = NULL;
+    else if (defaults && PyTuple_Check(defaults)) {
+        Py_INCREF(defaults);
+    }
+    else {
+        PyErr_SetString(PyExc_SystemError, "non-tuple default args");
+        return -1;
+    }
+    Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
+    ((PyFunctionObject *) op) -> func_defaults = defaults;
+    return 0;
+}
+
+PyObject *
+PyFunction_GetClosure(PyObject *op)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyFunctionObject *) op) -> func_closure;
+}
+
+int
+PyFunction_SetClosure(PyObject *op, PyObject *closure)
+{
+    if (!PyFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (closure == Py_None)
+        closure = NULL;
+    else if (PyTuple_Check(closure)) {
+        Py_INCREF(closure);
+    }
+    else {
+        PyErr_Format(PyExc_SystemError,
+                     "expected tuple for closure, got '%.100s'",
+                     closure->ob_type->tp_name);
+        return -1;
+    }
+    Py_XDECREF(((PyFunctionObject *) op) -> func_closure);
+    ((PyFunctionObject *) op) -> func_closure = closure;
+    return 0;
+}
+
+/* Methods */
+
+#define OFF(x) offsetof(PyFunctionObject, x)
+
+static PyMemberDef func_memberlist[] = {
+    {"func_closure",  T_OBJECT,     OFF(func_closure),
+     RESTRICTED|READONLY},
+    {"__closure__",  T_OBJECT,      OFF(func_closure),
+     RESTRICTED|READONLY},
+    {"func_doc",      T_OBJECT,     OFF(func_doc), PY_WRITE_RESTRICTED},
+    {"__doc__",       T_OBJECT,     OFF(func_doc), PY_WRITE_RESTRICTED},
+    {"func_globals",  T_OBJECT,     OFF(func_globals),
+     RESTRICTED|READONLY},
+    {"__globals__",  T_OBJECT,      OFF(func_globals),
+     RESTRICTED|READONLY},
+    {"__module__",    T_OBJECT,     OFF(func_module), PY_WRITE_RESTRICTED},
+    {NULL}  /* Sentinel */
+};
+
+static int
+restricted(void)
+{
+    if (!PyEval_GetRestricted())
+        return 0;
+    PyErr_SetString(PyExc_RuntimeError,
+        "function attributes not accessible in restricted mode");
+    return 1;
+}
+
+static PyObject *
+func_get_dict(PyFunctionObject *op)
+{
+    if (restricted())
+        return NULL;
+    if (op->func_dict == NULL) {
+        op->func_dict = PyDict_New();
+        if (op->func_dict == NULL)
+            return NULL;
+    }
+    Py_INCREF(op->func_dict);
+    return op->func_dict;
+}
+
+static int
+func_set_dict(PyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (restricted())
+        return -1;
+    /* It is illegal to del f.func_dict */
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "function's dictionary may not be deleted");
+        return -1;
+    }
+    /* Can only set func_dict to a dictionary */
+    if (!PyDict_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "setting function's dictionary to a non-dict");
+        return -1;
+    }
+    tmp = op->func_dict;
+    Py_INCREF(value);
+    op->func_dict = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+
+static PyObject *
+func_get_code(PyFunctionObject *op)
+{
+    if (restricted())
+        return NULL;
+    Py_INCREF(op->func_code);
+    return op->func_code;
+}
+
+static int
+func_set_code(PyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+    Py_ssize_t nfree, nclosure;
+
+    if (restricted())
+        return -1;
+    /* Not legal to del f.func_code or to set it to anything
+     * other than a code object. */
+    if (value == NULL || !PyCode_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__code__ must be set to a code object");
+        return -1;
+    }
+    nfree = PyCode_GetNumFree((PyCodeObject *)value);
+    nclosure = (op->func_closure == NULL ? 0 :
+            PyTuple_GET_SIZE(op->func_closure));
+    if (nclosure != nfree) {
+        PyErr_Format(PyExc_ValueError,
+                     "%s() requires a code object with %zd free vars,"
+                     " not %zd",
+                     PyString_AsString(op->func_name),
+                     nclosure, nfree);
+        return -1;
+    }
+    tmp = op->func_code;
+    Py_INCREF(value);
+    op->func_code = value;
+    Py_DECREF(tmp);
+    return 0;
+}
+
+static PyObject *
+func_get_name(PyFunctionObject *op)
+{
+    Py_INCREF(op->func_name);
+    return op->func_name;
+}
+
+static int
+func_set_name(PyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (restricted())
+        return -1;
+    /* Not legal to del f.func_name or to set it to anything
+     * other than a string object. */
+    if (value == NULL || !PyString_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__name__ must be set to a string object");
+        return -1;
+    }
+    tmp = op->func_name;
+    Py_INCREF(value);
+    op->func_name = value;
+    Py_DECREF(tmp);
+    return 0;
+}
+
+static PyObject *
+func_get_defaults(PyFunctionObject *op)
+{
+    if (restricted())
+        return NULL;
+    if (op->func_defaults == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    Py_INCREF(op->func_defaults);
+    return op->func_defaults;
+}
+
+static int
+func_set_defaults(PyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (restricted())
+        return -1;
+    /* Legal to del f.func_defaults.
+     * Can only set func_defaults to NULL or a tuple. */
+    if (value == Py_None)
+        value = NULL;
+    if (value != NULL && !PyTuple_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__defaults__ must be set to a tuple object");
+        return -1;
+    }
+    tmp = op->func_defaults;
+    Py_XINCREF(value);
+    op->func_defaults = value;
+    Py_XDECREF(tmp);
+    return 0;
+}
+
+static PyGetSetDef func_getsetlist[] = {
+    {"func_code", (getter)func_get_code, (setter)func_set_code},
+    {"__code__", (getter)func_get_code, (setter)func_set_code},
+    {"func_defaults", (getter)func_get_defaults,
+     (setter)func_set_defaults},
+    {"__defaults__", (getter)func_get_defaults,
+     (setter)func_set_defaults},
+    {"func_dict", (getter)func_get_dict, (setter)func_set_dict},
+    {"__dict__", (getter)func_get_dict, (setter)func_set_dict},
+    {"func_name", (getter)func_get_name, (setter)func_set_name},
+    {"__name__", (getter)func_get_name, (setter)func_set_name},
+    {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(func_doc,
+"function(code, globals[, name[, argdefs[, closure]]])\n\
+\n\
+Create a function object from a code object and a dictionary.\n\
+The optional name string overrides the name from the code object.\n\
+The optional argdefs tuple specifies the default argument values.\n\
+The optional closure tuple supplies the bindings for free variables.");
+
+/* func_new() maintains the following invariants for closures.  The
+   closure must correspond to the free variables of the code object.
+
+   if len(code.co_freevars) == 0:
+       closure = NULL
+   else:
+       len(closure) == len(code.co_freevars)
+   for every elt in closure, type(elt) == cell
+*/
+
+static PyObject *
+func_new(PyTypeObject* type, PyObject* args, PyObject* kw)
+{
+    PyCodeObject *code;
+    PyObject *globals;
+    PyObject *name = Py_None;
+    PyObject *defaults = Py_None;
+    PyObject *closure = Py_None;
+    PyFunctionObject *newfunc;
+    Py_ssize_t nfree, nclosure;
+    static char *kwlist[] = {"code", "globals", "name",
+                             "argdefs", "closure", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!|OOO:function",
+                          kwlist,
+                          &PyCode_Type, &code,
+                          &PyDict_Type, &globals,
+                          &name, &defaults, &closure))
+        return NULL;
+    if (name != Py_None && !PyString_Check(name)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "arg 3 (name) must be None or string");
+        return NULL;
+    }
+    if (defaults != Py_None && !PyTuple_Check(defaults)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "arg 4 (defaults) must be None or tuple");
+        return NULL;
+    }
+    nfree = PyTuple_GET_SIZE(code->co_freevars);
+    if (!PyTuple_Check(closure)) {
+        if (nfree && closure == Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+                            "arg 5 (closure) must be tuple");
+            return NULL;
+        }
+        else if (closure != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+                "arg 5 (closure) must be None or tuple");
+            return NULL;
+        }
+    }
+
+    /* check that the closure is well-formed */
+    nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
+    if (nfree != nclosure)
+        return PyErr_Format(PyExc_ValueError,
+                            "%s requires closure of length %zd, not %zd",
+                            PyString_AS_STRING(code->co_name),
+                            nfree, nclosure);
+    if (nclosure) {
+        Py_ssize_t i;
+        for (i = 0; i < nclosure; i++) {
+            PyObject *o = PyTuple_GET_ITEM(closure, i);
+            if (!PyCell_Check(o)) {
+                return PyErr_Format(PyExc_TypeError,
+                    "arg 5 (closure) expected cell, found %s",
+                                    o->ob_type->tp_name);
+            }
+        }
+    }
+
+    newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,
+                                                 globals);
+    if (newfunc == NULL)
+        return NULL;
+
+    if (name != Py_None) {
+        Py_INCREF(name);
+        Py_DECREF(newfunc->func_name);
+        newfunc->func_name = name;
+    }
+    if (defaults != Py_None) {
+        Py_INCREF(defaults);
+        newfunc->func_defaults  = defaults;
+    }
+    if (closure != Py_None) {
+        Py_INCREF(closure);
+        newfunc->func_closure = closure;
+    }
+
+    return (PyObject *)newfunc;
+}
+
+static void
+func_dealloc(PyFunctionObject *op)
+{
+    _PyObject_GC_UNTRACK(op);
+    if (op->func_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) op);
+    Py_DECREF(op->func_code);
+    Py_DECREF(op->func_globals);
+    Py_XDECREF(op->func_module);
+    Py_DECREF(op->func_name);
+    Py_XDECREF(op->func_defaults);
+    Py_XDECREF(op->func_doc);
+    Py_XDECREF(op->func_dict);
+    Py_XDECREF(op->func_closure);
+    PyObject_GC_Del(op);
+}
+
+static PyObject*
+func_repr(PyFunctionObject *op)
+{
+    return PyString_FromFormat("<function %s at %p>",
+                               PyString_AsString(op->func_name),
+                               op);
+}
+
+static int
+func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
+{
+    Py_VISIT(f->func_code);
+    Py_VISIT(f->func_globals);
+    Py_VISIT(f->func_module);
+    Py_VISIT(f->func_defaults);
+    Py_VISIT(f->func_doc);
+    Py_VISIT(f->func_name);
+    Py_VISIT(f->func_dict);
+    Py_VISIT(f->func_closure);
+    return 0;
+}
+
+static PyObject *
+function_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+    PyObject *result;
+    PyObject *argdefs;
+    PyObject *kwtuple = NULL;
+    PyObject **d, **k;
+    Py_ssize_t nk, nd;
+
+    argdefs = PyFunction_GET_DEFAULTS(func);
+    if (argdefs != NULL && PyTuple_Check(argdefs)) {
+        d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
+        nd = PyTuple_GET_SIZE(argdefs);
+    }
+    else {
+        d = NULL;
+        nd = 0;
+    }
+
+    if (kw != NULL && PyDict_Check(kw)) {
+        Py_ssize_t pos, i;
+        nk = PyDict_Size(kw);
+        kwtuple = PyTuple_New(2*nk);
+        if (kwtuple == NULL)
+            return NULL;
+        k = &PyTuple_GET_ITEM(kwtuple, 0);
+        pos = i = 0;
+        while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) {
+            Py_INCREF(k[i]);
+            Py_INCREF(k[i+1]);
+            i += 2;
+        }
+        nk = i/2;
+    }
+    else {
+        k = NULL;
+        nk = 0;
+    }
+
+    result = PyEval_EvalCodeEx(
+        (PyCodeObject *)PyFunction_GET_CODE(func),
+        PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
+        &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
+        k, nk, d, nd,
+        PyFunction_GET_CLOSURE(func));
+
+    Py_XDECREF(kwtuple);
+
+    return result;
+}
+
+/* Bind a function to an object */
+static PyObject *
+func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+    if (obj == Py_None)
+        obj = NULL;
+    return PyMethod_New(func, obj, type);
+}
+
+PyTypeObject PyFunction_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "function",
+    sizeof(PyFunctionObject),
+    0,
+    (destructor)func_dealloc,                   /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)func_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    function_call,                              /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    PyObject_GenericSetAttr,                    /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    func_doc,                                   /* tp_doc */
+    (traverseproc)func_traverse,                /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    func_memberlist,                            /* tp_members */
+    func_getsetlist,                            /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    func_descr_get,                             /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    offsetof(PyFunctionObject, func_dict),      /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    func_new,                                   /* tp_new */
+};
+
+
+/* Class method object */
+
+/* A class method receives the class as implicit first argument,
+   just like an instance method receives the instance.
+   To declare a class method, use this idiom:
+
+     class C:
+     def f(cls, arg1, arg2, ...): ...
+     f = classmethod(f)
+
+   It can be called either on the class (e.g. C.f()) or on an instance
+   (e.g. C().f()); the instance is ignored except for its class.
+   If a class method is called for a derived class, the derived class
+   object is passed as the implied first argument.
+
+   Class methods are different than C++ or Java static methods.
+   If you want those, see static methods below.
+*/
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *cm_callable;
+} classmethod;
+
+static void
+cm_dealloc(classmethod *cm)
+{
+    _PyObject_GC_UNTRACK((PyObject *)cm);
+    Py_XDECREF(cm->cm_callable);
+    Py_TYPE(cm)->tp_free((PyObject *)cm);
+}
+
+static int
+cm_traverse(classmethod *cm, visitproc visit, void *arg)
+{
+    Py_VISIT(cm->cm_callable);
+    return 0;
+}
+
+static int
+cm_clear(classmethod *cm)
+{
+    Py_CLEAR(cm->cm_callable);
+    return 0;
+}
+
+
+static PyObject *
+cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    classmethod *cm = (classmethod *)self;
+
+    if (cm->cm_callable == NULL) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "uninitialized classmethod object");
+        return NULL;
+    }
+    if (type == NULL)
+        type = (PyObject *)(Py_TYPE(obj));
+    return PyMethod_New(cm->cm_callable,
+                        type, (PyObject *)(Py_TYPE(type)));
+}
+
+static int
+cm_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    classmethod *cm = (classmethod *)self;
+    PyObject *callable;
+
+    if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))
+        return -1;
+    if (!_PyArg_NoKeywords("classmethod", kwds))
+        return -1;
+    Py_INCREF(callable);
+    cm->cm_callable = callable;
+    return 0;
+}
+
+static PyMemberDef cm_memberlist[] = {
+    {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
+    {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(classmethod_doc,
+"classmethod(function) -> method\n\
+\n\
+Convert a function to be a class method.\n\
+\n\
+A class method receives the class as implicit first argument,\n\
+just like an instance method receives the instance.\n\
+To declare a class method, use this idiom:\n\
+\n\
+  class C:\n\
+      def f(cls, arg1, arg2, ...): ...\n\
+      f = classmethod(f)\n\
+\n\
+It can be called either on the class (e.g. C.f()) or on an instance\n\
+(e.g. C().f()).  The instance is ignored except for its class.\n\
+If a class method is called for a derived class, the derived class\n\
+object is passed as the implied first argument.\n\
+\n\
+Class methods are different than C++ or Java static methods.\n\
+If you want those, see the staticmethod builtin.");
+
+PyTypeObject PyClassMethod_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "classmethod",
+    sizeof(classmethod),
+    0,
+    (destructor)cm_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    classmethod_doc,                            /* tp_doc */
+    (traverseproc)cm_traverse,                  /* tp_traverse */
+    (inquiry)cm_clear,                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    cm_memberlist,              /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    cm_descr_get,                               /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    cm_init,                                    /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    PyType_GenericNew,                          /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
+
+PyObject *
+PyClassMethod_New(PyObject *callable)
+{
+    classmethod *cm = (classmethod *)
+        PyType_GenericAlloc(&PyClassMethod_Type, 0);
+    if (cm != NULL) {
+        Py_INCREF(callable);
+        cm->cm_callable = callable;
+    }
+    return (PyObject *)cm;
+}
+
+
+/* Static method object */
+
+/* A static method does not receive an implicit first argument.
+   To declare a static method, use this idiom:
+
+     class C:
+     def f(arg1, arg2, ...): ...
+     f = staticmethod(f)
+
+   It can be called either on the class (e.g. C.f()) or on an instance
+   (e.g. C().f()); the instance is ignored except for its class.
+
+   Static methods in Python are similar to those found in Java or C++.
+   For a more advanced concept, see class methods above.
+*/
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *sm_callable;
+} staticmethod;
+
+static void
+sm_dealloc(staticmethod *sm)
+{
+    _PyObject_GC_UNTRACK((PyObject *)sm);
+    Py_XDECREF(sm->sm_callable);
+    Py_TYPE(sm)->tp_free((PyObject *)sm);
+}
+
+static int
+sm_traverse(staticmethod *sm, visitproc visit, void *arg)
+{
+    Py_VISIT(sm->sm_callable);
+    return 0;
+}
+
+static int
+sm_clear(staticmethod *sm)
+{
+    Py_CLEAR(sm->sm_callable);
+    return 0;
+}
+
+static PyObject *
+sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    staticmethod *sm = (staticmethod *)self;
+
+    if (sm->sm_callable == NULL) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "uninitialized staticmethod object");
+        return NULL;
+    }
+    Py_INCREF(sm->sm_callable);
+    return sm->sm_callable;
+}
+
+static int
+sm_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    staticmethod *sm = (staticmethod *)self;
+    PyObject *callable;
+
+    if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))
+        return -1;
+    if (!_PyArg_NoKeywords("staticmethod", kwds))
+        return -1;
+    Py_INCREF(callable);
+    sm->sm_callable = callable;
+    return 0;
+}
+
+static PyMemberDef sm_memberlist[] = {
+    {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
+    {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(staticmethod_doc,
+"staticmethod(function) -> method\n\
+\n\
+Convert a function to be a static method.\n\
+\n\
+A static method does not receive an implicit first argument.\n\
+To declare a static method, use this idiom:\n\
+\n\
+     class C:\n\
+     def f(arg1, arg2, ...): ...\n\
+     f = staticmethod(f)\n\
+\n\
+It can be called either on the class (e.g. C.f()) or on an instance\n\
+(e.g. C().f()).  The instance is ignored except for its class.\n\
+\n\
+Static methods in Python are similar to those found in Java or C++.\n\
+For a more advanced concept, see the classmethod builtin.");
+
+PyTypeObject PyStaticMethod_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "staticmethod",
+    sizeof(staticmethod),
+    0,
+    (destructor)sm_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    staticmethod_doc,                           /* tp_doc */
+    (traverseproc)sm_traverse,                  /* tp_traverse */
+    (inquiry)sm_clear,                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    sm_memberlist,              /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    sm_descr_get,                               /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    sm_init,                                    /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    PyType_GenericNew,                          /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
+
+PyObject *
+PyStaticMethod_New(PyObject *callable)
+{
+    staticmethod *sm = (staticmethod *)
+        PyType_GenericAlloc(&PyStaticMethod_Type, 0);
+    if (sm != NULL) {
+        Py_INCREF(callable);
+        sm->sm_callable = callable;
+    }
+    return (PyObject *)sm;
+}
diff --git a/Python-2.7.5/Objects/genobject.c b/Python-2.7.5/Objects/genobject.c
new file mode 100644
index 0000000..341f660
--- /dev/null
+++ b/Python-2.7.5/Objects/genobject.c
@@ -0,0 +1,414 @@
+/* Generator object implementation */
+
+#include "Python.h"
+#include "frameobject.h"
+#include "genobject.h"
+#include "ceval.h"
+#include "structmember.h"
+#include "opcode.h"
+
+static int
+gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
+{
+    Py_VISIT((PyObject *)gen->gi_frame);
+    Py_VISIT(gen->gi_code);
+    return 0;
+}
+
+static void
+gen_dealloc(PyGenObject *gen)
+{
+    PyObject *self = (PyObject *) gen;
+
+    _PyObject_GC_UNTRACK(gen);
+
+    if (gen->gi_weakreflist != NULL)
+        PyObject_ClearWeakRefs(self);
+
+    _PyObject_GC_TRACK(self);
+
+    if (gen->gi_frame != NULL && gen->gi_frame->f_stacktop != NULL) {
+        /* Generator is paused, so we need to close */
+        Py_TYPE(gen)->tp_del(self);
+        if (self->ob_refcnt > 0)
+            return;                     /* resurrected.  :( */
+    }
+
+    _PyObject_GC_UNTRACK(self);
+    Py_CLEAR(gen->gi_frame);
+    Py_CLEAR(gen->gi_code);
+    PyObject_GC_Del(gen);
+}
+
+
+static PyObject *
+gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
+{
+    PyThreadState *tstate = PyThreadState_GET();
+    PyFrameObject *f = gen->gi_frame;
+    PyObject *result;
+
+    if (gen->gi_running) {
+        PyErr_SetString(PyExc_ValueError,
+                        "generator already executing");
+        return NULL;
+    }
+    if (f==NULL || f->f_stacktop == NULL) {
+        /* Only set exception if called from send() */
+        if (arg && !exc)
+            PyErr_SetNone(PyExc_StopIteration);
+        return NULL;
+    }
+
+    if (f->f_lasti == -1) {
+        if (arg && arg != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+                            "can't send non-None value to a "
+                            "just-started generator");
+            return NULL;
+        }
+    } else {
+        /* Push arg onto the frame's value stack */
+        result = arg ? arg : Py_None;
+        Py_INCREF(result);
+        *(f->f_stacktop++) = result;
+    }
+
+    /* Generators always return to their most recent caller, not
+     * necessarily their creator. */
+    Py_XINCREF(tstate->frame);
+    assert(f->f_back == NULL);
+    f->f_back = tstate->frame;
+
+    gen->gi_running = 1;
+    result = PyEval_EvalFrameEx(f, exc);
+    gen->gi_running = 0;
+
+    /* Don't keep the reference to f_back any longer than necessary.  It
+     * may keep a chain of frames alive or it could create a reference
+     * cycle. */
+    assert(f->f_back == tstate->frame);
+    Py_CLEAR(f->f_back);
+
+    /* If the generator just returned (as opposed to yielding), signal
+     * that the generator is exhausted. */
+    if (result == Py_None && f->f_stacktop == NULL) {
+        Py_DECREF(result);
+        result = NULL;
+        /* Set exception if not called by gen_iternext() */
+        if (arg)
+            PyErr_SetNone(PyExc_StopIteration);
+    }
+
+    if (!result || f->f_stacktop == NULL) {
+        /* generator can't be rerun, so release the frame */
+        Py_DECREF(f);
+        gen->gi_frame = NULL;
+    }
+
+    return result;
+}
+
+PyDoc_STRVAR(send_doc,
+"send(arg) -> send 'arg' into generator,\n\
+return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_send(PyGenObject *gen, PyObject *arg)
+{
+    return gen_send_ex(gen, arg, 0);
+}
+
+PyDoc_STRVAR(close_doc,
+"close() -> raise GeneratorExit inside generator.");
+
+static PyObject *
+gen_close(PyGenObject *gen, PyObject *args)
+{
+    PyObject *retval;
+    PyErr_SetNone(PyExc_GeneratorExit);
+    retval = gen_send_ex(gen, Py_None, 1);
+    if (retval) {
+        Py_DECREF(retval);
+        PyErr_SetString(PyExc_RuntimeError,
+                        "generator ignored GeneratorExit");
+        return NULL;
+    }
+    if (PyErr_ExceptionMatches(PyExc_StopIteration)
+        || PyErr_ExceptionMatches(PyExc_GeneratorExit))
+    {
+        PyErr_Clear();          /* ignore these errors */
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return NULL;
+}
+
+static void
+gen_del(PyObject *self)
+{
+    PyObject *res;
+    PyObject *error_type, *error_value, *error_traceback;
+    PyGenObject *gen = (PyGenObject *)self;
+
+    if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
+        /* Generator isn't paused, so no need to close */
+        return;
+
+    /* Temporarily resurrect the object. */
+    assert(self->ob_refcnt == 0);
+    self->ob_refcnt = 1;
+
+    /* Save the current exception, if any. */
+    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+    res = gen_close(gen, NULL);
+
+    if (res == NULL)
+        PyErr_WriteUnraisable(self);
+    else
+        Py_DECREF(res);
+
+    /* Restore the saved exception. */
+    PyErr_Restore(error_type, error_value, error_traceback);
+
+    /* Undo the temporary resurrection; can't use DECREF here, it would
+     * cause a recursive call.
+     */
+    assert(self->ob_refcnt > 0);
+    if (--self->ob_refcnt == 0)
+        return; /* this is the normal path out */
+
+    /* close() resurrected it!  Make it look like the original Py_DECREF
+     * never happened.
+     */
+    {
+        Py_ssize_t refcnt = self->ob_refcnt;
+        _Py_NewReference(self);
+        self->ob_refcnt = refcnt;
+    }
+    assert(PyType_IS_GC(self->ob_type) &&
+           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+
+    /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+     * we need to undo that. */
+    _Py_DEC_REFTOTAL;
+    /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+     * chain, so no more to do there.
+     * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+     * _Py_NewReference bumped tp_allocs:  both of those need to be
+     * undone.
+     */
+#ifdef COUNT_ALLOCS
+    --self->ob_type->tp_frees;
+    --self->ob_type->tp_allocs;
+#endif
+}
+
+
+
+PyDoc_STRVAR(throw_doc,
+"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
+return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_throw(PyGenObject *gen, PyObject *args)
+{
+    PyObject *typ;
+    PyObject *tb = NULL;
+    PyObject *val = NULL;
+
+    if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
+        return NULL;
+
+    /* First, check the traceback argument, replacing None with
+       NULL. */
+    if (tb == Py_None)
+        tb = NULL;
+    else if (tb != NULL && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "throw() third argument must be a traceback object");
+        return NULL;
+    }
+
+    Py_INCREF(typ);
+    Py_XINCREF(val);
+    Py_XINCREF(tb);
+
+    if (PyExceptionClass_Check(typ)) {
+        PyErr_NormalizeException(&typ, &val, &tb);
+    }
+
+    else if (PyExceptionInstance_Check(typ)) {
+        /* Raising an instance.  The value should be a dummy. */
+        if (val && val != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+              "instance exception may not have a separate value");
+            goto failed_throw;
+        }
+        else {
+            /* Normalize to raise <class>, <instance> */
+            Py_XDECREF(val);
+            val = typ;
+            typ = PyExceptionInstance_Class(typ);
+            Py_INCREF(typ);
+        }
+    }
+    else {
+        /* Not something you can raise.  throw() fails. */
+        PyErr_Format(PyExc_TypeError,
+                     "exceptions must be classes, or instances, not %s",
+                     typ->ob_type->tp_name);
+            goto failed_throw;
+    }
+
+    PyErr_Restore(typ, val, tb);
+    return gen_send_ex(gen, Py_None, 1);
+
+failed_throw:
+    /* Didn't use our arguments, so restore their original refcounts */
+    Py_DECREF(typ);
+    Py_XDECREF(val);
+    Py_XDECREF(tb);
+    return NULL;
+}
+
+
+static PyObject *
+gen_iternext(PyGenObject *gen)
+{
+    return gen_send_ex(gen, NULL, 0);
+}
+
+
+static PyObject *
+gen_repr(PyGenObject *gen)
+{
+    char *code_name;
+    code_name = PyString_AsString(((PyCodeObject *)gen->gi_code)->co_name);
+    if (code_name == NULL)
+        return NULL;
+    return PyString_FromFormat("<generator object %.200s at %p>",
+                               code_name, gen);
+}
+
+
+static PyObject *
+gen_get_name(PyGenObject *gen)
+{
+    PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name;
+    Py_INCREF(name);
+    return name;
+}
+
+
+PyDoc_STRVAR(gen__name__doc__,
+"Return the name of the generator's associated code object.");
+
+static PyGetSetDef gen_getsetlist[] = {
+    {"__name__", (getter)gen_get_name, NULL, gen__name__doc__},
+    {NULL}
+};
+
+
+static PyMemberDef gen_memberlist[] = {
+    {"gi_frame",        T_OBJECT, offsetof(PyGenObject, gi_frame),      RO},
+    {"gi_running",      T_INT,    offsetof(PyGenObject, gi_running),    RO},
+    {"gi_code",     T_OBJECT, offsetof(PyGenObject, gi_code),  RO},
+    {NULL}      /* Sentinel */
+};
+
+static PyMethodDef gen_methods[] = {
+    {"send",(PyCFunction)gen_send, METH_O, send_doc},
+    {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
+    {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
+    {NULL, NULL}        /* Sentinel */
+};
+
+PyTypeObject PyGen_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "generator",                                /* tp_name */
+    sizeof(PyGenObject),                        /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)gen_dealloc,                    /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)gen_repr,                         /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)gen_traverse,                 /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    offsetof(PyGenObject, gi_weakreflist),      /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)gen_iternext,                 /* tp_iternext */
+    gen_methods,                                /* tp_methods */
+    gen_memberlist,                             /* tp_members */
+    gen_getsetlist,                             /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    0,                                          /* tp_new */
+    0,                                          /* tp_free */
+    0,                                          /* tp_is_gc */
+    0,                                          /* tp_bases */
+    0,                                          /* tp_mro */
+    0,                                          /* tp_cache */
+    0,                                          /* tp_subclasses */
+    0,                                          /* tp_weaklist */
+    gen_del,                                    /* tp_del */
+};
+
+PyObject *
+PyGen_New(PyFrameObject *f)
+{
+    PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
+    if (gen == NULL) {
+        Py_DECREF(f);
+        return NULL;
+    }
+    gen->gi_frame = f;
+    Py_INCREF(f->f_code);
+    gen->gi_code = (PyObject *)(f->f_code);
+    gen->gi_running = 0;
+    gen->gi_weakreflist = NULL;
+    _PyObject_GC_TRACK(gen);
+    return (PyObject *)gen;
+}
+
+int
+PyGen_NeedsFinalizing(PyGenObject *gen)
+{
+    int i;
+    PyFrameObject *f = gen->gi_frame;
+
+    if (f == NULL || f->f_stacktop == NULL || f->f_iblock <= 0)
+        return 0; /* no frame or empty blockstack == no finalization */
+
+    /* Any block type besides a loop requires cleanup. */
+    i = f->f_iblock;
+    while (--i >= 0) {
+        if (f->f_blockstack[i].b_type != SETUP_LOOP)
+            return 1;
+    }
+
+    /* No blocks except loops, it's safe to skip finalization. */
+    return 0;
+}
diff --git a/Python-2.7.5/Objects/intobject.c b/Python-2.7.5/Objects/intobject.c
new file mode 100644
index 0000000..28182f9
--- /dev/null
+++ b/Python-2.7.5/Objects/intobject.c
@@ -0,0 +1,1581 @@
+
+/* Integer object implementation */
+
+#include "Python.h"
+#include <ctype.h>
+#include <float.h>
+
+static PyObject *int_int(PyIntObject *v);
+
+long
+PyInt_GetMax(void)
+{
+    return LONG_MAX;            /* To initialize sys.maxint */
+}
+
+/* Integers are quite normal objects, to make object handling uniform.
+   (Using odd pointers to represent integers would save much space
+   but require extra checks for this special case throughout the code.)
+   Since a typical Python program spends much of its time allocating
+   and deallocating integers, these operations should be very fast.
+   Therefore we use a dedicated allocation scheme with a much lower
+   overhead (in space and time) than straight malloc(): a simple
+   dedicated free list, filled when necessary with memory from malloc().
+
+   block_list is a singly-linked list of all PyIntBlocks ever allocated,
+   linked via their next members.  PyIntBlocks are never returned to the
+   system before shutdown (PyInt_Fini).
+
+   free_list is a singly-linked list of available PyIntObjects, linked
+   via abuse of their ob_type members.
+*/
+
+#define BLOCK_SIZE      1000    /* 1K less typical malloc overhead */
+#define BHEAD_SIZE      8       /* Enough for a 64-bit pointer */
+#define N_INTOBJECTS    ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
+
+struct _intblock {
+    struct _intblock *next;
+    PyIntObject objects[N_INTOBJECTS];
+};
+
+typedef struct _intblock PyIntBlock;
+
+static PyIntBlock *block_list = NULL;
+static PyIntObject *free_list = NULL;
+
+static PyIntObject *
+fill_free_list(void)
+{
+    PyIntObject *p, *q;
+    /* Python's object allocator isn't appropriate for large blocks. */
+    p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
+    if (p == NULL)
+        return (PyIntObject *) PyErr_NoMemory();
+    ((PyIntBlock *)p)->next = block_list;
+    block_list = (PyIntBlock *)p;
+    /* Link the int objects together, from rear to front, then return
+       the address of the last int object in the block. */
+    p = &((PyIntBlock *)p)->objects[0];
+    q = p + N_INTOBJECTS;
+    while (--q > p)
+        Py_TYPE(q) = (struct _typeobject *)(q-1);
+    Py_TYPE(q) = NULL;
+    return p + N_INTOBJECTS - 1;
+}
+
+#ifndef NSMALLPOSINTS
+#define NSMALLPOSINTS           257
+#endif
+#ifndef NSMALLNEGINTS
+#define NSMALLNEGINTS           5
+#endif
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+/* References to small integers are saved in this array so that they
+   can be shared.
+   The integers that are saved are those in the range
+   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
+*/
+static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
+#endif
+#ifdef COUNT_ALLOCS
+Py_ssize_t quick_int_allocs;
+Py_ssize_t quick_neg_int_allocs;
+#endif
+
+PyObject *
+PyInt_FromLong(long ival)
+{
+    register PyIntObject *v;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+    if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
+        v = small_ints[ival + NSMALLNEGINTS];
+        Py_INCREF(v);
+#ifdef COUNT_ALLOCS
+        if (ival >= 0)
+            quick_int_allocs++;
+        else
+            quick_neg_int_allocs++;
+#endif
+        return (PyObject *) v;
+    }
+#endif
+    if (free_list == NULL) {
+        if ((free_list = fill_free_list()) == NULL)
+            return NULL;
+    }
+    /* Inline PyObject_New */
+    v = free_list;
+    free_list = (PyIntObject *)Py_TYPE(v);
+    PyObject_INIT(v, &PyInt_Type);
+    v->ob_ival = ival;
+    return (PyObject *) v;
+}
+
+PyObject *
+PyInt_FromSize_t(size_t ival)
+{
+    if (ival <= LONG_MAX)
+        return PyInt_FromLong((long)ival);
+    return _PyLong_FromSize_t(ival);
+}
+
+PyObject *
+PyInt_FromSsize_t(Py_ssize_t ival)
+{
+    if (ival >= LONG_MIN && ival <= LONG_MAX)
+        return PyInt_FromLong((long)ival);
+    return _PyLong_FromSsize_t(ival);
+}
+
+static void
+int_dealloc(PyIntObject *v)
+{
+    if (PyInt_CheckExact(v)) {
+        Py_TYPE(v) = (struct _typeobject *)free_list;
+        free_list = v;
+    }
+    else
+        Py_TYPE(v)->tp_free((PyObject *)v);
+}
+
+static void
+int_free(PyIntObject *v)
+{
+    Py_TYPE(v) = (struct _typeobject *)free_list;
+    free_list = v;
+}
+
+long
+PyInt_AsLong(register PyObject *op)
+{
+    PyNumberMethods *nb;
+    PyIntObject *io;
+    long val;
+
+    if (op && PyInt_Check(op))
+        return PyInt_AS_LONG((PyIntObject*) op);
+
+    if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
+        nb->nb_int == NULL) {
+        PyErr_SetString(PyExc_TypeError, "an integer is required");
+        return -1;
+    }
+
+    io = (PyIntObject*) (*nb->nb_int) (op);
+    if (io == NULL)
+        return -1;
+    if (!PyInt_Check(io)) {
+        if (PyLong_Check(io)) {
+            /* got a long? => retry int conversion */
+            val = PyLong_AsLong((PyObject *)io);
+            Py_DECREF(io);
+            if ((val == -1) && PyErr_Occurred())
+                return -1;
+            return val;
+        }
+        else
+        {
+            Py_DECREF(io);
+            PyErr_SetString(PyExc_TypeError,
+                        "__int__ method should return an integer");
+            return -1;
+        }
+    }
+
+    val = PyInt_AS_LONG(io);
+    Py_DECREF(io);
+
+    return val;
+}
+
+int
+_PyInt_AsInt(PyObject *obj)
+{
+    long result = PyInt_AsLong(obj);
+    if (result == -1 && PyErr_Occurred())
+        return -1;
+    if (result > INT_MAX || result < INT_MIN) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "Python int too large to convert to C int");
+        return -1;
+    }
+    return (int)result;
+}
+
+Py_ssize_t
+PyInt_AsSsize_t(register PyObject *op)
+{
+#if SIZEOF_SIZE_T != SIZEOF_LONG
+    PyNumberMethods *nb;
+    PyIntObject *io;
+    Py_ssize_t val;
+#endif
+
+    if (op == NULL) {
+        PyErr_SetString(PyExc_TypeError, "an integer is required");
+        return -1;
+    }
+
+    if (PyInt_Check(op))
+        return PyInt_AS_LONG((PyIntObject*) op);
+    if (PyLong_Check(op))
+        return _PyLong_AsSsize_t(op);
+#if SIZEOF_SIZE_T == SIZEOF_LONG
+    return PyInt_AsLong(op);
+#else
+
+    if ((nb = Py_TYPE(op)->tp_as_number) == NULL ||
+        (nb->nb_int == NULL && nb->nb_long == 0)) {
+        PyErr_SetString(PyExc_TypeError, "an integer is required");
+        return -1;
+    }
+
+    if (nb->nb_long != 0)
+        io = (PyIntObject*) (*nb->nb_long) (op);
+    else
+        io = (PyIntObject*) (*nb->nb_int) (op);
+    if (io == NULL)
+        return -1;
+    if (!PyInt_Check(io)) {
+        if (PyLong_Check(io)) {
+            /* got a long? => retry int conversion */
+            val = _PyLong_AsSsize_t((PyObject *)io);
+            Py_DECREF(io);
+            if ((val == -1) && PyErr_Occurred())
+                return -1;
+            return val;
+        }
+        else
+        {
+            Py_DECREF(io);
+            PyErr_SetString(PyExc_TypeError,
+                        "__int__ method should return an integer");
+            return -1;
+        }
+    }
+
+    val = PyInt_AS_LONG(io);
+    Py_DECREF(io);
+
+    return val;
+#endif
+}
+
+unsigned long
+PyInt_AsUnsignedLongMask(register PyObject *op)
+{
+    PyNumberMethods *nb;
+    PyIntObject *io;
+    unsigned long val;
+
+    if (op && PyInt_Check(op))
+        return PyInt_AS_LONG((PyIntObject*) op);
+    if (op && PyLong_Check(op))
+        return PyLong_AsUnsignedLongMask(op);
+
+    if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
+        nb->nb_int == NULL) {
+        PyErr_SetString(PyExc_TypeError, "an integer is required");
+        return (unsigned long)-1;
+    }
+
+    io = (PyIntObject*) (*nb->nb_int) (op);
+    if (io == NULL)
+        return (unsigned long)-1;
+    if (!PyInt_Check(io)) {
+        if (PyLong_Check(io)) {
+            val = PyLong_AsUnsignedLongMask((PyObject *)io);
+            Py_DECREF(io);
+            if (PyErr_Occurred())
+                return (unsigned long)-1;
+            return val;
+        }
+        else
+        {
+            Py_DECREF(io);
+            PyErr_SetString(PyExc_TypeError,
+                        "__int__ method should return an integer");
+            return (unsigned long)-1;
+        }
+    }
+
+    val = PyInt_AS_LONG(io);
+    Py_DECREF(io);
+
+    return val;
+}
+
+#ifdef HAVE_LONG_LONG
+unsigned PY_LONG_LONG
+PyInt_AsUnsignedLongLongMask(register PyObject *op)
+{
+    PyNumberMethods *nb;
+    PyIntObject *io;
+    unsigned PY_LONG_LONG val;
+
+    if (op && PyInt_Check(op))
+        return PyInt_AS_LONG((PyIntObject*) op);
+    if (op && PyLong_Check(op))
+        return PyLong_AsUnsignedLongLongMask(op);
+
+    if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
+        nb->nb_int == NULL) {
+        PyErr_SetString(PyExc_TypeError, "an integer is required");
+        return (unsigned PY_LONG_LONG)-1;
+    }
+
+    io = (PyIntObject*) (*nb->nb_int) (op);
+    if (io == NULL)
+        return (unsigned PY_LONG_LONG)-1;
+    if (!PyInt_Check(io)) {
+        if (PyLong_Check(io)) {
+            val = PyLong_AsUnsignedLongLongMask((PyObject *)io);
+            Py_DECREF(io);
+            if (PyErr_Occurred())
+                return (unsigned PY_LONG_LONG)-1;
+            return val;
+        }
+        else
+        {
+            Py_DECREF(io);
+            PyErr_SetString(PyExc_TypeError,
+                        "__int__ method should return an integer");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+    }
+
+    val = PyInt_AS_LONG(io);
+    Py_DECREF(io);
+
+    return val;
+}
+#endif
+
+PyObject *
+PyInt_FromString(char *s, char **pend, int base)
+{
+    char *end;
+    long x;
+    Py_ssize_t slen;
+    PyObject *sobj, *srepr;
+
+    if ((base != 0 && base < 2) || base > 36) {
+        PyErr_SetString(PyExc_ValueError,
+                        "int() base must be >= 2 and <= 36");
+        return NULL;
+    }
+
+    while (*s && isspace(Py_CHARMASK(*s)))
+        s++;
+    errno = 0;
+    if (base == 0 && s[0] == '0') {
+        x = (long) PyOS_strtoul(s, &end, base);
+        if (x < 0)
+            return PyLong_FromString(s, pend, base);
+    }
+    else
+        x = PyOS_strtol(s, &end, base);
+    if (end == s || !isalnum(Py_CHARMASK(end[-1])))
+        goto bad;
+    while (*end && isspace(Py_CHARMASK(*end)))
+        end++;
+    if (*end != '\0') {
+  bad:
+        slen = strlen(s) < 200 ? strlen(s) : 200;
+        sobj = PyString_FromStringAndSize(s, slen);
+        if (sobj == NULL)
+            return NULL;
+        srepr = PyObject_Repr(sobj);
+        Py_DECREF(sobj);
+        if (srepr == NULL)
+            return NULL;
+        PyErr_Format(PyExc_ValueError,
+                     "invalid literal for int() with base %d: %s",
+                     base, PyString_AS_STRING(srepr));
+        Py_DECREF(srepr);
+        return NULL;
+    }
+    else if (errno != 0)
+        return PyLong_FromString(s, pend, base);
+    if (pend)
+        *pend = end;
+    return PyInt_FromLong(x);
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyInt_FromUnicode(Py_UNICODE *s, Py_ssize_t length, int base)
+{
+    PyObject *result;
+    char *buffer = (char *)PyMem_MALLOC(length+1);
+
+    if (buffer == NULL)
+        return PyErr_NoMemory();
+
+    if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) {
+        PyMem_FREE(buffer);
+        return NULL;
+    }
+    result = PyInt_FromString(buffer, NULL, base);
+    PyMem_FREE(buffer);
+    return result;
+}
+#endif
+
+/* Methods */
+
+/* Integers are seen as the "smallest" of all numeric types and thus
+   don't have any knowledge about conversion of other types to
+   integers. */
+
+#define CONVERT_TO_LONG(obj, lng)               \
+    if (PyInt_Check(obj)) {                     \
+        lng = PyInt_AS_LONG(obj);               \
+    }                                           \
+    else {                                      \
+        Py_INCREF(Py_NotImplemented);           \
+        return Py_NotImplemented;               \
+    }
+
+/* ARGSUSED */
+static int
+int_print(PyIntObject *v, FILE *fp, int flags)
+     /* flags -- not used but required by interface */
+{
+    long int_val = v->ob_ival;
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "%ld", int_val);
+    Py_END_ALLOW_THREADS
+    return 0;
+}
+
+static int
+int_compare(PyIntObject *v, PyIntObject *w)
+{
+    register long i = v->ob_ival;
+    register long j = w->ob_ival;
+    return (i < j) ? -1 : (i > j) ? 1 : 0;
+}
+
+static long
+int_hash(PyIntObject *v)
+{
+    /* XXX If this is changed, you also need to change the way
+       Python's long, float and complex types are hashed. */
+    long x = v -> ob_ival;
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+static PyObject *
+int_add(PyIntObject *v, PyIntObject *w)
+{
+    register long a, b, x;
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    /* casts in the line below avoid undefined behaviour on overflow */
+    x = (long)((unsigned long)a + b);
+    if ((x^a) >= 0 || (x^b) >= 0)
+        return PyInt_FromLong(x);
+    return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
+}
+
+static PyObject *
+int_sub(PyIntObject *v, PyIntObject *w)
+{
+    register long a, b, x;
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    /* casts in the line below avoid undefined behaviour on overflow */
+    x = (long)((unsigned long)a - b);
+    if ((x^a) >= 0 || (x^~b) >= 0)
+        return PyInt_FromLong(x);
+    return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v,
+                                                 (PyObject *)w);
+}
+
+/*
+Integer overflow checking for * is painful:  Python tried a couple ways, but
+they didn't work on all platforms, or failed in endcases (a product of
+-sys.maxint-1 has been a particular pain).
+
+Here's another way:
+
+The native long product x*y is either exactly right or *way* off, being
+just the last n bits of the true product, where n is the number of bits
+in a long (the delivered product is the true product plus i*2**n for
+some integer i).
+
+The native double product (double)x * (double)y is subject to three
+rounding errors:  on a sizeof(long)==8 box, each cast to double can lose
+info, and even on a sizeof(long)==4 box, the multiplication can lose info.
+But, unlike the native long product, it's not in *range* trouble:  even
+if sizeof(long)==32 (256-bit longs), the product easily fits in the
+dynamic range of a double.  So the leading 50 (or so) bits of the double
+product are correct.
+
+We check these two ways against each other, and declare victory if they're
+approximately the same.  Else, because the native long product is the only
+one that can lose catastrophic amounts of information, it's the native long
+product that must have overflowed.
+*/
+
+static PyObject *
+int_mul(PyObject *v, PyObject *w)
+{
+    long a, b;
+    long longprod;                      /* a*b in native long arithmetic */
+    double doubled_longprod;            /* (double)longprod */
+    double doubleprod;                  /* (double)a * (double)b */
+
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    /* casts in the next line avoid undefined behaviour on overflow */
+    longprod = (long)((unsigned long)a * b);
+    doubleprod = (double)a * (double)b;
+    doubled_longprod = (double)longprod;
+
+    /* Fast path for normal case:  small multiplicands, and no info
+       is lost in either method. */
+    if (doubled_longprod == doubleprod)
+        return PyInt_FromLong(longprod);
+
+    /* Somebody somewhere lost info.  Close enough, or way off?  Note
+       that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
+       The difference either is or isn't significant compared to the
+       true value (of which doubleprod is a good approximation).
+    */
+    {
+        const double diff = doubled_longprod - doubleprod;
+        const double absdiff = diff >= 0.0 ? diff : -diff;
+        const double absprod = doubleprod >= 0.0 ? doubleprod :
+                              -doubleprod;
+        /* absdiff/absprod <= 1/32 iff
+           32 * absdiff <= absprod -- 5 good bits is "close enough" */
+        if (32.0 * absdiff <= absprod)
+            return PyInt_FromLong(longprod);
+        else
+            return PyLong_Type.tp_as_number->nb_multiply(v, w);
+    }
+}
+
+/* Integer overflow checking for unary negation: on a 2's-complement
+ * box, -x overflows iff x is the most negative long.  In this case we
+ * get -x == x.  However, -x is undefined (by C) if x /is/ the most
+ * negative long (it's a signed overflow case), and some compilers care.
+ * So we cast x to unsigned long first.  However, then other compilers
+ * warn about applying unary minus to an unsigned operand.  Hence the
+ * weird "0-".
+ */
+#define UNARY_NEG_WOULD_OVERFLOW(x)     \
+    ((x) < 0 && (unsigned long)(x) == 0-(unsigned long)(x))
+
+/* Return type of i_divmod */
+enum divmod_result {
+    DIVMOD_OK,                  /* Correct result */
+    DIVMOD_OVERFLOW,            /* Overflow, try again using longs */
+    DIVMOD_ERROR                /* Exception raised */
+};
+
+static enum divmod_result
+i_divmod(register long x, register long y,
+         long *p_xdivy, long *p_xmody)
+{
+    long xdivy, xmody;
+
+    if (y == 0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "integer division or modulo by zero");
+        return DIVMOD_ERROR;
+    }
+    /* (-sys.maxint-1)/-1 is the only overflow case. */
+    if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
+        return DIVMOD_OVERFLOW;
+    xdivy = x / y;
+    /* xdiv*y can overflow on platforms where x/y gives floor(x/y)
+     * for x and y with differing signs. (This is unusual
+     * behaviour, and C99 prohibits it, but it's allowed by C89;
+     * for an example of overflow, take x = LONG_MIN, y = 5 or x =
+     * LONG_MAX, y = -5.)  However, x - xdivy*y is always
+     * representable as a long, since it lies strictly between
+     * -abs(y) and abs(y).  We add casts to avoid intermediate
+     * overflow.
+     */
+    xmody = (long)(x - (unsigned long)xdivy * y);
+    /* If the signs of x and y differ, and the remainder is non-0,
+     * C89 doesn't define whether xdivy is now the floor or the
+     * ceiling of the infinitely precise quotient.  We want the floor,
+     * and we have it iff the remainder's sign matches y's.
+     */
+    if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
+        xmody += y;
+        --xdivy;
+        assert(xmody && ((y ^ xmody) >= 0));
+    }
+    *p_xdivy = xdivy;
+    *p_xmody = xmody;
+    return DIVMOD_OK;
+}
+
+static PyObject *
+int_div(PyIntObject *x, PyIntObject *y)
+{
+    long xi, yi;
+    long d, m;
+    CONVERT_TO_LONG(x, xi);
+    CONVERT_TO_LONG(y, yi);
+    switch (i_divmod(xi, yi, &d, &m)) {
+    case DIVMOD_OK:
+        return PyInt_FromLong(d);
+    case DIVMOD_OVERFLOW:
+        return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
+                                                   (PyObject *)y);
+    default:
+        return NULL;
+    }
+}
+
+static PyObject *
+int_classic_div(PyIntObject *x, PyIntObject *y)
+{
+    long xi, yi;
+    long d, m;
+    CONVERT_TO_LONG(x, xi);
+    CONVERT_TO_LONG(y, yi);
+    if (Py_DivisionWarningFlag &&
+        PyErr_Warn(PyExc_DeprecationWarning, "classic int division") < 0)
+        return NULL;
+    switch (i_divmod(xi, yi, &d, &m)) {
+    case DIVMOD_OK:
+        return PyInt_FromLong(d);
+    case DIVMOD_OVERFLOW:
+        return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
+                                                   (PyObject *)y);
+    default:
+        return NULL;
+    }
+}
+
+static PyObject *
+int_true_divide(PyIntObject *x, PyIntObject *y)
+{
+    long xi, yi;
+    /* If they aren't both ints, give someone else a chance.  In
+       particular, this lets int/long get handled by longs, which
+       underflows to 0 gracefully if the long is too big to convert
+       to float. */
+    CONVERT_TO_LONG(x, xi);
+    CONVERT_TO_LONG(y, yi);
+    if (yi == 0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "division by zero");
+        return NULL;
+    }
+    if (xi == 0)
+        return PyFloat_FromDouble(yi < 0 ? -0.0 : 0.0);
+
+#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG)
+#if DBL_MANT_DIG < WIDTH_OF_ULONG
+    if ((xi >= 0 ? 0UL + xi : 0UL - xi) >> DBL_MANT_DIG ||
+        (yi >= 0 ? 0UL + yi : 0UL - yi) >> DBL_MANT_DIG)
+        /* Large x or y.  Use long integer arithmetic. */
+        return PyLong_Type.tp_as_number->nb_true_divide(
+            (PyObject *)x, (PyObject *)y);
+    else
+#endif
+        /* Both ints can be exactly represented as doubles.  Do a
+           floating-point division. */
+        return PyFloat_FromDouble((double)xi / (double)yi);
+}
+
+static PyObject *
+int_mod(PyIntObject *x, PyIntObject *y)
+{
+    long xi, yi;
+    long d, m;
+    CONVERT_TO_LONG(x, xi);
+    CONVERT_TO_LONG(y, yi);
+    switch (i_divmod(xi, yi, &d, &m)) {
+    case DIVMOD_OK:
+        return PyInt_FromLong(m);
+    case DIVMOD_OVERFLOW:
+        return PyLong_Type.tp_as_number->nb_remainder((PyObject *)x,
+                                                      (PyObject *)y);
+    default:
+        return NULL;
+    }
+}
+
+static PyObject *
+int_divmod(PyIntObject *x, PyIntObject *y)
+{
+    long xi, yi;
+    long d, m;
+    CONVERT_TO_LONG(x, xi);
+    CONVERT_TO_LONG(y, yi);
+    switch (i_divmod(xi, yi, &d, &m)) {
+    case DIVMOD_OK:
+        return Py_BuildValue("(ll)", d, m);
+    case DIVMOD_OVERFLOW:
+        return PyLong_Type.tp_as_number->nb_divmod((PyObject *)x,
+                                                   (PyObject *)y);
+    default:
+        return NULL;
+    }
+}
+
+static PyObject *
+int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
+{
+    register long iv, iw, iz=0, ix, temp, prev;
+    CONVERT_TO_LONG(v, iv);
+    CONVERT_TO_LONG(w, iw);
+    if (iw < 0) {
+        if ((PyObject *)z != Py_None) {
+            PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
+                 "cannot be negative when 3rd argument specified");
+            return NULL;
+        }
+        /* Return a float.  This works because we know that
+           this calls float_pow() which converts its
+           arguments to double. */
+        return PyFloat_Type.tp_as_number->nb_power(
+            (PyObject *)v, (PyObject *)w, (PyObject *)z);
+    }
+    if ((PyObject *)z != Py_None) {
+        CONVERT_TO_LONG(z, iz);
+        if (iz == 0) {
+            PyErr_SetString(PyExc_ValueError,
+                            "pow() 3rd argument cannot be 0");
+            return NULL;
+        }
+    }
+    /*
+     * XXX: The original exponentiation code stopped looping
+     * when temp hit zero; this code will continue onwards
+     * unnecessarily, but at least it won't cause any errors.
+     * Hopefully the speed improvement from the fast exponentiation
+     * will compensate for the slight inefficiency.
+     * XXX: Better handling of overflows is desperately needed.
+     */
+    temp = iv;
+    ix = 1;
+    while (iw > 0) {
+        prev = ix;              /* Save value for overflow check */
+        if (iw & 1) {
+            /*
+             * The (unsigned long) cast below ensures that the multiplication
+             * is interpreted as an unsigned operation rather than a signed one
+             * (C99 6.3.1.8p1), thus avoiding the perils of undefined behaviour
+             * from signed arithmetic overflow (C99 6.5p5).  See issue #12973.
+             */
+            ix = (unsigned long)ix * temp;
+            if (temp == 0)
+                break; /* Avoid ix / 0 */
+            if (ix / temp != prev) {
+                return PyLong_Type.tp_as_number->nb_power(
+                    (PyObject *)v,
+                    (PyObject *)w,
+                    (PyObject *)z);
+            }
+        }
+        iw >>= 1;               /* Shift exponent down by 1 bit */
+        if (iw==0) break;
+        prev = temp;
+        temp = (unsigned long)temp * temp;  /* Square the value of temp */
+        if (prev != 0 && temp / prev != prev) {
+            return PyLong_Type.tp_as_number->nb_power(
+                (PyObject *)v, (PyObject *)w, (PyObject *)z);
+        }
+        if (iz) {
+            /* If we did a multiplication, perform a modulo */
+            ix = ix % iz;
+            temp = temp % iz;
+        }
+    }
+    if (iz) {
+        long div, mod;
+        switch (i_divmod(ix, iz, &div, &mod)) {
+        case DIVMOD_OK:
+            ix = mod;
+            break;
+        case DIVMOD_OVERFLOW:
+            return PyLong_Type.tp_as_number->nb_power(
+                (PyObject *)v, (PyObject *)w, (PyObject *)z);
+        default:
+            return NULL;
+        }
+    }
+    return PyInt_FromLong(ix);
+}
+
+static PyObject *
+int_neg(PyIntObject *v)
+{
+    register long a;
+    a = v->ob_ival;
+    /* check for overflow */
+    if (UNARY_NEG_WOULD_OVERFLOW(a)) {
+        PyObject *o = PyLong_FromLong(a);
+        if (o != NULL) {
+            PyObject *result = PyNumber_Negative(o);
+            Py_DECREF(o);
+            return result;
+        }
+        return NULL;
+    }
+    return PyInt_FromLong(-a);
+}
+
+static PyObject *
+int_abs(PyIntObject *v)
+{
+    if (v->ob_ival >= 0)
+        return int_int(v);
+    else
+        return int_neg(v);
+}
+
+static int
+int_nonzero(PyIntObject *v)
+{
+    return v->ob_ival != 0;
+}
+
+static PyObject *
+int_invert(PyIntObject *v)
+{
+    return PyInt_FromLong(~v->ob_ival);
+}
+
+static PyObject *
+int_lshift(PyIntObject *v, PyIntObject *w)
+{
+    long a, b, c;
+    PyObject *vv, *ww, *result;
+
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    if (b < 0) {
+        PyErr_SetString(PyExc_ValueError, "negative shift count");
+        return NULL;
+    }
+    if (a == 0 || b == 0)
+        return int_int(v);
+    if (b >= LONG_BIT) {
+        vv = PyLong_FromLong(PyInt_AS_LONG(v));
+        if (vv == NULL)
+            return NULL;
+        ww = PyLong_FromLong(PyInt_AS_LONG(w));
+        if (ww == NULL) {
+            Py_DECREF(vv);
+            return NULL;
+        }
+        result = PyNumber_Lshift(vv, ww);
+        Py_DECREF(vv);
+        Py_DECREF(ww);
+        return result;
+    }
+    c = a << b;
+    if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
+        vv = PyLong_FromLong(PyInt_AS_LONG(v));
+        if (vv == NULL)
+            return NULL;
+        ww = PyLong_FromLong(PyInt_AS_LONG(w));
+        if (ww == NULL) {
+            Py_DECREF(vv);
+            return NULL;
+        }
+        result = PyNumber_Lshift(vv, ww);
+        Py_DECREF(vv);
+        Py_DECREF(ww);
+        return result;
+    }
+    return PyInt_FromLong(c);
+}
+
+static PyObject *
+int_rshift(PyIntObject *v, PyIntObject *w)
+{
+    register long a, b;
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    if (b < 0) {
+        PyErr_SetString(PyExc_ValueError, "negative shift count");
+        return NULL;
+    }
+    if (a == 0 || b == 0)
+        return int_int(v);
+    if (b >= LONG_BIT) {
+        if (a < 0)
+            a = -1;
+        else
+            a = 0;
+    }
+    else {
+        a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
+    }
+    return PyInt_FromLong(a);
+}
+
+static PyObject *
+int_and(PyIntObject *v, PyIntObject *w)
+{
+    register long a, b;
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    return PyInt_FromLong(a & b);
+}
+
+static PyObject *
+int_xor(PyIntObject *v, PyIntObject *w)
+{
+    register long a, b;
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    return PyInt_FromLong(a ^ b);
+}
+
+static PyObject *
+int_or(PyIntObject *v, PyIntObject *w)
+{
+    register long a, b;
+    CONVERT_TO_LONG(v, a);
+    CONVERT_TO_LONG(w, b);
+    return PyInt_FromLong(a | b);
+}
+
+static int
+int_coerce(PyObject **pv, PyObject **pw)
+{
+    if (PyInt_Check(*pw)) {
+        Py_INCREF(*pv);
+        Py_INCREF(*pw);
+        return 0;
+    }
+    return 1; /* Can't do it */
+}
+
+static PyObject *
+int_int(PyIntObject *v)
+{
+    if (PyInt_CheckExact(v))
+        Py_INCREF(v);
+    else
+        v = (PyIntObject *)PyInt_FromLong(v->ob_ival);
+    return (PyObject *)v;
+}
+
+static PyObject *
+int_long(PyIntObject *v)
+{
+    return PyLong_FromLong((v -> ob_ival));
+}
+
+static const unsigned char BitLengthTable[32] = {
+    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_ulong(unsigned long d)
+{
+    int d_bits = 0;
+    while (d >= 32) {
+        d_bits += 6;
+        d >>= 6;
+    }
+    d_bits += (int)BitLengthTable[d];
+    return d_bits;
+}
+
+#if 8*SIZEOF_LONG-1 <= DBL_MANT_DIG
+/* Every Python int can be exactly represented as a float. */
+
+static PyObject *
+int_float(PyIntObject *v)
+{
+    return PyFloat_FromDouble((double)(v -> ob_ival));
+}
+
+#else
+/* Here not all Python ints are exactly representable as floats, so we may
+   have to round.  We do this manually, since the C standards don't specify
+   whether converting an integer to a float rounds up or down */
+
+static PyObject *
+int_float(PyIntObject *v)
+{
+    unsigned long abs_ival, lsb;
+    int round_up;
+
+    if (v->ob_ival < 0)
+        abs_ival = 0U-(unsigned long)v->ob_ival;
+    else
+        abs_ival = (unsigned long)v->ob_ival;
+    if (abs_ival < (1L << DBL_MANT_DIG))
+        /* small integer;  no need to round */
+        return PyFloat_FromDouble((double)v->ob_ival);
+
+    /* Round abs_ival to MANT_DIG significant bits, using the
+       round-half-to-even rule.  abs_ival & lsb picks out the 'rounding'
+       bit: the first bit after the most significant MANT_DIG bits of
+       abs_ival.  We round up if this bit is set, provided that either:
+
+         (1) abs_ival isn't exactly halfway between two floats, in which
+         case at least one of the bits following the rounding bit must be
+         set; i.e., abs_ival & lsb-1 != 0, or:
+
+         (2) the resulting rounded value has least significant bit 0; or
+         in other words the bit above the rounding bit is set (this is the
+         'to-even' bit of round-half-to-even); i.e., abs_ival & 2*lsb != 0
+
+       The condition "(1) or (2)" equates to abs_ival & 3*lsb-1 != 0. */
+
+    lsb = 1L << (bits_in_ulong(abs_ival)-DBL_MANT_DIG-1);
+    round_up = (abs_ival & lsb) && (abs_ival & (3*lsb-1));
+    abs_ival &= -2*lsb;
+    if (round_up)
+        abs_ival += 2*lsb;
+    return PyFloat_FromDouble(v->ob_ival < 0 ?
+                              -(double)abs_ival :
+                  (double)abs_ival);
+}
+
+#endif
+
+static PyObject *
+int_oct(PyIntObject *v)
+{
+    return _PyInt_Format(v, 8, 0);
+}
+
+static PyObject *
+int_hex(PyIntObject *v)
+{
+    return _PyInt_Format(v, 16, 0);
+}
+
+static PyObject *
+int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *x = NULL;
+    int base = -909;
+    static char *kwlist[] = {"x", "base", 0};
+
+    if (type != &PyInt_Type)
+        return int_subtype_new(type, args, kwds); /* Wimp out */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
+                                     &x, &base))
+        return NULL;
+    if (x == NULL) {
+        if (base != -909) {
+            PyErr_SetString(PyExc_TypeError,
+                            "int() missing string argument");
+            return NULL;
+        }
+        return PyInt_FromLong(0L);
+    }
+    if (base == -909)
+        return PyNumber_Int(x);
+    if (PyString_Check(x)) {
+        /* Since PyInt_FromString doesn't have a length parameter,
+         * check here for possible NULs in the string. */
+        char *string = PyString_AS_STRING(x);
+        if (strlen(string) != PyString_Size(x)) {
+            /* create a repr() of the input string,
+             * just like PyInt_FromString does */
+            PyObject *srepr;
+            srepr = PyObject_Repr(x);
+            if (srepr == NULL)
+                return NULL;
+            PyErr_Format(PyExc_ValueError,
+                 "invalid literal for int() with base %d: %s",
+                 base, PyString_AS_STRING(srepr));
+            Py_DECREF(srepr);
+            return NULL;
+        }
+        return PyInt_FromString(string, NULL, base);
+    }
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(x))
+        return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
+                                 PyUnicode_GET_SIZE(x),
+                                 base);
+#endif
+    PyErr_SetString(PyExc_TypeError,
+                    "int() can't convert non-string with explicit base");
+    return NULL;
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of int:
+   first create a regular int from whatever arguments we got,
+   then allocate a subtype instance and initialize its ob_ival
+   from the regular int.  The regular int is then thrown away.
+*/
+static PyObject *
+int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *tmp, *newobj;
+    long ival;
+
+    assert(PyType_IsSubtype(type, &PyInt_Type));
+    tmp = int_new(&PyInt_Type, args, kwds);
+    if (tmp == NULL)
+        return NULL;
+    if (!PyInt_Check(tmp)) {
+        ival = PyLong_AsLong(tmp);
+        if (ival == -1 && PyErr_Occurred()) {
+            Py_DECREF(tmp);
+            return NULL;
+        }
+    } else {
+        ival = ((PyIntObject *)tmp)->ob_ival;
+    }
+
+    newobj = type->tp_alloc(type, 0);
+    if (newobj == NULL) {
+        Py_DECREF(tmp);
+        return NULL;
+    }
+    ((PyIntObject *)newobj)->ob_ival = ival;
+    Py_DECREF(tmp);
+    return newobj;
+}
+
+static PyObject *
+int_getnewargs(PyIntObject *v)
+{
+    return Py_BuildValue("(l)", v->ob_ival);
+}
+
+static PyObject *
+int_get0(PyIntObject *v, void *context) {
+    return PyInt_FromLong(0L);
+}
+
+static PyObject *
+int_get1(PyIntObject *v, void *context) {
+    return PyInt_FromLong(1L);
+}
+
+/* Convert an integer to a decimal string.  On many platforms, this
+   will be significantly faster than the general arbitrary-base
+   conversion machinery in _PyInt_Format, thanks to optimization
+   opportunities offered by division by a compile-time constant. */
+static PyObject *
+int_to_decimal_string(PyIntObject *v) {
+    char buf[sizeof(long)*CHAR_BIT/3+6], *p, *bufend;
+    long n = v->ob_ival;
+    unsigned long absn;
+    p = bufend = buf + sizeof(buf);
+    absn = n < 0 ? 0UL - n : n;
+    do {
+        *--p = '0' + (char)(absn % 10);
+        absn /= 10;
+    } while (absn);
+    if (n < 0)
+        *--p = '-';
+    return PyString_FromStringAndSize(p, bufend - p);
+}
+
+/* Convert an integer to the given base.  Returns a string.
+   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'.
+   If newstyle is zero, then use the pre-2.6 behavior of octal having
+   a leading "0" */
+PyAPI_FUNC(PyObject*)
+_PyInt_Format(PyIntObject *v, int base, int newstyle)
+{
+    /* There are no doubt many, many ways to optimize this, using code
+       similar to _PyLong_Format */
+    long n = v->ob_ival;
+    int  negative = n < 0;
+    int is_zero = n == 0;
+
+    /* For the reasoning behind this size, see
+       http://c-faq.com/misc/hexio.html. Then, add a few bytes for
+       the possible sign and prefix "0[box]" */
+    char buf[sizeof(n)*CHAR_BIT+6];
+
+    /* Start by pointing to the end of the buffer.  We fill in from
+       the back forward. */
+    char* p = &buf[sizeof(buf)];
+
+    assert(base >= 2 && base <= 36);
+
+    /* Special case base 10, for speed */
+    if (base == 10)
+        return int_to_decimal_string(v);
+
+    do {
+        /* I'd use i_divmod, except it doesn't produce the results
+           I want when n is negative.  So just duplicate the salient
+           part here. */
+        long div = n / base;
+        long mod = n - div * base;
+
+        /* convert abs(mod) to the right character in [0-9, a-z] */
+        char cdigit = (char)(mod < 0 ? -mod : mod);
+        cdigit += (cdigit < 10) ? '0' : 'a'-10;
+        *--p = cdigit;
+
+        n = div;
+    } while(n);
+
+    if (base == 2) {
+        *--p = 'b';
+        *--p = '0';
+    }
+    else if (base == 8) {
+        if (newstyle) {
+            *--p = 'o';
+            *--p = '0';
+        }
+        else
+            if (!is_zero)
+                *--p = '0';
+    }
+    else if (base == 16) {
+        *--p = 'x';
+        *--p = '0';
+    }
+    else {
+        *--p = '#';
+        *--p = '0' + base%10;
+        if (base > 10)
+            *--p = '0' + base/10;
+    }
+    if (negative)
+        *--p = '-';
+
+    return PyString_FromStringAndSize(p, &buf[sizeof(buf)] - p);
+}
+
+static PyObject *
+int__format__(PyObject *self, PyObject *args)
+{
+    PyObject *format_spec;
+
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+        return NULL;
+    if (PyBytes_Check(format_spec))
+        return _PyInt_FormatAdvanced(self,
+                                     PyBytes_AS_STRING(format_spec),
+                                     PyBytes_GET_SIZE(format_spec));
+    if (PyUnicode_Check(format_spec)) {
+        /* Convert format_spec to a str */
+        PyObject *result;
+        PyObject *str_spec = PyObject_Str(format_spec);
+
+        if (str_spec == NULL)
+            return NULL;
+
+        result = _PyInt_FormatAdvanced(self,
+                                       PyBytes_AS_STRING(str_spec),
+                                       PyBytes_GET_SIZE(str_spec));
+
+        Py_DECREF(str_spec);
+        return result;
+    }
+    PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+    return NULL;
+}
+
+static PyObject *
+int_bit_length(PyIntObject *v)
+{
+    unsigned long n;
+
+    if (v->ob_ival < 0)
+        /* avoid undefined behaviour when v->ob_ival == -LONG_MAX-1 */
+        n = 0U-(unsigned long)v->ob_ival;
+    else
+        n = (unsigned long)v->ob_ival;
+
+    return PyInt_FromLong(bits_in_ulong(n));
+}
+
+PyDoc_STRVAR(int_bit_length_doc,
+"int.bit_length() -> int\n\
+\n\
+Number of bits necessary to represent self in binary.\n\
+>>> bin(37)\n\
+'0b100101'\n\
+>>> (37).bit_length()\n\
+6");
+
+#if 0
+static PyObject *
+int_is_finite(PyObject *v)
+{
+    Py_RETURN_TRUE;
+}
+#endif
+
+static PyMethodDef int_methods[] = {
+    {"conjugate",       (PyCFunction)int_int,   METH_NOARGS,
+     "Returns self, the complex conjugate of any int."},
+    {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS,
+     int_bit_length_doc},
+#if 0
+    {"is_finite",       (PyCFunction)int_is_finite,     METH_NOARGS,
+     "Returns always True."},
+#endif
+    {"__trunc__",       (PyCFunction)int_int,   METH_NOARGS,
+     "Truncating an Integral returns itself."},
+    {"__getnewargs__",          (PyCFunction)int_getnewargs,    METH_NOARGS},
+    {"__format__", (PyCFunction)int__format__, METH_VARARGS},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyGetSetDef int_getset[] = {
+    {"real",
+     (getter)int_int, (setter)NULL,
+     "the real part of a complex number",
+     NULL},
+    {"imag",
+     (getter)int_get0, (setter)NULL,
+     "the imaginary part of a complex number",
+     NULL},
+    {"numerator",
+     (getter)int_int, (setter)NULL,
+     "the numerator of a rational number in lowest terms",
+     NULL},
+    {"denominator",
+     (getter)int_get1, (setter)NULL,
+     "the denominator of a rational number in lowest terms",
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(int_doc,
+"int(x=0) -> int or long\n\
+int(x, base=10) -> int or long\n\
+\n\
+Convert a number or string to an integer, or return 0 if no arguments\n\
+are given.  If x is floating point, the conversion truncates towards zero.\n\
+If x is outside the integer range, the function returns a long instead.\n\
+\n\
+If x is not a number or if base is given, then x must be a string or\n\
+Unicode object representing an integer literal in the given base.  The\n\
+literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\
+The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to\n\
+interpret the base from the string as an integer literal.\n\
+>>> int('0b100', base=0)\n\
+4");
+
+static PyNumberMethods int_as_number = {
+    (binaryfunc)int_add,        /*nb_add*/
+    (binaryfunc)int_sub,        /*nb_subtract*/
+    (binaryfunc)int_mul,        /*nb_multiply*/
+    (binaryfunc)int_classic_div, /*nb_divide*/
+    (binaryfunc)int_mod,        /*nb_remainder*/
+    (binaryfunc)int_divmod,     /*nb_divmod*/
+    (ternaryfunc)int_pow,       /*nb_power*/
+    (unaryfunc)int_neg,         /*nb_negative*/
+    (unaryfunc)int_int,         /*nb_positive*/
+    (unaryfunc)int_abs,         /*nb_absolute*/
+    (inquiry)int_nonzero,       /*nb_nonzero*/
+    (unaryfunc)int_invert,      /*nb_invert*/
+    (binaryfunc)int_lshift,     /*nb_lshift*/
+    (binaryfunc)int_rshift,     /*nb_rshift*/
+    (binaryfunc)int_and,        /*nb_and*/
+    (binaryfunc)int_xor,        /*nb_xor*/
+    (binaryfunc)int_or,         /*nb_or*/
+    int_coerce,                 /*nb_coerce*/
+    (unaryfunc)int_int,         /*nb_int*/
+    (unaryfunc)int_long,        /*nb_long*/
+    (unaryfunc)int_float,       /*nb_float*/
+    (unaryfunc)int_oct,         /*nb_oct*/
+    (unaryfunc)int_hex,         /*nb_hex*/
+    0,                          /*nb_inplace_add*/
+    0,                          /*nb_inplace_subtract*/
+    0,                          /*nb_inplace_multiply*/
+    0,                          /*nb_inplace_divide*/
+    0,                          /*nb_inplace_remainder*/
+    0,                          /*nb_inplace_power*/
+    0,                          /*nb_inplace_lshift*/
+    0,                          /*nb_inplace_rshift*/
+    0,                          /*nb_inplace_and*/
+    0,                          /*nb_inplace_xor*/
+    0,                          /*nb_inplace_or*/
+    (binaryfunc)int_div,        /* nb_floor_divide */
+    (binaryfunc)int_true_divide, /* nb_true_divide */
+    0,                          /* nb_inplace_floor_divide */
+    0,                          /* nb_inplace_true_divide */
+    (unaryfunc)int_int,         /* nb_index */
+};
+
+PyTypeObject PyInt_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "int",
+    sizeof(PyIntObject),
+    0,
+    (destructor)int_dealloc,                    /* tp_dealloc */
+    (printfunc)int_print,                       /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)int_compare,                       /* tp_compare */
+    (reprfunc)int_to_decimal_string,            /* tp_repr */
+    &int_as_number,                             /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)int_hash,                         /* tp_hash */
+    0,                                          /* tp_call */
+    (reprfunc)int_to_decimal_string,            /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_INT_SUBCLASS,          /* tp_flags */
+    int_doc,                                    /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    int_methods,                                /* tp_methods */
+    0,                                          /* tp_members */
+    int_getset,                                 /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    int_new,                                    /* tp_new */
+    (freefunc)int_free,                         /* tp_free */
+};
+
+int
+_PyInt_Init(void)
+{
+    PyIntObject *v;
+    int ival;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+    for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
+          if (!free_list && (free_list = fill_free_list()) == NULL)
+                    return 0;
+        /* PyObject_New is inlined */
+        v = free_list;
+        free_list = (PyIntObject *)Py_TYPE(v);
+        PyObject_INIT(v, &PyInt_Type);
+        v->ob_ival = ival;
+        small_ints[ival + NSMALLNEGINTS] = v;
+    }
+#endif
+    return 1;
+}
+
+int
+PyInt_ClearFreeList(void)
+{
+    PyIntObject *p;
+    PyIntBlock *list, *next;
+    int i;
+    int u;                      /* remaining unfreed ints per block */
+    int freelist_size = 0;
+
+    list = block_list;
+    block_list = NULL;
+    free_list = NULL;
+    while (list != NULL) {
+        u = 0;
+        for (i = 0, p = &list->objects[0];
+             i < N_INTOBJECTS;
+             i++, p++) {
+            if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
+                u++;
+        }
+        next = list->next;
+        if (u) {
+            list->next = block_list;
+            block_list = list;
+            for (i = 0, p = &list->objects[0];
+                 i < N_INTOBJECTS;
+                 i++, p++) {
+                if (!PyInt_CheckExact(p) ||
+                    p->ob_refcnt == 0) {
+                    Py_TYPE(p) = (struct _typeobject *)
+                        free_list;
+                    free_list = p;
+                }
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+                else if (-NSMALLNEGINTS <= p->ob_ival &&
+                         p->ob_ival < NSMALLPOSINTS &&
+                         small_ints[p->ob_ival +
+                                    NSMALLNEGINTS] == NULL) {
+                    Py_INCREF(p);
+                    small_ints[p->ob_ival +
+                               NSMALLNEGINTS] = p;
+                }
+#endif
+            }
+        }
+        else {
+            PyMem_FREE(list);
+        }
+        freelist_size += u;
+        list = next;
+    }
+
+    return freelist_size;
+}
+
+void
+PyInt_Fini(void)
+{
+    PyIntObject *p;
+    PyIntBlock *list;
+    int i;
+    int u;                      /* total unfreed ints per block */
+
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+    PyIntObject **q;
+
+    i = NSMALLNEGINTS + NSMALLPOSINTS;
+    q = small_ints;
+    while (--i >= 0) {
+        Py_XDECREF(*q);
+        *q++ = NULL;
+    }
+#endif
+    u = PyInt_ClearFreeList();
+    if (!Py_VerboseFlag)
+        return;
+    fprintf(stderr, "# cleanup ints");
+    if (!u) {
+        fprintf(stderr, "\n");
+    }
+    else {
+        fprintf(stderr,
+            ": %d unfreed int%s\n",
+            u, u == 1 ? "" : "s");
+    }
+    if (Py_VerboseFlag > 1) {
+        list = block_list;
+        while (list != NULL) {
+            for (i = 0, p = &list->objects[0];
+                 i < N_INTOBJECTS;
+                 i++, p++) {
+                if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
+                    /* XXX(twouters) cast refcount to
+                       long until %zd is universally
+                       available
+                     */
+                    fprintf(stderr,
+                "#   <int at %p, refcnt=%ld, val=%ld>\n",
+                                p, (long)p->ob_refcnt,
+                                p->ob_ival);
+            }
+            list = list->next;
+        }
+    }
+}
diff --git a/Python-2.7.5/Objects/iterobject.c b/Python-2.7.5/Objects/iterobject.c
new file mode 100644
index 0000000..5a9a2dd
--- /dev/null
+++ b/Python-2.7.5/Objects/iterobject.c
@@ -0,0 +1,230 @@
+/* Iterator objects */
+
+#include "Python.h"
+
+typedef struct {
+    PyObject_HEAD
+    long      it_index;
+    PyObject *it_seq; /* Set to NULL when iterator is exhausted */
+} seqiterobject;
+
+PyObject *
+PySeqIter_New(PyObject *seq)
+{
+    seqiterobject *it;
+
+    if (!PySequence_Check(seq)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
+    if (it == NULL)
+        return NULL;
+    it->it_index = 0;
+    Py_INCREF(seq);
+    it->it_seq = seq;
+    _PyObject_GC_TRACK(it);
+    return (PyObject *)it;
+}
+
+static void
+iter_dealloc(seqiterobject *it)
+{
+    _PyObject_GC_UNTRACK(it);
+    Py_XDECREF(it->it_seq);
+    PyObject_GC_Del(it);
+}
+
+static int
+iter_traverse(seqiterobject *it, visitproc visit, void *arg)
+{
+    Py_VISIT(it->it_seq);
+    return 0;
+}
+
+static PyObject *
+iter_iternext(PyObject *iterator)
+{
+    seqiterobject *it;
+    PyObject *seq;
+    PyObject *result;
+
+    assert(PySeqIter_Check(iterator));
+    it = (seqiterobject *)iterator;
+    seq = it->it_seq;
+    if (seq == NULL)
+        return NULL;
+
+    result = PySequence_GetItem(seq, it->it_index);
+    if (result != NULL) {
+        it->it_index++;
+        return result;
+    }
+    if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+        PyErr_ExceptionMatches(PyExc_StopIteration))
+    {
+        PyErr_Clear();
+        Py_DECREF(seq);
+        it->it_seq = NULL;
+    }
+    return NULL;
+}
+
+static PyObject *
+iter_len(seqiterobject *it)
+{
+    Py_ssize_t seqsize, len;
+
+    if (it->it_seq) {
+        seqsize = PySequence_Size(it->it_seq);
+        if (seqsize == -1)
+            return NULL;
+        len = seqsize - it->it_index;
+        if (len >= 0)
+            return PyInt_FromSsize_t(len);
+    }
+    return PyInt_FromLong(0);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef seqiter_methods[] = {
+    {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PySeqIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "iterator",                                 /* tp_name */
+    sizeof(seqiterobject),                      /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)iter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)iter_traverse,                /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    iter_iternext,                              /* tp_iternext */
+    seqiter_methods,                            /* tp_methods */
+    0,                                          /* tp_members */
+};
+
+/* -------------------------------------- */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *it_callable; /* Set to NULL when iterator is exhausted */
+    PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
+} calliterobject;
+
+PyObject *
+PyCallIter_New(PyObject *callable, PyObject *sentinel)
+{
+    calliterobject *it;
+    it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
+    if (it == NULL)
+        return NULL;
+    Py_INCREF(callable);
+    it->it_callable = callable;
+    Py_INCREF(sentinel);
+    it->it_sentinel = sentinel;
+    _PyObject_GC_TRACK(it);
+    return (PyObject *)it;
+}
+static void
+calliter_dealloc(calliterobject *it)
+{
+    _PyObject_GC_UNTRACK(it);
+    Py_XDECREF(it->it_callable);
+    Py_XDECREF(it->it_sentinel);
+    PyObject_GC_Del(it);
+}
+
+static int
+calliter_traverse(calliterobject *it, visitproc visit, void *arg)
+{
+    Py_VISIT(it->it_callable);
+    Py_VISIT(it->it_sentinel);
+    return 0;
+}
+
+static PyObject *
+calliter_iternext(calliterobject *it)
+{
+    if (it->it_callable != NULL) {
+        PyObject *args = PyTuple_New(0);
+        PyObject *result;
+        if (args == NULL)
+            return NULL;
+        result = PyObject_Call(it->it_callable, args, NULL);
+        Py_DECREF(args);
+        if (result != NULL) {
+            int ok;
+            ok = PyObject_RichCompareBool(result,
+                                          it->it_sentinel,
+                                          Py_EQ);
+            if (ok == 0)
+                return result; /* Common case, fast path */
+            Py_DECREF(result);
+            if (ok > 0) {
+                Py_CLEAR(it->it_callable);
+                Py_CLEAR(it->it_sentinel);
+            }
+        }
+        else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+            PyErr_Clear();
+            Py_CLEAR(it->it_callable);
+            Py_CLEAR(it->it_sentinel);
+        }
+    }
+    return NULL;
+}
+
+PyTypeObject PyCallIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "callable-iterator",                        /* tp_name */
+    sizeof(calliterobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)calliter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)calliter_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)calliter_iternext,            /* tp_iternext */
+    0,                                          /* tp_methods */
+};
diff --git a/Python-2.7.5/Objects/listobject.c b/Python-2.7.5/Objects/listobject.c
new file mode 100644
index 0000000..f753643
--- /dev/null
+++ b/Python-2.7.5/Objects/listobject.c
@@ -0,0 +1,3044 @@
+/* List object implementation */
+
+#include "Python.h"
+
+#ifdef STDC_HEADERS
+#include <stddef.h>
+#else
+#include <sys/types.h>          /* For size_t */
+#endif
+
+/* Ensure ob_item has room for at least newsize elements, and set
+ * ob_size to newsize.  If newsize > ob_size on entry, the content
+ * of the new slots at exit is undefined heap trash; it's the caller's
+ * responsibility to overwrite them with sane values.
+ * The number of allocated elements may grow, shrink, or stay the same.
+ * Failure is impossible if newsize <= self.allocated on entry, although
+ * that partly relies on an assumption that the system realloc() never
+ * fails when passed a number of bytes <= the number of bytes last
+ * allocated (the C standard doesn't guarantee this, but it's hard to
+ * imagine a realloc implementation where it wouldn't be true).
+ * Note that self->ob_item may change, and even if newsize is less
+ * than ob_size on entry.
+ */
+static int
+list_resize(PyListObject *self, Py_ssize_t newsize)
+{
+    PyObject **items;
+    size_t new_allocated;
+    Py_ssize_t allocated = self->allocated;
+
+    /* Bypass realloc() when a previous overallocation is large enough
+       to accommodate the newsize.  If the newsize falls lower than half
+       the allocated size, then proceed with the realloc() to shrink the list.
+    */
+    if (allocated >= newsize && newsize >= (allocated >> 1)) {
+        assert(self->ob_item != NULL || newsize == 0);
+        Py_SIZE(self) = newsize;
+        return 0;
+    }
+
+    /* This over-allocates proportional to the list size, making room
+     * for additional growth.  The over-allocation is mild, but is
+     * enough to give linear-time amortized behavior over a long
+     * sequence of appends() in the presence of a poorly-performing
+     * system realloc().
+     * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
+     */
+    new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
+
+    /* check for integer overflow */
+    if (new_allocated > PY_SIZE_MAX - newsize) {
+        PyErr_NoMemory();
+        return -1;
+    } else {
+        new_allocated += newsize;
+    }
+
+    if (newsize == 0)
+        new_allocated = 0;
+    items = self->ob_item;
+    if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *)))
+        PyMem_RESIZE(items, PyObject *, new_allocated);
+    else
+        items = NULL;
+    if (items == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    self->ob_item = items;
+    Py_SIZE(self) = newsize;
+    self->allocated = new_allocated;
+    return 0;
+}
+
+/* Debug statistic to compare allocations with reuse through the free list */
+#undef SHOW_ALLOC_COUNT
+#ifdef SHOW_ALLOC_COUNT
+static size_t count_alloc = 0;
+static size_t count_reuse = 0;
+
+static void
+show_alloc(void)
+{
+    fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n",
+        count_alloc);
+    fprintf(stderr, "List reuse through freelist: %" PY_FORMAT_SIZE_T
+        "d\n", count_reuse);
+    fprintf(stderr, "%.2f%% reuse rate\n\n",
+        (100.0*count_reuse/(count_alloc+count_reuse)));
+}
+#endif
+
+/* Empty list reuse scheme to save calls to malloc and free */
+#ifndef PyList_MAXFREELIST
+#define PyList_MAXFREELIST 80
+#endif
+static PyListObject *free_list[PyList_MAXFREELIST];
+static int numfree = 0;
+
+void
+PyList_Fini(void)
+{
+    PyListObject *op;
+
+    while (numfree) {
+        op = free_list[--numfree];
+        assert(PyList_CheckExact(op));
+        PyObject_GC_Del(op);
+    }
+}
+
+PyObject *
+PyList_New(Py_ssize_t size)
+{
+    PyListObject *op;
+    size_t nbytes;
+#ifdef SHOW_ALLOC_COUNT
+    static int initialized = 0;
+    if (!initialized) {
+        Py_AtExit(show_alloc);
+        initialized = 1;
+    }
+#endif
+
+    if (size < 0) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    /* Check for overflow without an actual overflow,
+     *  which can cause compiler to optimise out */
+    if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *))
+        return PyErr_NoMemory();
+    nbytes = size * sizeof(PyObject *);
+    if (numfree) {
+        numfree--;
+        op = free_list[numfree];
+        _Py_NewReference((PyObject *)op);
+#ifdef SHOW_ALLOC_COUNT
+        count_reuse++;
+#endif
+    } else {
+        op = PyObject_GC_New(PyListObject, &PyList_Type);
+        if (op == NULL)
+            return NULL;
+#ifdef SHOW_ALLOC_COUNT
+        count_alloc++;
+#endif
+    }
+    if (size <= 0)
+        op->ob_item = NULL;
+    else {
+        op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);
+        if (op->ob_item == NULL) {
+            Py_DECREF(op);
+            return PyErr_NoMemory();
+        }
+        memset(op->ob_item, 0, nbytes);
+    }
+    Py_SIZE(op) = size;
+    op->allocated = size;
+    _PyObject_GC_TRACK(op);
+    return (PyObject *) op;
+}
+
+Py_ssize_t
+PyList_Size(PyObject *op)
+{
+    if (!PyList_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    else
+        return Py_SIZE(op);
+}
+
+static PyObject *indexerr = NULL;
+
+PyObject *
+PyList_GetItem(PyObject *op, Py_ssize_t i)
+{
+    if (!PyList_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    if (i < 0 || i >= Py_SIZE(op)) {
+        if (indexerr == NULL) {
+            indexerr = PyString_FromString(
+                "list index out of range");
+            if (indexerr == NULL)
+                return NULL;
+        }
+        PyErr_SetObject(PyExc_IndexError, indexerr);
+        return NULL;
+    }
+    return ((PyListObject *)op) -> ob_item[i];
+}
+
+int
+PyList_SetItem(register PyObject *op, register Py_ssize_t i,
+               register PyObject *newitem)
+{
+    register PyObject *olditem;
+    register PyObject **p;
+    if (!PyList_Check(op)) {
+        Py_XDECREF(newitem);
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (i < 0 || i >= Py_SIZE(op)) {
+        Py_XDECREF(newitem);
+        PyErr_SetString(PyExc_IndexError,
+                        "list assignment index out of range");
+        return -1;
+    }
+    p = ((PyListObject *)op) -> ob_item + i;
+    olditem = *p;
+    *p = newitem;
+    Py_XDECREF(olditem);
+    return 0;
+}
+
+static int
+ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
+{
+    Py_ssize_t i, n = Py_SIZE(self);
+    PyObject **items;
+    if (v == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (n == PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+            "cannot add more objects to list");
+        return -1;
+    }
+
+    if (list_resize(self, n+1) == -1)
+        return -1;
+
+    if (where < 0) {
+        where += n;
+        if (where < 0)
+            where = 0;
+    }
+    if (where > n)
+        where = n;
+    items = self->ob_item;
+    for (i = n; --i >= where; )
+        items[i+1] = items[i];
+    Py_INCREF(v);
+    items[where] = v;
+    return 0;
+}
+
+int
+PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
+{
+    if (!PyList_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return ins1((PyListObject *)op, where, newitem);
+}
+
+static int
+app1(PyListObject *self, PyObject *v)
+{
+    Py_ssize_t n = PyList_GET_SIZE(self);
+
+    assert (v != NULL);
+    if (n == PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+            "cannot add more objects to list");
+        return -1;
+    }
+
+    if (list_resize(self, n+1) == -1)
+        return -1;
+
+    Py_INCREF(v);
+    PyList_SET_ITEM(self, n, v);
+    return 0;
+}
+
+int
+PyList_Append(PyObject *op, PyObject *newitem)
+{
+    if (PyList_Check(op) && (newitem != NULL))
+        return app1((PyListObject *)op, newitem);
+    PyErr_BadInternalCall();
+    return -1;
+}
+
+/* Methods */
+
+static void
+list_dealloc(PyListObject *op)
+{
+    Py_ssize_t i;
+    PyObject_GC_UnTrack(op);
+    Py_TRASHCAN_SAFE_BEGIN(op)
+    if (op->ob_item != NULL) {
+        /* Do it backwards, for Christian Tismer.
+           There's a simple test case where somehow this reduces
+           thrashing when a *very* large list is created and
+           immediately deleted. */
+        i = Py_SIZE(op);
+        while (--i >= 0) {
+            Py_XDECREF(op->ob_item[i]);
+        }
+        PyMem_FREE(op->ob_item);
+    }
+    if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))
+        free_list[numfree++] = op;
+    else
+        Py_TYPE(op)->tp_free((PyObject *)op);
+    Py_TRASHCAN_SAFE_END(op)
+}
+
+static int
+list_print(PyListObject *op, FILE *fp, int flags)
+{
+    int rc;
+    Py_ssize_t i;
+    PyObject *item;
+
+    rc = Py_ReprEnter((PyObject*)op);
+    if (rc != 0) {
+        if (rc < 0)
+            return rc;
+        Py_BEGIN_ALLOW_THREADS
+        fprintf(fp, "[...]");
+        Py_END_ALLOW_THREADS
+        return 0;
+    }
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "[");
+    Py_END_ALLOW_THREADS
+    for (i = 0; i < Py_SIZE(op); i++) {
+        item = op->ob_item[i];
+        Py_INCREF(item);
+        if (i > 0) {
+            Py_BEGIN_ALLOW_THREADS
+            fprintf(fp, ", ");
+            Py_END_ALLOW_THREADS
+        }
+        if (PyObject_Print(item, fp, 0) != 0) {
+            Py_DECREF(item);
+            Py_ReprLeave((PyObject *)op);
+            return -1;
+        }
+        Py_DECREF(item);
+    }
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "]");
+    Py_END_ALLOW_THREADS
+    Py_ReprLeave((PyObject *)op);
+    return 0;
+}
+
+static PyObject *
+list_repr(PyListObject *v)
+{
+    Py_ssize_t i;
+    PyObject *s, *temp;
+    PyObject *pieces = NULL, *result = NULL;
+
+    i = Py_ReprEnter((PyObject*)v);
+    if (i != 0) {
+        return i > 0 ? PyString_FromString("[...]") : NULL;
+    }
+
+    if (Py_SIZE(v) == 0) {
+        result = PyString_FromString("[]");
+        goto Done;
+    }
+
+    pieces = PyList_New(0);
+    if (pieces == NULL)
+        goto Done;
+
+    /* Do repr() on each element.  Note that this may mutate the list,
+       so must refetch the list size on each iteration. */
+    for (i = 0; i < Py_SIZE(v); ++i) {
+        int status;
+        if (Py_EnterRecursiveCall(" while getting the repr of a list"))
+            goto Done;
+        s = PyObject_Repr(v->ob_item[i]);
+        Py_LeaveRecursiveCall();
+        if (s == NULL)
+            goto Done;
+        status = PyList_Append(pieces, s);
+        Py_DECREF(s);  /* append created a new ref */
+        if (status < 0)
+            goto Done;
+    }
+
+    /* Add "[]" decorations to the first and last items. */
+    assert(PyList_GET_SIZE(pieces) > 0);
+    s = PyString_FromString("[");
+    if (s == NULL)
+        goto Done;
+    temp = PyList_GET_ITEM(pieces, 0);
+    PyString_ConcatAndDel(&s, temp);
+    PyList_SET_ITEM(pieces, 0, s);
+    if (s == NULL)
+        goto Done;
+
+    s = PyString_FromString("]");
+    if (s == NULL)
+        goto Done;
+    temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
+    PyString_ConcatAndDel(&temp, s);
+    PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
+    if (temp == NULL)
+        goto Done;
+
+    /* Paste them all together with ", " between. */
+    s = PyString_FromString(", ");
+    if (s == NULL)
+        goto Done;
+    result = _PyString_Join(s, pieces);
+    Py_DECREF(s);
+
+Done:
+    Py_XDECREF(pieces);
+    Py_ReprLeave((PyObject *)v);
+    return result;
+}
+
+static Py_ssize_t
+list_length(PyListObject *a)
+{
+    return Py_SIZE(a);
+}
+
+static int
+list_contains(PyListObject *a, PyObject *el)
+{
+    Py_ssize_t i;
+    int cmp;
+
+    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
+        cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
+                                           Py_EQ);
+    return cmp;
+}
+
+static PyObject *
+list_item(PyListObject *a, Py_ssize_t i)
+{
+    if (i < 0 || i >= Py_SIZE(a)) {
+        if (indexerr == NULL) {
+            indexerr = PyString_FromString(
+                "list index out of range");
+            if (indexerr == NULL)
+                return NULL;
+        }
+        PyErr_SetObject(PyExc_IndexError, indexerr);
+        return NULL;
+    }
+    Py_INCREF(a->ob_item[i]);
+    return a->ob_item[i];
+}
+
+static PyObject *
+list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+    PyListObject *np;
+    PyObject **src, **dest;
+    Py_ssize_t i, len;
+    if (ilow < 0)
+        ilow = 0;
+    else if (ilow > Py_SIZE(a))
+        ilow = Py_SIZE(a);
+    if (ihigh < ilow)
+        ihigh = ilow;
+    else if (ihigh > Py_SIZE(a))
+        ihigh = Py_SIZE(a);
+    len = ihigh - ilow;
+    np = (PyListObject *) PyList_New(len);
+    if (np == NULL)
+        return NULL;
+
+    src = a->ob_item + ilow;
+    dest = np->ob_item;
+    for (i = 0; i < len; i++) {
+        PyObject *v = src[i];
+        Py_INCREF(v);
+        dest[i] = v;
+    }
+    return (PyObject *)np;
+}
+
+PyObject *
+PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+    if (!PyList_Check(a)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return list_slice((PyListObject *)a, ilow, ihigh);
+}
+
+static PyObject *
+list_concat(PyListObject *a, PyObject *bb)
+{
+    Py_ssize_t size;
+    Py_ssize_t i;
+    PyObject **src, **dest;
+    PyListObject *np;
+    if (!PyList_Check(bb)) {
+        PyErr_Format(PyExc_TypeError,
+                  "can only concatenate list (not \"%.200s\") to list",
+                  bb->ob_type->tp_name);
+        return NULL;
+    }
+#define b ((PyListObject *)bb)
+    size = Py_SIZE(a) + Py_SIZE(b);
+    if (size < 0)
+        return PyErr_NoMemory();
+    np = (PyListObject *) PyList_New(size);
+    if (np == NULL) {
+        return NULL;
+    }
+    src = a->ob_item;
+    dest = np->ob_item;
+    for (i = 0; i < Py_SIZE(a); i++) {
+        PyObject *v = src[i];
+        Py_INCREF(v);
+        dest[i] = v;
+    }
+    src = b->ob_item;
+    dest = np->ob_item + Py_SIZE(a);
+    for (i = 0; i < Py_SIZE(b); i++) {
+        PyObject *v = src[i];
+        Py_INCREF(v);
+        dest[i] = v;
+    }
+    return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+list_repeat(PyListObject *a, Py_ssize_t n)
+{
+    Py_ssize_t i, j;
+    Py_ssize_t size;
+    PyListObject *np;
+    PyObject **p, **items;
+    PyObject *elem;
+    if (n < 0)
+        n = 0;
+    if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n)
+        return PyErr_NoMemory();
+    size = Py_SIZE(a) * n;
+    if (size == 0)
+        return PyList_New(0);
+    np = (PyListObject *) PyList_New(size);
+    if (np == NULL)
+        return NULL;
+
+    items = np->ob_item;
+    if (Py_SIZE(a) == 1) {
+        elem = a->ob_item[0];
+        for (i = 0; i < n; i++) {
+            items[i] = elem;
+            Py_INCREF(elem);
+        }
+        return (PyObject *) np;
+    }
+    p = np->ob_item;
+    items = a->ob_item;
+    for (i = 0; i < n; i++) {
+        for (j = 0; j < Py_SIZE(a); j++) {
+            *p = items[j];
+            Py_INCREF(*p);
+            p++;
+        }
+    }
+    return (PyObject *) np;
+}
+
+static int
+list_clear(PyListObject *a)
+{
+    Py_ssize_t i;
+    PyObject **item = a->ob_item;
+    if (item != NULL) {
+        /* Because XDECREF can recursively invoke operations on
+           this list, we make it empty first. */
+        i = Py_SIZE(a);
+        Py_SIZE(a) = 0;
+        a->ob_item = NULL;
+        a->allocated = 0;
+        while (--i >= 0) {
+            Py_XDECREF(item[i]);
+        }
+        PyMem_FREE(item);
+    }
+    /* Never fails; the return value can be ignored.
+       Note that there is no guarantee that the list is actually empty
+       at this point, because XDECREF may have populated it again! */
+    return 0;
+}
+
+/* a[ilow:ihigh] = v if v != NULL.
+ * del a[ilow:ihigh] if v == NULL.
+ *
+ * Special speed gimmick:  when v is NULL and ihigh - ilow <= 8, it's
+ * guaranteed the call cannot fail.
+ */
+static int
+list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+    /* Because [X]DECREF can recursively invoke list operations on
+       this list, we must postpone all [X]DECREF activity until
+       after the list is back in its canonical shape.  Therefore
+       we must allocate an additional array, 'recycle', into which
+       we temporarily copy the items that are deleted from the
+       list. :-( */
+    PyObject *recycle_on_stack[8];
+    PyObject **recycle = recycle_on_stack; /* will allocate more if needed */
+    PyObject **item;
+    PyObject **vitem = NULL;
+    PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
+    Py_ssize_t n; /* # of elements in replacement list */
+    Py_ssize_t norig; /* # of elements in list getting replaced */
+    Py_ssize_t d; /* Change in size */
+    Py_ssize_t k;
+    size_t s;
+    int result = -1;            /* guilty until proved innocent */
+#define b ((PyListObject *)v)
+    if (v == NULL)
+        n = 0;
+    else {
+        if (a == b) {
+            /* Special case "a[i:j] = a" -- copy b first */
+            v = list_slice(b, 0, Py_SIZE(b));
+            if (v == NULL)
+                return result;
+            result = list_ass_slice(a, ilow, ihigh, v);
+            Py_DECREF(v);
+            return result;
+        }
+        v_as_SF = PySequence_Fast(v, "can only assign an iterable");
+        if(v_as_SF == NULL)
+            goto Error;
+        n = PySequence_Fast_GET_SIZE(v_as_SF);
+        vitem = PySequence_Fast_ITEMS(v_as_SF);
+    }
+    if (ilow < 0)
+        ilow = 0;
+    else if (ilow > Py_SIZE(a))
+        ilow = Py_SIZE(a);
+
+    if (ihigh < ilow)
+        ihigh = ilow;
+    else if (ihigh > Py_SIZE(a))
+        ihigh = Py_SIZE(a);
+
+    norig = ihigh - ilow;
+    assert(norig >= 0);
+    d = n - norig;
+    if (Py_SIZE(a) + d == 0) {
+        Py_XDECREF(v_as_SF);
+        return list_clear(a);
+    }
+    item = a->ob_item;
+    /* recycle the items that we are about to remove */
+    s = norig * sizeof(PyObject *);
+    if (s > sizeof(recycle_on_stack)) {
+        recycle = (PyObject **)PyMem_MALLOC(s);
+        if (recycle == NULL) {
+            PyErr_NoMemory();
+            goto Error;
+        }
+    }
+    memcpy(recycle, &item[ilow], s);
+
+    if (d < 0) { /* Delete -d items */
+        memmove(&item[ihigh+d], &item[ihigh],
+            (Py_SIZE(a) - ihigh)*sizeof(PyObject *));
+        list_resize(a, Py_SIZE(a) + d);
+        item = a->ob_item;
+    }
+    else if (d > 0) { /* Insert d items */
+        k = Py_SIZE(a);
+        if (list_resize(a, k+d) < 0)
+            goto Error;
+        item = a->ob_item;
+        memmove(&item[ihigh+d], &item[ihigh],
+            (k - ihigh)*sizeof(PyObject *));
+    }
+    for (k = 0; k < n; k++, ilow++) {
+        PyObject *w = vitem[k];
+        Py_XINCREF(w);
+        item[ilow] = w;
+    }
+    for (k = norig - 1; k >= 0; --k)
+        Py_XDECREF(recycle[k]);
+    result = 0;
+ Error:
+    if (recycle != recycle_on_stack)
+        PyMem_FREE(recycle);
+    Py_XDECREF(v_as_SF);
+    return result;
+#undef b
+}
+
+int
+PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+    if (!PyList_Check(a)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return list_ass_slice((PyListObject *)a, ilow, ihigh, v);
+}
+
+static PyObject *
+list_inplace_repeat(PyListObject *self, Py_ssize_t n)
+{
+    PyObject **items;
+    Py_ssize_t size, i, j, p;
+
+
+    size = PyList_GET_SIZE(self);
+    if (size == 0 || n == 1) {
+        Py_INCREF(self);
+        return (PyObject *)self;
+    }
+
+    if (n < 1) {
+        (void)list_clear(self);
+        Py_INCREF(self);
+        return (PyObject *)self;
+    }
+
+    if (size > PY_SSIZE_T_MAX / n) {
+        return PyErr_NoMemory();
+    }
+
+    if (list_resize(self, size*n) == -1)
+        return NULL;
+
+    p = size;
+    items = self->ob_item;
+    for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */
+        for (j = 0; j < size; j++) {
+            PyObject *o = items[j];
+            Py_INCREF(o);
+            items[p++] = o;
+        }
+    }
+    Py_INCREF(self);
+    return (PyObject *)self;
+}
+
+static int
+list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
+{
+    PyObject *old_value;
+    if (i < 0 || i >= Py_SIZE(a)) {
+        PyErr_SetString(PyExc_IndexError,
+                        "list assignment index out of range");
+        return -1;
+    }
+    if (v == NULL)
+        return list_ass_slice(a, i, i+1, v);
+    Py_INCREF(v);
+    old_value = a->ob_item[i];
+    a->ob_item[i] = v;
+    Py_DECREF(old_value);
+    return 0;
+}
+
+static PyObject *
+listinsert(PyListObject *self, PyObject *args)
+{
+    Py_ssize_t i;
+    PyObject *v;
+    if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
+        return NULL;
+    if (ins1(self, i, v) == 0)
+        Py_RETURN_NONE;
+    return NULL;
+}
+
+static PyObject *
+listappend(PyListObject *self, PyObject *v)
+{
+    if (app1(self, v) == 0)
+        Py_RETURN_NONE;
+    return NULL;
+}
+
+static PyObject *
+listextend(PyListObject *self, PyObject *b)
+{
+    PyObject *it;      /* iter(v) */
+    Py_ssize_t m;                  /* size of self */
+    Py_ssize_t n;                  /* guess for size of b */
+    Py_ssize_t mn;                 /* m + n */
+    Py_ssize_t i;
+    PyObject *(*iternext)(PyObject *);
+
+    /* Special cases:
+       1) lists and tuples which can use PySequence_Fast ops
+       2) extending self to self requires making a copy first
+    */
+    if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {
+        PyObject **src, **dest;
+        b = PySequence_Fast(b, "argument must be iterable");
+        if (!b)
+            return NULL;
+        n = PySequence_Fast_GET_SIZE(b);
+        if (n == 0) {
+            /* short circuit when b is empty */
+            Py_DECREF(b);
+            Py_RETURN_NONE;
+        }
+        m = Py_SIZE(self);
+        if (list_resize(self, m + n) == -1) {
+            Py_DECREF(b);
+            return NULL;
+        }
+        /* note that we may still have self == b here for the
+         * situation a.extend(a), but the following code works
+         * in that case too.  Just make sure to resize self
+         * before calling PySequence_Fast_ITEMS.
+         */
+        /* populate the end of self with b's items */
+        src = PySequence_Fast_ITEMS(b);
+        dest = self->ob_item + m;
+        for (i = 0; i < n; i++) {
+            PyObject *o = src[i];
+            Py_INCREF(o);
+            dest[i] = o;
+        }
+        Py_DECREF(b);
+        Py_RETURN_NONE;
+    }
+
+    it = PyObject_GetIter(b);
+    if (it == NULL)
+        return NULL;
+    iternext = *it->ob_type->tp_iternext;
+
+    /* Guess a result list size. */
+    n = _PyObject_LengthHint(b, 8);
+    if (n == -1) {
+        Py_DECREF(it);
+        return NULL;
+    }
+    m = Py_SIZE(self);
+    mn = m + n;
+    if (mn >= m) {
+        /* Make room. */
+        if (list_resize(self, mn) == -1)
+            goto error;
+        /* Make the list sane again. */
+        Py_SIZE(self) = m;
+    }
+    /* Else m + n overflowed; on the chance that n lied, and there really
+     * is enough room, ignore it.  If n was telling the truth, we'll
+     * eventually run out of memory during the loop.
+     */
+
+    /* Run iterator to exhaustion. */
+    for (;;) {
+        PyObject *item = iternext(it);
+        if (item == NULL) {
+            if (PyErr_Occurred()) {
+                if (PyErr_ExceptionMatches(PyExc_StopIteration))
+                    PyErr_Clear();
+                else
+                    goto error;
+            }
+            break;
+        }
+        if (Py_SIZE(self) < self->allocated) {
+            /* steals ref */
+            PyList_SET_ITEM(self, Py_SIZE(self), item);
+            ++Py_SIZE(self);
+        }
+        else {
+            int status = app1(self, item);
+            Py_DECREF(item);  /* append creates a new ref */
+            if (status < 0)
+                goto error;
+        }
+    }
+
+    /* Cut back result list if initial guess was too large. */
+    if (Py_SIZE(self) < self->allocated)
+        list_resize(self, Py_SIZE(self));  /* shrinking can't fail */
+
+    Py_DECREF(it);
+    Py_RETURN_NONE;
+
+  error:
+    Py_DECREF(it);
+    return NULL;
+}
+
+PyObject *
+_PyList_Extend(PyListObject *self, PyObject *b)
+{
+    return listextend(self, b);
+}
+
+static PyObject *
+list_inplace_concat(PyListObject *self, PyObject *other)
+{
+    PyObject *result;
+
+    result = listextend(self, other);
+    if (result == NULL)
+        return result;
+    Py_DECREF(result);
+    Py_INCREF(self);
+    return (PyObject *)self;
+}
+
+static PyObject *
+listpop(PyListObject *self, PyObject *args)
+{
+    Py_ssize_t i = -1;
+    PyObject *v;
+    int status;
+
+    if (!PyArg_ParseTuple(args, "|n:pop", &i))
+        return NULL;
+
+    if (Py_SIZE(self) == 0) {
+        /* Special-case most common failure cause */
+        PyErr_SetString(PyExc_IndexError, "pop from empty list");
+        return NULL;
+    }
+    if (i < 0)
+        i += Py_SIZE(self);
+    if (i < 0 || i >= Py_SIZE(self)) {
+        PyErr_SetString(PyExc_IndexError, "pop index out of range");
+        return NULL;
+    }
+    v = self->ob_item[i];
+    if (i == Py_SIZE(self) - 1) {
+        status = list_resize(self, Py_SIZE(self) - 1);
+        assert(status >= 0);
+        return v; /* and v now owns the reference the list had */
+    }
+    Py_INCREF(v);
+    status = list_ass_slice(self, i, i+1, (PyObject *)NULL);
+    assert(status >= 0);
+    /* Use status, so that in a release build compilers don't
+     * complain about the unused name.
+     */
+    (void) status;
+
+    return v;
+}
+
+/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
+static void
+reverse_slice(PyObject **lo, PyObject **hi)
+{
+    assert(lo && hi);
+
+    --hi;
+    while (lo < hi) {
+        PyObject *t = *lo;
+        *lo = *hi;
+        *hi = t;
+        ++lo;
+        --hi;
+    }
+}
+
+/* Lots of code for an adaptive, stable, natural mergesort.  There are many
+ * pieces to this algorithm; read listsort.txt for overviews and details.
+ */
+
+/* Comparison function.  Takes care of calling a user-supplied
+ * comparison function (any callable Python object), which must not be
+ * NULL (use the ISLT macro if you don't know, or call PyObject_RichCompareBool
+ * with Py_LT if you know it's NULL).
+ * Returns -1 on error, 1 if x < y, 0 if x >= y.
+ */
+static int
+islt(PyObject *x, PyObject *y, PyObject *compare)
+{
+    PyObject *res;
+    PyObject *args;
+    Py_ssize_t i;
+
+    assert(compare != NULL);
+    /* Call the user's comparison function and translate the 3-way
+     * result into true or false (or error).
+     */
+    args = PyTuple_New(2);
+    if (args == NULL)
+        return -1;
+    Py_INCREF(x);
+    Py_INCREF(y);
+    PyTuple_SET_ITEM(args, 0, x);
+    PyTuple_SET_ITEM(args, 1, y);
+    res = PyObject_Call(compare, args, NULL);
+    Py_DECREF(args);
+    if (res == NULL)
+        return -1;
+    if (!PyInt_Check(res)) {
+        PyErr_Format(PyExc_TypeError,
+                     "comparison function must return int, not %.200s",
+                     res->ob_type->tp_name);
+        Py_DECREF(res);
+        return -1;
+    }
+    i = PyInt_AsLong(res);
+    Py_DECREF(res);
+    return i < 0;
+}
+
+/* If COMPARE is NULL, calls PyObject_RichCompareBool with Py_LT, else calls
+ * islt.  This avoids a layer of function call in the usual case, and
+ * sorting does many comparisons.
+ * Returns -1 on error, 1 if x < y, 0 if x >= y.
+ */
+#define ISLT(X, Y, COMPARE) ((COMPARE) == NULL ?                        \
+                 PyObject_RichCompareBool(X, Y, Py_LT) :                \
+                 islt(X, Y, COMPARE))
+
+/* Compare X to Y via "<".  Goto "fail" if the comparison raises an
+   error.  Else "k" is set to true iff X<Y, and an "if (k)" block is
+   started.  It makes more sense in context <wink>.  X and Y are PyObject*s.
+*/
+#define IFLT(X, Y) if ((k = ISLT(X, Y, compare)) < 0) goto fail;  \
+           if (k)
+
+/* binarysort is the best method for sorting small arrays: it does
+   few compares, but can do data movement quadratic in the number of
+   elements.
+   [lo, hi) is a contiguous slice of a list, and is sorted via
+   binary insertion.  This sort is stable.
+   On entry, must have lo <= start <= hi, and that [lo, start) is already
+   sorted (pass start == lo if you don't know!).
+   If islt() complains return -1, else 0.
+   Even in case of error, the output slice will be some permutation of
+   the input (nothing is lost or duplicated).
+*/
+static int
+binarysort(PyObject **lo, PyObject **hi, PyObject **start, PyObject *compare)
+     /* compare -- comparison function object, or NULL for default */
+{
+    register Py_ssize_t k;
+    register PyObject **l, **p, **r;
+    register PyObject *pivot;
+
+    assert(lo <= start && start <= hi);
+    /* assert [lo, start) is sorted */
+    if (lo == start)
+        ++start;
+    for (; start < hi; ++start) {
+        /* set l to where *start belongs */
+        l = lo;
+        r = start;
+        pivot = *r;
+        /* Invariants:
+         * pivot >= all in [lo, l).
+         * pivot  < all in [r, start).
+         * The second is vacuously true at the start.
+         */
+        assert(l < r);
+        do {
+            p = l + ((r - l) >> 1);
+            IFLT(pivot, *p)
+                r = p;
+            else
+                l = p+1;
+        } while (l < r);
+        assert(l == r);
+        /* The invariants still hold, so pivot >= all in [lo, l) and
+           pivot < all in [l, start), so pivot belongs at l.  Note
+           that if there are elements equal to pivot, l points to the
+           first slot after them -- that's why this sort is stable.
+           Slide over to make room.
+           Caution: using memmove is much slower under MSVC 5;
+           we're not usually moving many slots. */
+        for (p = start; p > l; --p)
+            *p = *(p-1);
+        *l = pivot;
+    }
+    return 0;
+
+ fail:
+    return -1;
+}
+
+/*
+Return the length of the run beginning at lo, in the slice [lo, hi).  lo < hi
+is required on entry.  "A run" is the longest ascending sequence, with
+
+    lo[0] <= lo[1] <= lo[2] <= ...
+
+or the longest descending sequence, with
+
+    lo[0] > lo[1] > lo[2] > ...
+
+Boolean *descending is set to 0 in the former case, or to 1 in the latter.
+For its intended use in a stable mergesort, the strictness of the defn of
+"descending" is needed so that the caller can safely reverse a descending
+sequence without violating stability (strict > ensures there are no equal
+elements to get out of order).
+
+Returns -1 in case of error.
+*/
+static Py_ssize_t
+count_run(PyObject **lo, PyObject **hi, PyObject *compare, int *descending)
+{
+    Py_ssize_t k;
+    Py_ssize_t n;
+
+    assert(lo < hi);
+    *descending = 0;
+    ++lo;
+    if (lo == hi)
+        return 1;
+
+    n = 2;
+    IFLT(*lo, *(lo-1)) {
+        *descending = 1;
+        for (lo = lo+1; lo < hi; ++lo, ++n) {
+            IFLT(*lo, *(lo-1))
+                ;
+            else
+                break;
+        }
+    }
+    else {
+        for (lo = lo+1; lo < hi; ++lo, ++n) {
+            IFLT(*lo, *(lo-1))
+                break;
+        }
+    }
+
+    return n;
+fail:
+    return -1;
+}
+
+/*
+Locate the proper position of key in a sorted vector; if the vector contains
+an element equal to key, return the position immediately to the left of
+the leftmost equal element.  [gallop_right() does the same except returns
+the position to the right of the rightmost equal element (if any).]
+
+"a" is a sorted vector with n elements, starting at a[0].  n must be > 0.
+
+"hint" is an index at which to begin the search, 0 <= hint < n.  The closer
+hint is to the final result, the faster this runs.
+
+The return value is the int k in 0..n such that
+
+    a[k-1] < key <= a[k]
+
+pretending that *(a-1) is minus infinity and a[n] is plus infinity.  IOW,
+key belongs at index k; or, IOW, the first k elements of a should precede
+key, and the last n-k should follow key.
+
+Returns -1 on error.  See listsort.txt for info on the method.
+*/
+static Py_ssize_t
+gallop_left(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)
+{
+    Py_ssize_t ofs;
+    Py_ssize_t lastofs;
+    Py_ssize_t k;
+
+    assert(key && a && n > 0 && hint >= 0 && hint < n);
+
+    a += hint;
+    lastofs = 0;
+    ofs = 1;
+    IFLT(*a, key) {
+        /* a[hint] < key -- gallop right, until
+         * a[hint + lastofs] < key <= a[hint + ofs]
+         */
+        const Py_ssize_t maxofs = n - hint;             /* &a[n-1] is highest */
+        while (ofs < maxofs) {
+            IFLT(a[ofs], key) {
+                lastofs = ofs;
+                ofs = (ofs << 1) + 1;
+                if (ofs <= 0)                   /* int overflow */
+                    ofs = maxofs;
+            }
+            else                /* key <= a[hint + ofs] */
+                break;
+        }
+        if (ofs > maxofs)
+            ofs = maxofs;
+        /* Translate back to offsets relative to &a[0]. */
+        lastofs += hint;
+        ofs += hint;
+    }
+    else {
+        /* key <= a[hint] -- gallop left, until
+         * a[hint - ofs] < key <= a[hint - lastofs]
+         */
+        const Py_ssize_t maxofs = hint + 1;             /* &a[0] is lowest */
+        while (ofs < maxofs) {
+            IFLT(*(a-ofs), key)
+                break;
+            /* key <= a[hint - ofs] */
+            lastofs = ofs;
+            ofs = (ofs << 1) + 1;
+            if (ofs <= 0)               /* int overflow */
+                ofs = maxofs;
+        }
+        if (ofs > maxofs)
+            ofs = maxofs;
+        /* Translate back to positive offsets relative to &a[0]. */
+        k = lastofs;
+        lastofs = hint - ofs;
+        ofs = hint - k;
+    }
+    a -= hint;
+
+    assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
+    /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
+     * right of lastofs but no farther right than ofs.  Do a binary
+     * search, with invariant a[lastofs-1] < key <= a[ofs].
+     */
+    ++lastofs;
+    while (lastofs < ofs) {
+        Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
+
+        IFLT(a[m], key)
+            lastofs = m+1;              /* a[m] < key */
+        else
+            ofs = m;                    /* key <= a[m] */
+    }
+    assert(lastofs == ofs);             /* so a[ofs-1] < key <= a[ofs] */
+    return ofs;
+
+fail:
+    return -1;
+}
+
+/*
+Exactly like gallop_left(), except that if key already exists in a[0:n],
+finds the position immediately to the right of the rightmost equal value.
+
+The return value is the int k in 0..n such that
+
+    a[k-1] <= key < a[k]
+
+or -1 if error.
+
+The code duplication is massive, but this is enough different given that
+we're sticking to "<" comparisons that it's much harder to follow if
+written as one routine with yet another "left or right?" flag.
+*/
+static Py_ssize_t
+gallop_right(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)
+{
+    Py_ssize_t ofs;
+    Py_ssize_t lastofs;
+    Py_ssize_t k;
+
+    assert(key && a && n > 0 && hint >= 0 && hint < n);
+
+    a += hint;
+    lastofs = 0;
+    ofs = 1;
+    IFLT(key, *a) {
+        /* key < a[hint] -- gallop left, until
+         * a[hint - ofs] <= key < a[hint - lastofs]
+         */
+        const Py_ssize_t maxofs = hint + 1;             /* &a[0] is lowest */
+        while (ofs < maxofs) {
+            IFLT(key, *(a-ofs)) {
+                lastofs = ofs;
+                ofs = (ofs << 1) + 1;
+                if (ofs <= 0)                   /* int overflow */
+                    ofs = maxofs;
+            }
+            else                /* a[hint - ofs] <= key */
+                break;
+        }
+        if (ofs > maxofs)
+            ofs = maxofs;
+        /* Translate back to positive offsets relative to &a[0]. */
+        k = lastofs;
+        lastofs = hint - ofs;
+        ofs = hint - k;
+    }
+    else {
+        /* a[hint] <= key -- gallop right, until
+         * a[hint + lastofs] <= key < a[hint + ofs]
+        */
+        const Py_ssize_t maxofs = n - hint;             /* &a[n-1] is highest */
+        while (ofs < maxofs) {
+            IFLT(key, a[ofs])
+                break;
+            /* a[hint + ofs] <= key */
+            lastofs = ofs;
+            ofs = (ofs << 1) + 1;
+            if (ofs <= 0)               /* int overflow */
+                ofs = maxofs;
+        }
+        if (ofs > maxofs)
+            ofs = maxofs;
+        /* Translate back to offsets relative to &a[0]. */
+        lastofs += hint;
+        ofs += hint;
+    }
+    a -= hint;
+
+    assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
+    /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
+     * right of lastofs but no farther right than ofs.  Do a binary
+     * search, with invariant a[lastofs-1] <= key < a[ofs].
+     */
+    ++lastofs;
+    while (lastofs < ofs) {
+        Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
+
+        IFLT(key, a[m])
+            ofs = m;                    /* key < a[m] */
+        else
+            lastofs = m+1;              /* a[m] <= key */
+    }
+    assert(lastofs == ofs);             /* so a[ofs-1] <= key < a[ofs] */
+    return ofs;
+
+fail:
+    return -1;
+}
+
+/* The maximum number of entries in a MergeState's pending-runs stack.
+ * This is enough to sort arrays of size up to about
+ *     32 * phi ** MAX_MERGE_PENDING
+ * where phi ~= 1.618.  85 is ridiculouslylarge enough, good for an array
+ * with 2**64 elements.
+ */
+#define MAX_MERGE_PENDING 85
+
+/* When we get into galloping mode, we stay there until both runs win less
+ * often than MIN_GALLOP consecutive times.  See listsort.txt for more info.
+ */
+#define MIN_GALLOP 7
+
+/* Avoid malloc for small temp arrays. */
+#define MERGESTATE_TEMP_SIZE 256
+
+/* One MergeState exists on the stack per invocation of mergesort.  It's just
+ * a convenient way to pass state around among the helper functions.
+ */
+struct s_slice {
+    PyObject **base;
+    Py_ssize_t len;
+};
+
+typedef struct s_MergeState {
+    /* The user-supplied comparison function. or NULL if none given. */
+    PyObject *compare;
+
+    /* This controls when we get *into* galloping mode.  It's initialized
+     * to MIN_GALLOP.  merge_lo and merge_hi tend to nudge it higher for
+     * random data, and lower for highly structured data.
+     */
+    Py_ssize_t min_gallop;
+
+    /* 'a' is temp storage to help with merges.  It contains room for
+     * alloced entries.
+     */
+    PyObject **a;       /* may point to temparray below */
+    Py_ssize_t alloced;
+
+    /* A stack of n pending runs yet to be merged.  Run #i starts at
+     * address base[i] and extends for len[i] elements.  It's always
+     * true (so long as the indices are in bounds) that
+     *
+     *     pending[i].base + pending[i].len == pending[i+1].base
+     *
+     * so we could cut the storage for this, but it's a minor amount,
+     * and keeping all the info explicit simplifies the code.
+     */
+    int n;
+    struct s_slice pending[MAX_MERGE_PENDING];
+
+    /* 'a' points to this when possible, rather than muck with malloc. */
+    PyObject *temparray[MERGESTATE_TEMP_SIZE];
+} MergeState;
+
+/* Conceptually a MergeState's constructor. */
+static void
+merge_init(MergeState *ms, PyObject *compare)
+{
+    assert(ms != NULL);
+    ms->compare = compare;
+    ms->a = ms->temparray;
+    ms->alloced = MERGESTATE_TEMP_SIZE;
+    ms->n = 0;
+    ms->min_gallop = MIN_GALLOP;
+}
+
+/* Free all the temp memory owned by the MergeState.  This must be called
+ * when you're done with a MergeState, and may be called before then if
+ * you want to free the temp memory early.
+ */
+static void
+merge_freemem(MergeState *ms)
+{
+    assert(ms != NULL);
+    if (ms->a != ms->temparray)
+        PyMem_Free(ms->a);
+    ms->a = ms->temparray;
+    ms->alloced = MERGESTATE_TEMP_SIZE;
+}
+
+/* Ensure enough temp memory for 'need' array slots is available.
+ * Returns 0 on success and -1 if the memory can't be gotten.
+ */
+static int
+merge_getmem(MergeState *ms, Py_ssize_t need)
+{
+    assert(ms != NULL);
+    if (need <= ms->alloced)
+        return 0;
+    /* Don't realloc!  That can cost cycles to copy the old data, but
+     * we don't care what's in the block.
+     */
+    merge_freemem(ms);
+    if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
+    if (ms->a) {
+        ms->alloced = need;
+        return 0;
+    }
+    PyErr_NoMemory();
+    merge_freemem(ms);          /* reset to sane state */
+    return -1;
+}
+#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 :   \
+                                merge_getmem(MS, NEED))
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na <= nb.  See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+static Py_ssize_t
+merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
+                         PyObject **pb, Py_ssize_t nb)
+{
+    Py_ssize_t k;
+    PyObject *compare;
+    PyObject **dest;
+    int result = -1;            /* guilty until proved innocent */
+    Py_ssize_t min_gallop;
+
+    assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+    if (MERGE_GETMEM(ms, na) < 0)
+        return -1;
+    memcpy(ms->a, pa, na * sizeof(PyObject*));
+    dest = pa;
+    pa = ms->a;
+
+    *dest++ = *pb++;
+    --nb;
+    if (nb == 0)
+        goto Succeed;
+    if (na == 1)
+        goto CopyB;
+
+    min_gallop = ms->min_gallop;
+    compare = ms->compare;
+    for (;;) {
+        Py_ssize_t acount = 0;          /* # of times A won in a row */
+        Py_ssize_t bcount = 0;          /* # of times B won in a row */
+
+        /* Do the straightforward thing until (if ever) one run
+         * appears to win consistently.
+         */
+        for (;;) {
+            assert(na > 1 && nb > 0);
+            k = ISLT(*pb, *pa, compare);
+            if (k) {
+                if (k < 0)
+                    goto Fail;
+                *dest++ = *pb++;
+                ++bcount;
+                acount = 0;
+                --nb;
+                if (nb == 0)
+                    goto Succeed;
+                if (bcount >= min_gallop)
+                    break;
+            }
+            else {
+                *dest++ = *pa++;
+                ++acount;
+                bcount = 0;
+                --na;
+                if (na == 1)
+                    goto CopyB;
+                if (acount >= min_gallop)
+                    break;
+            }
+        }
+
+        /* One run is winning so consistently that galloping may
+         * be a huge win.  So try that, and continue galloping until
+         * (if ever) neither run appears to be winning consistently
+         * anymore.
+         */
+        ++min_gallop;
+        do {
+            assert(na > 1 && nb > 0);
+            min_gallop -= min_gallop > 1;
+            ms->min_gallop = min_gallop;
+            k = gallop_right(*pb, pa, na, 0, compare);
+            acount = k;
+            if (k) {
+                if (k < 0)
+                    goto Fail;
+                memcpy(dest, pa, k * sizeof(PyObject *));
+                dest += k;
+                pa += k;
+                na -= k;
+                if (na == 1)
+                    goto CopyB;
+                /* na==0 is impossible now if the comparison
+                 * function is consistent, but we can't assume
+                 * that it is.
+                 */
+                if (na == 0)
+                    goto Succeed;
+            }
+            *dest++ = *pb++;
+            --nb;
+            if (nb == 0)
+                goto Succeed;
+
+            k = gallop_left(*pa, pb, nb, 0, compare);
+            bcount = k;
+            if (k) {
+                if (k < 0)
+                    goto Fail;
+                memmove(dest, pb, k * sizeof(PyObject *));
+                dest += k;
+                pb += k;
+                nb -= k;
+                if (nb == 0)
+                    goto Succeed;
+            }
+            *dest++ = *pa++;
+            --na;
+            if (na == 1)
+                goto CopyB;
+        } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+        ++min_gallop;           /* penalize it for leaving galloping mode */
+        ms->min_gallop = min_gallop;
+    }
+Succeed:
+    result = 0;
+Fail:
+    if (na)
+        memcpy(dest, pa, na * sizeof(PyObject*));
+    return result;
+CopyB:
+    assert(na == 1 && nb > 0);
+    /* The last element of pa belongs at the end of the merge. */
+    memmove(dest, pb, nb * sizeof(PyObject *));
+    dest[nb] = *pa;
+    return 0;
+}
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place.  na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na >= nb.  See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+static Py_ssize_t
+merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb)
+{
+    Py_ssize_t k;
+    PyObject *compare;
+    PyObject **dest;
+    int result = -1;            /* guilty until proved innocent */
+    PyObject **basea;
+    PyObject **baseb;
+    Py_ssize_t min_gallop;
+
+    assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+    if (MERGE_GETMEM(ms, nb) < 0)
+        return -1;
+    dest = pb + nb - 1;
+    memcpy(ms->a, pb, nb * sizeof(PyObject*));
+    basea = pa;
+    baseb = ms->a;
+    pb = ms->a + nb - 1;
+    pa += na - 1;
+
+    *dest-- = *pa--;
+    --na;
+    if (na == 0)
+        goto Succeed;
+    if (nb == 1)
+        goto CopyA;
+
+    min_gallop = ms->min_gallop;
+    compare = ms->compare;
+    for (;;) {
+        Py_ssize_t acount = 0;          /* # of times A won in a row */
+        Py_ssize_t bcount = 0;          /* # of times B won in a row */
+
+        /* Do the straightforward thing until (if ever) one run
+         * appears to win consistently.
+         */
+        for (;;) {
+            assert(na > 0 && nb > 1);
+            k = ISLT(*pb, *pa, compare);
+            if (k) {
+                if (k < 0)
+                    goto Fail;
+                *dest-- = *pa--;
+                ++acount;
+                bcount = 0;
+                --na;
+                if (na == 0)
+                    goto Succeed;
+                if (acount >= min_gallop)
+                    break;
+            }
+            else {
+                *dest-- = *pb--;
+                ++bcount;
+                acount = 0;
+                --nb;
+                if (nb == 1)
+                    goto CopyA;
+                if (bcount >= min_gallop)
+                    break;
+            }
+        }
+
+        /* One run is winning so consistently that galloping may
+         * be a huge win.  So try that, and continue galloping until
+         * (if ever) neither run appears to be winning consistently
+         * anymore.
+         */
+        ++min_gallop;
+        do {
+            assert(na > 0 && nb > 1);
+            min_gallop -= min_gallop > 1;
+            ms->min_gallop = min_gallop;
+            k = gallop_right(*pb, basea, na, na-1, compare);
+            if (k < 0)
+                goto Fail;
+            k = na - k;
+            acount = k;
+            if (k) {
+                dest -= k;
+                pa -= k;
+                memmove(dest+1, pa+1, k * sizeof(PyObject *));
+                na -= k;
+                if (na == 0)
+                    goto Succeed;
+            }
+            *dest-- = *pb--;
+            --nb;
+            if (nb == 1)
+                goto CopyA;
+
+            k = gallop_left(*pa, baseb, nb, nb-1, compare);
+            if (k < 0)
+                goto Fail;
+            k = nb - k;
+            bcount = k;
+            if (k) {
+                dest -= k;
+                pb -= k;
+                memcpy(dest+1, pb+1, k * sizeof(PyObject *));
+                nb -= k;
+                if (nb == 1)
+                    goto CopyA;
+                /* nb==0 is impossible now if the comparison
+                 * function is consistent, but we can't assume
+                 * that it is.
+                 */
+                if (nb == 0)
+                    goto Succeed;
+            }
+            *dest-- = *pa--;
+            --na;
+            if (na == 0)
+                goto Succeed;
+        } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+        ++min_gallop;           /* penalize it for leaving galloping mode */
+        ms->min_gallop = min_gallop;
+    }
+Succeed:
+    result = 0;
+Fail:
+    if (nb)
+        memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*));
+    return result;
+CopyA:
+    assert(nb == 1 && na > 0);
+    /* The first element of pb belongs at the front of the merge. */
+    dest -= na;
+    pa -= na;
+    memmove(dest+1, pa+1, na * sizeof(PyObject *));
+    *dest = *pb;
+    return 0;
+}
+
+/* Merge the two runs at stack indices i and i+1.
+ * Returns 0 on success, -1 on error.
+ */
+static Py_ssize_t
+merge_at(MergeState *ms, Py_ssize_t i)
+{
+    PyObject **pa, **pb;
+    Py_ssize_t na, nb;
+    Py_ssize_t k;
+    PyObject *compare;
+
+    assert(ms != NULL);
+    assert(ms->n >= 2);
+    assert(i >= 0);
+    assert(i == ms->n - 2 || i == ms->n - 3);
+
+    pa = ms->pending[i].base;
+    na = ms->pending[i].len;
+    pb = ms->pending[i+1].base;
+    nb = ms->pending[i+1].len;
+    assert(na > 0 && nb > 0);
+    assert(pa + na == pb);
+
+    /* Record the length of the combined runs; if i is the 3rd-last
+     * run now, also slide over the last run (which isn't involved
+     * in this merge).  The current run i+1 goes away in any case.
+     */
+    ms->pending[i].len = na + nb;
+    if (i == ms->n - 3)
+        ms->pending[i+1] = ms->pending[i+2];
+    --ms->n;
+
+    /* Where does b start in a?  Elements in a before that can be
+     * ignored (already in place).
+     */
+    compare = ms->compare;
+    k = gallop_right(*pb, pa, na, 0, compare);
+    if (k < 0)
+        return -1;
+    pa += k;
+    na -= k;
+    if (na == 0)
+        return 0;
+
+    /* Where does a end in b?  Elements in b after that can be
+     * ignored (already in place).
+     */
+    nb = gallop_left(pa[na-1], pb, nb, nb-1, compare);
+    if (nb <= 0)
+        return nb;
+
+    /* Merge what remains of the runs, using a temp array with
+     * min(na, nb) elements.
+     */
+    if (na <= nb)
+        return merge_lo(ms, pa, na, pb, nb);
+    else
+        return merge_hi(ms, pa, na, pb, nb);
+}
+
+/* Examine the stack of runs waiting to be merged, merging adjacent runs
+ * until the stack invariants are re-established:
+ *
+ * 1. len[-3] > len[-2] + len[-1]
+ * 2. len[-2] > len[-1]
+ *
+ * See listsort.txt for more info.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int
+merge_collapse(MergeState *ms)
+{
+    struct s_slice *p = ms->pending;
+
+    assert(ms);
+    while (ms->n > 1) {
+        Py_ssize_t n = ms->n - 2;
+        if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) {
+            if (p[n-1].len < p[n+1].len)
+                --n;
+            if (merge_at(ms, n) < 0)
+                return -1;
+        }
+        else if (p[n].len <= p[n+1].len) {
+                 if (merge_at(ms, n) < 0)
+                        return -1;
+        }
+        else
+            break;
+    }
+    return 0;
+}
+
+/* Regardless of invariants, merge all runs on the stack until only one
+ * remains.  This is used at the end of the mergesort.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int
+merge_force_collapse(MergeState *ms)
+{
+    struct s_slice *p = ms->pending;
+
+    assert(ms);
+    while (ms->n > 1) {
+        Py_ssize_t n = ms->n - 2;
+        if (n > 0 && p[n-1].len < p[n+1].len)
+            --n;
+        if (merge_at(ms, n) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+/* Compute a good value for the minimum run length; natural runs shorter
+ * than this are boosted artificially via binary insertion.
+ *
+ * If n < 64, return n (it's too small to bother with fancy stuff).
+ * Else if n is an exact power of 2, return 32.
+ * Else return an int k, 32 <= k <= 64, such that n/k is close to, but
+ * strictly less than, an exact power of 2.
+ *
+ * See listsort.txt for more info.
+ */
+static Py_ssize_t
+merge_compute_minrun(Py_ssize_t n)
+{
+    Py_ssize_t r = 0;           /* becomes 1 if any 1 bits are shifted off */
+
+    assert(n >= 0);
+    while (n >= 64) {
+        r |= n & 1;
+        n >>= 1;
+    }
+    return n + r;
+}
+
+/* Special wrapper to support stable sorting using the decorate-sort-undecorate
+   pattern.  Holds a key which is used for comparisons and the original record
+   which is returned during the undecorate phase.  By exposing only the key
+   during comparisons, the underlying sort stability characteristics are left
+   unchanged.  Also, if a custom comparison function is used, it will only see
+   the key instead of a full record. */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *key;
+    PyObject *value;
+} sortwrapperobject;
+
+PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key.");
+static PyObject *
+sortwrapper_richcompare(sortwrapperobject *, sortwrapperobject *, int);
+static void
+sortwrapper_dealloc(sortwrapperobject *);
+
+static PyTypeObject sortwrapper_type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "sortwrapper",                              /* tp_name */
+    sizeof(sortwrapperobject),                  /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)sortwrapper_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+    Py_TPFLAGS_HAVE_RICHCOMPARE,                /* tp_flags */
+    sortwrapper_doc,                            /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    (richcmpfunc)sortwrapper_richcompare,       /* tp_richcompare */
+};
+
+
+static PyObject *
+sortwrapper_richcompare(sortwrapperobject *a, sortwrapperobject *b, int op)
+{
+    if (!PyObject_TypeCheck(b, &sortwrapper_type)) {
+        PyErr_SetString(PyExc_TypeError,
+            "expected a sortwrapperobject");
+        return NULL;
+    }
+    return PyObject_RichCompare(a->key, b->key, op);
+}
+
+static void
+sortwrapper_dealloc(sortwrapperobject *so)
+{
+    Py_XDECREF(so->key);
+    Py_XDECREF(so->value);
+    PyObject_Del(so);
+}
+
+/* Returns a new reference to a sortwrapper.
+   Consumes the references to the two underlying objects. */
+
+static PyObject *
+build_sortwrapper(PyObject *key, PyObject *value)
+{
+    sortwrapperobject *so;
+
+    so = PyObject_New(sortwrapperobject, &sortwrapper_type);
+    if (so == NULL)
+        return NULL;
+    so->key = key;
+    so->value = value;
+    return (PyObject *)so;
+}
+
+/* Returns a new reference to the value underlying the wrapper. */
+static PyObject *
+sortwrapper_getvalue(PyObject *so)
+{
+    PyObject *value;
+
+    if (!PyObject_TypeCheck(so, &sortwrapper_type)) {
+        PyErr_SetString(PyExc_TypeError,
+            "expected a sortwrapperobject");
+        return NULL;
+    }
+    value = ((sortwrapperobject *)so)->value;
+    Py_INCREF(value);
+    return value;
+}
+
+/* Wrapper for user specified cmp functions in combination with a
+   specified key function.  Makes sure the cmp function is presented
+   with the actual key instead of the sortwrapper */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *func;
+} cmpwrapperobject;
+
+static void
+cmpwrapper_dealloc(cmpwrapperobject *co)
+{
+    Py_XDECREF(co->func);
+    PyObject_Del(co);
+}
+
+static PyObject *
+cmpwrapper_call(cmpwrapperobject *co, PyObject *args, PyObject *kwds)
+{
+    PyObject *x, *y, *xx, *yy;
+
+    if (!PyArg_UnpackTuple(args, "", 2, 2, &x, &y))
+        return NULL;
+    if (!PyObject_TypeCheck(x, &sortwrapper_type) ||
+        !PyObject_TypeCheck(y, &sortwrapper_type)) {
+        PyErr_SetString(PyExc_TypeError,
+            "expected a sortwrapperobject");
+        return NULL;
+    }
+    xx = ((sortwrapperobject *)x)->key;
+    yy = ((sortwrapperobject *)y)->key;
+    return PyObject_CallFunctionObjArgs(co->func, xx, yy, NULL);
+}
+
+PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys.");
+
+static PyTypeObject cmpwrapper_type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "cmpwrapper",                               /* tp_name */
+    sizeof(cmpwrapperobject),                   /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)cmpwrapper_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 */
+    (ternaryfunc)cmpwrapper_call,               /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    cmpwrapper_doc,                             /* tp_doc */
+};
+
+static PyObject *
+build_cmpwrapper(PyObject *cmpfunc)
+{
+    cmpwrapperobject *co;
+
+    co = PyObject_New(cmpwrapperobject, &cmpwrapper_type);
+    if (co == NULL)
+        return NULL;
+    Py_INCREF(cmpfunc);
+    co->func = cmpfunc;
+    return (PyObject *)co;
+}
+
+/* An adaptive, stable, natural mergesort.  See listsort.txt.
+ * Returns Py_None on success, NULL on error.  Even in case of error, the
+ * list will be some permutation of its input state (nothing is lost or
+ * duplicated).
+ */
+static PyObject *
+listsort(PyListObject *self, PyObject *args, PyObject *kwds)
+{
+    MergeState ms;
+    PyObject **lo, **hi;
+    Py_ssize_t nremaining;
+    Py_ssize_t minrun;
+    Py_ssize_t saved_ob_size, saved_allocated;
+    PyObject **saved_ob_item;
+    PyObject **final_ob_item;
+    PyObject *compare = NULL;
+    PyObject *result = NULL;            /* guilty until proved innocent */
+    int reverse = 0;
+    PyObject *keyfunc = NULL;
+    Py_ssize_t i;
+    PyObject *key, *value, *kvpair;
+    static char *kwlist[] = {"cmp", "key", "reverse", 0};
+
+    assert(self != NULL);
+    assert (PyList_Check(self));
+    if (args != NULL) {
+        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort",
+            kwlist, &compare, &keyfunc, &reverse))
+            return NULL;
+    }
+    if (compare == Py_None)
+        compare = NULL;
+    if (compare != NULL &&
+        PyErr_WarnPy3k("the cmp argument is not supported in 3.x", 1) < 0)
+        return NULL;
+    if (keyfunc == Py_None)
+        keyfunc = NULL;
+    if (compare != NULL && keyfunc != NULL) {
+        compare = build_cmpwrapper(compare);
+        if (compare == NULL)
+            return NULL;
+    } else
+        Py_XINCREF(compare);
+
+    /* The list is temporarily made empty, so that mutations performed
+     * by comparison functions can't affect the slice of memory we're
+     * sorting (allowing mutations during sorting is a core-dump
+     * factory, since ob_item may change).
+     */
+    saved_ob_size = Py_SIZE(self);
+    saved_ob_item = self->ob_item;
+    saved_allocated = self->allocated;
+    Py_SIZE(self) = 0;
+    self->ob_item = NULL;
+    self->allocated = -1; /* any operation will reset it to >= 0 */
+
+    if (keyfunc != NULL) {
+        for (i=0 ; i < saved_ob_size ; i++) {
+            value = saved_ob_item[i];
+            key = PyObject_CallFunctionObjArgs(keyfunc, value,
+                                               NULL);
+            if (key == NULL) {
+                for (i=i-1 ; i>=0 ; i--) {
+                    kvpair = saved_ob_item[i];
+                    value = sortwrapper_getvalue(kvpair);
+                    saved_ob_item[i] = value;
+                    Py_DECREF(kvpair);
+                }
+                goto dsu_fail;
+            }
+            kvpair = build_sortwrapper(key, value);
+            if (kvpair == NULL)
+                goto dsu_fail;
+            saved_ob_item[i] = kvpair;
+        }
+    }
+
+    /* Reverse sort stability achieved by initially reversing the list,
+    applying a stable forward sort, then reversing the final result. */
+    if (reverse && saved_ob_size > 1)
+        reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+
+    merge_init(&ms, compare);
+
+    nremaining = saved_ob_size;
+    if (nremaining < 2)
+        goto succeed;
+
+    /* March over the array once, left to right, finding natural runs,
+     * and extending short natural runs to minrun elements.
+     */
+    lo = saved_ob_item;
+    hi = lo + nremaining;
+    minrun = merge_compute_minrun(nremaining);
+    do {
+        int descending;
+        Py_ssize_t n;
+
+        /* Identify next run. */
+        n = count_run(lo, hi, compare, &descending);
+        if (n < 0)
+            goto fail;
+        if (descending)
+            reverse_slice(lo, lo + n);
+        /* If short, extend to min(minrun, nremaining). */
+        if (n < minrun) {
+            const Py_ssize_t force = nremaining <= minrun ?
+                              nremaining : minrun;
+            if (binarysort(lo, lo + force, lo + n, compare) < 0)
+                goto fail;
+            n = force;
+        }
+        /* Push run onto pending-runs stack, and maybe merge. */
+        assert(ms.n < MAX_MERGE_PENDING);
+        ms.pending[ms.n].base = lo;
+        ms.pending[ms.n].len = n;
+        ++ms.n;
+        if (merge_collapse(&ms) < 0)
+            goto fail;
+        /* Advance to find next run. */
+        lo += n;
+        nremaining -= n;
+    } while (nremaining);
+    assert(lo == hi);
+
+    if (merge_force_collapse(&ms) < 0)
+        goto fail;
+    assert(ms.n == 1);
+    assert(ms.pending[0].base == saved_ob_item);
+    assert(ms.pending[0].len == saved_ob_size);
+
+succeed:
+    result = Py_None;
+fail:
+    if (keyfunc != NULL) {
+        for (i=0 ; i < saved_ob_size ; i++) {
+            kvpair = saved_ob_item[i];
+            value = sortwrapper_getvalue(kvpair);
+            saved_ob_item[i] = value;
+            Py_DECREF(kvpair);
+        }
+    }
+
+    if (self->allocated != -1 && result != NULL) {
+        /* The user mucked with the list during the sort,
+         * and we don't already have another error to report.
+         */
+        PyErr_SetString(PyExc_ValueError, "list modified during sort");
+        result = NULL;
+    }
+
+    if (reverse && saved_ob_size > 1)
+        reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+
+    merge_freemem(&ms);
+
+dsu_fail:
+    final_ob_item = self->ob_item;
+    i = Py_SIZE(self);
+    Py_SIZE(self) = saved_ob_size;
+    self->ob_item = saved_ob_item;
+    self->allocated = saved_allocated;
+    if (final_ob_item != NULL) {
+        /* we cannot use list_clear() for this because it does not
+           guarantee that the list is really empty when it returns */
+        while (--i >= 0) {
+            Py_XDECREF(final_ob_item[i]);
+        }
+        PyMem_FREE(final_ob_item);
+    }
+    Py_XDECREF(compare);
+    Py_XINCREF(result);
+    return result;
+}
+#undef IFLT
+#undef ISLT
+
+int
+PyList_Sort(PyObject *v)
+{
+    if (v == NULL || !PyList_Check(v)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    v = listsort((PyListObject *)v, (PyObject *)NULL, (PyObject *)NULL);
+    if (v == NULL)
+        return -1;
+    Py_DECREF(v);
+    return 0;
+}
+
+static PyObject *
+listreverse(PyListObject *self)
+{
+    if (Py_SIZE(self) > 1)
+        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
+    Py_RETURN_NONE;
+}
+
+int
+PyList_Reverse(PyObject *v)
+{
+    PyListObject *self = (PyListObject *)v;
+
+    if (v == NULL || !PyList_Check(v)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (Py_SIZE(self) > 1)
+        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
+    return 0;
+}
+
+PyObject *
+PyList_AsTuple(PyObject *v)
+{
+    PyObject *w;
+    PyObject **p, **q;
+    Py_ssize_t n;
+    if (v == NULL || !PyList_Check(v)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    n = Py_SIZE(v);
+    w = PyTuple_New(n);
+    if (w == NULL)
+        return NULL;
+    p = ((PyTupleObject *)w)->ob_item;
+    q = ((PyListObject *)v)->ob_item;
+    while (--n >= 0) {
+        Py_INCREF(*q);
+        *p = *q;
+        p++;
+        q++;
+    }
+    return w;
+}
+
+static PyObject *
+listindex(PyListObject *self, PyObject *args)
+{
+    Py_ssize_t i, start=0, stop=Py_SIZE(self);
+    PyObject *v, *format_tuple, *err_string;
+    static PyObject *err_format = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
+                                _PyEval_SliceIndex, &start,
+                                _PyEval_SliceIndex, &stop))
+        return NULL;
+    if (start < 0) {
+        start += Py_SIZE(self);
+        if (start < 0)
+            start = 0;
+    }
+    if (stop < 0) {
+        stop += Py_SIZE(self);
+        if (stop < 0)
+            stop = 0;
+    }
+    for (i = start; i < stop && i < Py_SIZE(self); i++) {
+        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+        if (cmp > 0)
+            return PyInt_FromSsize_t(i);
+        else if (cmp < 0)
+            return NULL;
+    }
+    if (err_format == NULL) {
+        err_format = PyString_FromString("%r is not in list");
+        if (err_format == NULL)
+            return NULL;
+    }
+    format_tuple = PyTuple_Pack(1, v);
+    if (format_tuple == NULL)
+        return NULL;
+    err_string = PyString_Format(err_format, format_tuple);
+    Py_DECREF(format_tuple);
+    if (err_string == NULL)
+        return NULL;
+    PyErr_SetObject(PyExc_ValueError, err_string);
+    Py_DECREF(err_string);
+    return NULL;
+}
+
+static PyObject *
+listcount(PyListObject *self, PyObject *v)
+{
+    Py_ssize_t count = 0;
+    Py_ssize_t i;
+
+    for (i = 0; i < Py_SIZE(self); i++) {
+        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+        if (cmp > 0)
+            count++;
+        else if (cmp < 0)
+            return NULL;
+    }
+    return PyInt_FromSsize_t(count);
+}
+
+static PyObject *
+listremove(PyListObject *self, PyObject *v)
+{
+    Py_ssize_t i;
+
+    for (i = 0; i < Py_SIZE(self); i++) {
+        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+        if (cmp > 0) {
+            if (list_ass_slice(self, i, i+1,
+                               (PyObject *)NULL) == 0)
+                Py_RETURN_NONE;
+            return NULL;
+        }
+        else if (cmp < 0)
+            return NULL;
+    }
+    PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
+    return NULL;
+}
+
+static int
+list_traverse(PyListObject *o, visitproc visit, void *arg)
+{
+    Py_ssize_t i;
+
+    for (i = Py_SIZE(o); --i >= 0; )
+        Py_VISIT(o->ob_item[i]);
+    return 0;
+}
+
+static PyObject *
+list_richcompare(PyObject *v, PyObject *w, int op)
+{
+    PyListObject *vl, *wl;
+    Py_ssize_t i;
+
+    if (!PyList_Check(v) || !PyList_Check(w)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    vl = (PyListObject *)v;
+    wl = (PyListObject *)w;
+
+    if (Py_SIZE(vl) != Py_SIZE(wl) && (op == Py_EQ || op == Py_NE)) {
+        /* Shortcut: if the lengths differ, the lists differ */
+        PyObject *res;
+        if (op == Py_EQ)
+            res = Py_False;
+        else
+            res = Py_True;
+        Py_INCREF(res);
+        return res;
+    }
+
+    /* Search for the first index where items are different */
+    for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
+        int k = PyObject_RichCompareBool(vl->ob_item[i],
+                                         wl->ob_item[i], Py_EQ);
+        if (k < 0)
+            return NULL;
+        if (!k)
+            break;
+    }
+
+    if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) {
+        /* No more items to compare -- compare sizes */
+        Py_ssize_t vs = Py_SIZE(vl);
+        Py_ssize_t ws = Py_SIZE(wl);
+        int cmp;
+        PyObject *res;
+        switch (op) {
+        case Py_LT: cmp = vs <  ws; break;
+        case Py_LE: cmp = vs <= ws; break;
+        case Py_EQ: cmp = vs == ws; break;
+        case Py_NE: cmp = vs != ws; break;
+        case Py_GT: cmp = vs >  ws; break;
+        case Py_GE: cmp = vs >= ws; break;
+        default: return NULL; /* cannot happen */
+        }
+        if (cmp)
+            res = Py_True;
+        else
+            res = Py_False;
+        Py_INCREF(res);
+        return res;
+    }
+
+    /* We have an item that differs -- shortcuts for EQ/NE */
+    if (op == Py_EQ) {
+        Py_INCREF(Py_False);
+        return Py_False;
+    }
+    if (op == Py_NE) {
+        Py_INCREF(Py_True);
+        return Py_True;
+    }
+
+    /* Compare the final item again using the proper operator */
+    return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
+}
+
+static int
+list_init(PyListObject *self, PyObject *args, PyObject *kw)
+{
+    PyObject *arg = NULL;
+    static char *kwlist[] = {"sequence", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg))
+        return -1;
+
+    /* Verify list invariants established by PyType_GenericAlloc() */
+    assert(0 <= Py_SIZE(self));
+    assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
+    assert(self->ob_item != NULL ||
+           self->allocated == 0 || self->allocated == -1);
+
+    /* Empty previous contents */
+    if (self->ob_item != NULL) {
+        (void)list_clear(self);
+    }
+    if (arg != NULL) {
+        PyObject *rv = listextend(self, arg);
+        if (rv == NULL)
+            return -1;
+        Py_DECREF(rv);
+    }
+    return 0;
+}
+
+static PyObject *
+list_sizeof(PyListObject *self)
+{
+    Py_ssize_t res;
+
+    res = sizeof(PyListObject) + self->allocated * sizeof(void*);
+    return PyInt_FromSsize_t(res);
+}
+
+static PyObject *list_iter(PyObject *seq);
+static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
+
+PyDoc_STRVAR(getitem_doc,
+"x.__getitem__(y) <==> x[y]");
+PyDoc_STRVAR(reversed_doc,
+"L.__reversed__() -- return a reverse iterator over the list");
+PyDoc_STRVAR(sizeof_doc,
+"L.__sizeof__() -- size of L in memory, in bytes");
+PyDoc_STRVAR(append_doc,
+"L.append(object) -- append object to end");
+PyDoc_STRVAR(extend_doc,
+"L.extend(iterable) -- extend list by appending elements from the iterable");
+PyDoc_STRVAR(insert_doc,
+"L.insert(index, object) -- insert object before index");
+PyDoc_STRVAR(pop_doc,
+"L.pop([index]) -> item -- remove and return item at index (default last).\n"
+"Raises IndexError if list is empty or index is out of range.");
+PyDoc_STRVAR(remove_doc,
+"L.remove(value) -- remove first occurrence of value.\n"
+"Raises ValueError if the value is not present.");
+PyDoc_STRVAR(index_doc,
+"L.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
+"Raises ValueError if the value is not present.");
+PyDoc_STRVAR(count_doc,
+"L.count(value) -> integer -- return number of occurrences of value");
+PyDoc_STRVAR(reverse_doc,
+"L.reverse() -- reverse *IN PLACE*");
+PyDoc_STRVAR(sort_doc,
+"L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;\n\
+cmp(x, y) -> -1, 0, 1");
+
+static PyObject *list_subscript(PyListObject*, PyObject*);
+
+static PyMethodDef list_methods[] = {
+    {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},
+    {"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},
+    {"__sizeof__",  (PyCFunction)list_sizeof, METH_NOARGS, sizeof_doc},
+    {"append",          (PyCFunction)listappend,  METH_O, append_doc},
+    {"insert",          (PyCFunction)listinsert,  METH_VARARGS, insert_doc},
+    {"extend",      (PyCFunction)listextend,  METH_O, extend_doc},
+    {"pop",             (PyCFunction)listpop,     METH_VARARGS, pop_doc},
+    {"remove",          (PyCFunction)listremove,  METH_O, remove_doc},
+    {"index",           (PyCFunction)listindex,   METH_VARARGS, index_doc},
+    {"count",           (PyCFunction)listcount,   METH_O, count_doc},
+    {"reverse",         (PyCFunction)listreverse, METH_NOARGS, reverse_doc},
+    {"sort",            (PyCFunction)listsort,    METH_VARARGS | METH_KEYWORDS, sort_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PySequenceMethods list_as_sequence = {
+    (lenfunc)list_length,                       /* sq_length */
+    (binaryfunc)list_concat,                    /* sq_concat */
+    (ssizeargfunc)list_repeat,                  /* sq_repeat */
+    (ssizeargfunc)list_item,                    /* sq_item */
+    (ssizessizeargfunc)list_slice,              /* sq_slice */
+    (ssizeobjargproc)list_ass_item,             /* sq_ass_item */
+    (ssizessizeobjargproc)list_ass_slice,       /* sq_ass_slice */
+    (objobjproc)list_contains,                  /* sq_contains */
+    (binaryfunc)list_inplace_concat,            /* sq_inplace_concat */
+    (ssizeargfunc)list_inplace_repeat,          /* sq_inplace_repeat */
+};
+
+PyDoc_STRVAR(list_doc,
+"list() -> new empty list\n"
+"list(iterable) -> new list initialized from iterable's items");
+
+
+static PyObject *
+list_subscript(PyListObject* self, PyObject* item)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i;
+        i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += PyList_GET_SIZE(self);
+        return list_item(self, i);
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+        PyObject* result;
+        PyObject* it;
+        PyObject **src, **dest;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
+                         &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0) {
+            return PyList_New(0);
+        }
+        else if (step == 1) {
+            return list_slice(self, start, stop);
+        }
+        else {
+            result = PyList_New(slicelength);
+            if (!result) return NULL;
+
+            src = self->ob_item;
+            dest = ((PyListObject *)result)->ob_item;
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                it = src[cur];
+                Py_INCREF(it);
+                dest[i] = it;
+            }
+
+            return result;
+        }
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "list indices must be integers, not %.200s",
+                     item->ob_type->tp_name);
+        return NULL;
+    }
+}
+
+static int
+list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return -1;
+        if (i < 0)
+            i += PyList_GET_SIZE(self);
+        return list_ass_item(self, i, value);
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
+                         &start, &stop, &step, &slicelength) < 0) {
+            return -1;
+        }
+
+        if (step == 1)
+            return list_ass_slice(self, start, stop, value);
+
+        /* Make sure s[5:2] = [..] inserts at the right place:
+           before 5, not before 2. */
+        if ((step < 0 && start < stop) ||
+            (step > 0 && start > stop))
+            stop = start;
+
+        if (value == NULL) {
+            /* delete slice */
+            PyObject **garbage;
+            size_t cur;
+            Py_ssize_t i;
+
+            if (slicelength <= 0)
+                return 0;
+
+            if (step < 0) {
+                stop = start + 1;
+                start = stop + step*(slicelength - 1) - 1;
+                step = -step;
+            }
+
+            assert((size_t)slicelength <=
+                   PY_SIZE_MAX / sizeof(PyObject*));
+
+            garbage = (PyObject**)
+                PyMem_MALLOC(slicelength*sizeof(PyObject*));
+            if (!garbage) {
+                PyErr_NoMemory();
+                return -1;
+            }
+
+            /* drawing pictures might help understand these for
+               loops. Basically, we memmove the parts of the
+               list that are *not* part of the slice: step-1
+               items for each item that is part of the slice,
+               and then tail end of the list that was not
+               covered by the slice */
+            for (cur = start, i = 0;
+                 cur < (size_t)stop;
+                 cur += step, i++) {
+                Py_ssize_t lim = step - 1;
+
+                garbage[i] = PyList_GET_ITEM(self, cur);
+
+                if (cur + step >= (size_t)Py_SIZE(self)) {
+                    lim = Py_SIZE(self) - cur - 1;
+                }
+
+                memmove(self->ob_item + cur - i,
+                    self->ob_item + cur + 1,
+                    lim * sizeof(PyObject *));
+            }
+            cur = start + slicelength*step;
+            if (cur < (size_t)Py_SIZE(self)) {
+                memmove(self->ob_item + cur - slicelength,
+                    self->ob_item + cur,
+                    (Py_SIZE(self) - cur) *
+                     sizeof(PyObject *));
+            }
+
+            Py_SIZE(self) -= slicelength;
+            list_resize(self, Py_SIZE(self));
+
+            for (i = 0; i < slicelength; i++) {
+                Py_DECREF(garbage[i]);
+            }
+            PyMem_FREE(garbage);
+
+            return 0;
+        }
+        else {
+            /* assign slice */
+            PyObject *ins, *seq;
+            PyObject **garbage, **seqitems, **selfitems;
+            Py_ssize_t cur, i;
+
+            /* protect against a[::-1] = a */
+            if (self == (PyListObject*)value) {
+                seq = list_slice((PyListObject*)value, 0,
+                                   PyList_GET_SIZE(value));
+            }
+            else {
+                seq = PySequence_Fast(value,
+                                      "must assign iterable "
+                                      "to extended slice");
+            }
+            if (!seq)
+                return -1;
+
+            if (PySequence_Fast_GET_SIZE(seq) != slicelength) {
+                PyErr_Format(PyExc_ValueError,
+                    "attempt to assign sequence of "
+                    "size %zd to extended slice of "
+                    "size %zd",
+                         PySequence_Fast_GET_SIZE(seq),
+                         slicelength);
+                Py_DECREF(seq);
+                return -1;
+            }
+
+            if (!slicelength) {
+                Py_DECREF(seq);
+                return 0;
+            }
+
+            garbage = (PyObject**)
+                PyMem_MALLOC(slicelength*sizeof(PyObject*));
+            if (!garbage) {
+                Py_DECREF(seq);
+                PyErr_NoMemory();
+                return -1;
+            }
+
+            selfitems = self->ob_item;
+            seqitems = PySequence_Fast_ITEMS(seq);
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                garbage[i] = selfitems[cur];
+                ins = seqitems[i];
+                Py_INCREF(ins);
+                selfitems[cur] = ins;
+            }
+
+            for (i = 0; i < slicelength; i++) {
+                Py_DECREF(garbage[i]);
+            }
+
+            PyMem_FREE(garbage);
+            Py_DECREF(seq);
+
+            return 0;
+        }
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "list indices must be integers, not %.200s",
+                     item->ob_type->tp_name);
+        return -1;
+    }
+}
+
+static PyMappingMethods list_as_mapping = {
+    (lenfunc)list_length,
+    (binaryfunc)list_subscript,
+    (objobjargproc)list_ass_subscript
+};
+
+PyTypeObject PyList_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "list",
+    sizeof(PyListObject),
+    0,
+    (destructor)list_dealloc,                   /* tp_dealloc */
+    (printfunc)list_print,                      /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)list_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    &list_as_sequence,                          /* tp_as_sequence */
+    &list_as_mapping,                           /* tp_as_mapping */
+    (hashfunc)PyObject_HashNotImplemented,      /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS,         /* tp_flags */
+    list_doc,                                   /* tp_doc */
+    (traverseproc)list_traverse,                /* tp_traverse */
+    (inquiry)list_clear,                        /* tp_clear */
+    list_richcompare,                           /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    list_iter,                                  /* tp_iter */
+    0,                                          /* tp_iternext */
+    list_methods,                               /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    (initproc)list_init,                        /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    PyType_GenericNew,                          /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
+
+
+/*********************** List Iterator **************************/
+
+typedef struct {
+    PyObject_HEAD
+    long it_index;
+    PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
+} listiterobject;
+
+static PyObject *list_iter(PyObject *);
+static void listiter_dealloc(listiterobject *);
+static int listiter_traverse(listiterobject *, visitproc, void *);
+static PyObject *listiter_next(listiterobject *);
+static PyObject *listiter_len(listiterobject *);
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef listiter_methods[] = {
+    {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyListIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "listiterator",                             /* tp_name */
+    sizeof(listiterobject),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)listiter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)listiter_traverse,            /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)listiter_next,                /* tp_iternext */
+    listiter_methods,                           /* tp_methods */
+    0,                                          /* tp_members */
+};
+
+
+static PyObject *
+list_iter(PyObject *seq)
+{
+    listiterobject *it;
+
+    if (!PyList_Check(seq)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    it = PyObject_GC_New(listiterobject, &PyListIter_Type);
+    if (it == NULL)
+        return NULL;
+    it->it_index = 0;
+    Py_INCREF(seq);
+    it->it_seq = (PyListObject *)seq;
+    _PyObject_GC_TRACK(it);
+    return (PyObject *)it;
+}
+
+static void
+listiter_dealloc(listiterobject *it)
+{
+    _PyObject_GC_UNTRACK(it);
+    Py_XDECREF(it->it_seq);
+    PyObject_GC_Del(it);
+}
+
+static int
+listiter_traverse(listiterobject *it, visitproc visit, void *arg)
+{
+    Py_VISIT(it->it_seq);
+    return 0;
+}
+
+static PyObject *
+listiter_next(listiterobject *it)
+{
+    PyListObject *seq;
+    PyObject *item;
+
+    assert(it != NULL);
+    seq = it->it_seq;
+    if (seq == NULL)
+        return NULL;
+    assert(PyList_Check(seq));
+
+    if (it->it_index < PyList_GET_SIZE(seq)) {
+        item = PyList_GET_ITEM(seq, it->it_index);
+        ++it->it_index;
+        Py_INCREF(item);
+        return item;
+    }
+
+    Py_DECREF(seq);
+    it->it_seq = NULL;
+    return NULL;
+}
+
+static PyObject *
+listiter_len(listiterobject *it)
+{
+    Py_ssize_t len;
+    if (it->it_seq) {
+        len = PyList_GET_SIZE(it->it_seq) - it->it_index;
+        if (len >= 0)
+            return PyInt_FromSsize_t(len);
+    }
+    return PyInt_FromLong(0);
+}
+/*********************** List Reverse Iterator **************************/
+
+typedef struct {
+    PyObject_HEAD
+    Py_ssize_t it_index;
+    PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
+} listreviterobject;
+
+static PyObject *list_reversed(PyListObject *, PyObject *);
+static void listreviter_dealloc(listreviterobject *);
+static int listreviter_traverse(listreviterobject *, visitproc, void *);
+static PyObject *listreviter_next(listreviterobject *);
+static PyObject *listreviter_len(listreviterobject *);
+
+static PyMethodDef listreviter_methods[] = {
+    {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyListRevIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "listreverseiterator",                      /* tp_name */
+    sizeof(listreviterobject),                  /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)listreviter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)listreviter_traverse,         /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)listreviter_next,             /* tp_iternext */
+    listreviter_methods,                /* tp_methods */
+    0,
+};
+
+static PyObject *
+list_reversed(PyListObject *seq, PyObject *unused)
+{
+    listreviterobject *it;
+
+    it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);
+    if (it == NULL)
+        return NULL;
+    assert(PyList_Check(seq));
+    it->it_index = PyList_GET_SIZE(seq) - 1;
+    Py_INCREF(seq);
+    it->it_seq = seq;
+    PyObject_GC_Track(it);
+    return (PyObject *)it;
+}
+
+static void
+listreviter_dealloc(listreviterobject *it)
+{
+    PyObject_GC_UnTrack(it);
+    Py_XDECREF(it->it_seq);
+    PyObject_GC_Del(it);
+}
+
+static int
+listreviter_traverse(listreviterobject *it, visitproc visit, void *arg)
+{
+    Py_VISIT(it->it_seq);
+    return 0;
+}
+
+static PyObject *
+listreviter_next(listreviterobject *it)
+{
+    PyObject *item;
+    Py_ssize_t index = it->it_index;
+    PyListObject *seq = it->it_seq;
+
+    if (index>=0 && index < PyList_GET_SIZE(seq)) {
+        item = PyList_GET_ITEM(seq, index);
+        it->it_index--;
+        Py_INCREF(item);
+        return item;
+    }
+    it->it_index = -1;
+    if (seq != NULL) {
+        it->it_seq = NULL;
+        Py_DECREF(seq);
+    }
+    return NULL;
+}
+
+static PyObject *
+listreviter_len(listreviterobject *it)
+{
+    Py_ssize_t len = it->it_index + 1;
+    if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len)
+        len = 0;
+    return PyLong_FromSsize_t(len);
+}
diff --git a/Python-2.7.5/Objects/listsort.txt b/Python-2.7.5/Objects/listsort.txt
new file mode 100644
index 0000000..31a5445
--- /dev/null
+++ b/Python-2.7.5/Objects/listsort.txt
@@ -0,0 +1,677 @@
+Intro
+-----
+This describes an adaptive, stable, natural mergesort, modestly called
+timsort (hey, I earned it <wink>).  It has supernatural performance on many
+kinds of partially ordered arrays (less than lg(N!) comparisons needed, and
+as few as N-1), yet as fast as Python's previous highly tuned samplesort
+hybrid on random arrays.
+
+In a nutshell, the main routine marches over the array once, left to right,
+alternately identifying the next run, then merging it into the previous
+runs "intelligently".  Everything else is complication for speed, and some
+hard-won measure of memory efficiency.
+
+
+Comparison with Python's Samplesort Hybrid
+------------------------------------------
++ timsort can require a temp array containing as many as N//2 pointers,
+  which means as many as 2*N extra bytes on 32-bit boxes.  It can be
+  expected to require a temp array this large when sorting random data; on
+  data with significant structure, it may get away without using any extra
+  heap memory.  This appears to be the strongest argument against it, but
+  compared to the size of an object, 2 temp bytes worst-case (also expected-
+  case for random data) doesn't scare me much.
+
+  It turns out that Perl is moving to a stable mergesort, and the code for
+  that appears always to require a temp array with room for at least N
+  pointers. (Note that I wouldn't want to do that even if space weren't an
+  issue; I believe its efforts at memory frugality also save timsort
+  significant pointer-copying costs, and allow it to have a smaller working
+  set.)
+
++ Across about four hours of generating random arrays, and sorting them
+  under both methods, samplesort required about 1.5% more comparisons
+  (the program is at the end of this file).
+
++ In real life, this may be faster or slower on random arrays than
+  samplesort was, depending on platform quirks.  Since it does fewer
+  comparisons on average, it can be expected to do better the more
+  expensive a comparison function is.  OTOH, it does more data movement
+  (pointer copying) than samplesort, and that may negate its small
+  comparison advantage (depending on platform quirks) unless comparison
+  is very expensive.
+
++ On arrays with many kinds of pre-existing order, this blows samplesort out
+  of the water.  It's significantly faster than samplesort even on some
+  cases samplesort was special-casing the snot out of.  I believe that lists
+  very often do have exploitable partial order in real life, and this is the
+  strongest argument in favor of timsort (indeed, samplesort's special cases
+  for extreme partial order are appreciated by real users, and timsort goes
+  much deeper than those, in particular naturally covering every case where
+  someone has suggested "and it would be cool if list.sort() had a special
+  case for this too ... and for that ...").
+
++ Here are exact comparison counts across all the tests in sortperf.py,
+  when run with arguments "15 20 1".
+
+  Column Key:
+      *sort: random data
+      \sort: descending data
+      /sort: ascending data
+      3sort: ascending, then 3 random exchanges
+      +sort: ascending, then 10 random at the end
+      ~sort: many duplicates
+      =sort: all equal
+      !sort: worst case scenario
+
+  First the trivial cases, trivial for samplesort because it special-cased
+  them, and trivial for timsort because it naturally works on runs.  Within
+  an "n" block, the first line gives the # of compares done by samplesort,
+  the second line by timsort, and the third line is the percentage by
+  which the samplesort count exceeds the timsort count:
+
+      n   \sort   /sort   =sort
+-------  ------  ------  ------
+  32768   32768   32767   32767  samplesort
+          32767   32767   32767  timsort
+          0.00%   0.00%   0.00%  (samplesort - timsort) / timsort
+
+  65536   65536   65535   65535
+          65535   65535   65535
+          0.00%   0.00%   0.00%
+
+ 131072  131072  131071  131071
+         131071  131071  131071
+          0.00%   0.00%   0.00%
+
+ 262144  262144  262143  262143
+         262143  262143  262143
+          0.00%   0.00%   0.00%
+
+ 524288  524288  524287  524287
+         524287  524287  524287
+          0.00%   0.00%   0.00%
+
+1048576 1048576 1048575 1048575
+        1048575 1048575 1048575
+          0.00%   0.00%   0.00%
+
+  The algorithms are effectively identical in these cases, except that
+  timsort does one less compare in \sort.
+
+  Now for the more interesting cases.  lg(n!) is the information-theoretic
+  limit for the best any comparison-based sorting algorithm can do on
+  average (across all permutations).  When a method gets significantly
+  below that, it's either astronomically lucky, or is finding exploitable
+  structure in the data.
+
+      n   lg(n!)    *sort    3sort     +sort   %sort    ~sort     !sort
+-------  -------   ------   -------  -------  ------  -------  --------
+  32768   444255   453096   453614    32908   452871   130491    469141 old
+                   448885    33016    33007    50426   182083     65534 new
+                    0.94% 1273.92%   -0.30%  798.09%  -28.33%   615.87% %ch from new
+
+  65536   954037   972699   981940    65686   973104   260029   1004607
+                   962991    65821    65808   101667   364341    131070
+                    1.01% 1391.83%   -0.19%  857.15%  -28.63%   666.47%
+
+ 131072  2039137  2101881  2091491   131232  2092894   554790   2161379
+                  2057533   131410   131361   206193   728871    262142
+                    2.16% 1491.58%   -0.10%  915.02%  -23.88%   724.51%
+
+ 262144  4340409  4464460  4403233   262314  4445884  1107842   4584560
+                  4377402   262437   262459   416347  1457945    524286
+                    1.99% 1577.82%   -0.06%  967.83%  -24.01%   774.44%
+
+ 524288  9205096  9453356  9408463   524468  9441930  2218577   9692015
+                  9278734   524580   524633   837947  2916107   1048574
+                   1.88%  1693.52%   -0.03% 1026.79%  -23.92%   824.30%
+
+1048576 19458756 19950272 19838588  1048766 19912134  4430649  20434212
+                 19606028  1048958  1048941  1694896  5832445   2097150
+                    1.76% 1791.27%   -0.02% 1074.83%  -24.03%   874.38%
+
+  Discussion of cases:
+
+  *sort:  There's no structure in random data to exploit, so the theoretical
+  limit is lg(n!).  Both methods get close to that, and timsort is hugging
+  it (indeed, in a *marginal* sense, it's a spectacular improvement --
+  there's only about 1% left before hitting the wall, and timsort knows
+  darned well it's doing compares that won't pay on random data -- but so
+  does the samplesort hybrid).  For contrast, Hoare's original random-pivot
+  quicksort does about 39% more compares than the limit, and the median-of-3
+  variant about 19% more.
+
+  3sort, %sort, and !sort:  No contest; there's structure in this data, but
+  not of the specific kinds samplesort special-cases.  Note that structure
+  in !sort wasn't put there on purpose -- it was crafted as a worst case for
+  a previous quicksort implementation.  That timsort nails it came as a
+  surprise to me (although it's obvious in retrospect).
+
+  +sort:  samplesort special-cases this data, and does a few less compares
+  than timsort.  However, timsort runs this case significantly faster on all
+  boxes we have timings for, because timsort is in the business of merging
+  runs efficiently, while samplesort does much more data movement in this
+  (for it) special case.
+
+  ~sort:  samplesort's special cases for large masses of equal elements are
+  extremely effective on ~sort's specific data pattern, and timsort just
+  isn't going to get close to that, despite that it's clearly getting a
+  great deal of benefit out of the duplicates (the # of compares is much less
+  than lg(n!)).  ~sort has a perfectly uniform distribution of just 4
+  distinct values, and as the distribution gets more skewed, samplesort's
+  equal-element gimmicks become less effective, while timsort's adaptive
+  strategies find more to exploit; in a database supplied by Kevin Altis, a
+  sort on its highly skewed "on which stock exchange does this company's
+  stock trade?" field ran over twice as fast under timsort.
+
+  However, despite that timsort does many more comparisons on ~sort, and
+  that on several platforms ~sort runs highly significantly slower under
+  timsort, on other platforms ~sort runs highly significantly faster under
+  timsort.  No other kind of data has shown this wild x-platform behavior,
+  and we don't have an explanation for it.  The only thing I can think of
+  that could transform what "should be" highly significant slowdowns into
+  highly significant speedups on some boxes are catastrophic cache effects
+  in samplesort.
+
+  But timsort "should be" slower than samplesort on ~sort, so it's hard
+  to count that it isn't on some boxes as a strike against it <wink>.
+
++ Here's the highwater mark for the number of heap-based temp slots (4
+  bytes each on this box) needed by each test, again with arguments
+  "15 20 1":
+
+   2**i  *sort \sort /sort  3sort  +sort  %sort  ~sort  =sort  !sort
+  32768  16384     0     0   6256      0  10821  12288      0  16383
+  65536  32766     0     0  21652      0  31276  24576      0  32767
+ 131072  65534     0     0  17258      0  58112  49152      0  65535
+ 262144 131072     0     0  35660      0 123561  98304      0 131071
+ 524288 262142     0     0  31302      0 212057 196608      0 262143
+1048576 524286     0     0 312438      0 484942 393216      0 524287
+
+  Discussion:  The tests that end up doing (close to) perfectly balanced
+  merges (*sort, !sort) need all N//2 temp slots (or almost all).  ~sort
+  also ends up doing balanced merges, but systematically benefits a lot from
+  the preliminary pre-merge searches described under "Merge Memory" later.
+  %sort approaches having a balanced merge at the end because the random
+  selection of elements to replace is expected to produce an out-of-order
+  element near the midpoint.  \sort, /sort, =sort are the trivial one-run
+  cases, needing no merging at all.  +sort ends up having one very long run
+  and one very short, and so gets all the temp space it needs from the small
+  temparray member of the MergeState struct (note that the same would be
+  true if the new random elements were prefixed to the sorted list instead,
+  but not if they appeared "in the middle").  3sort approaches N//3 temp
+  slots twice, but the run lengths that remain after 3 random exchanges
+  clearly has very high variance.
+
+
+A detailed description of timsort follows.
+
+Runs
+----
+count_run() returns the # of elements in the next run.  A run is either
+"ascending", which means non-decreasing:
+
+    a0 <= a1 <= a2 <= ...
+
+or "descending", which means strictly decreasing:
+
+    a0 > a1 > a2 > ...
+
+Note that a run is always at least 2 long, unless we start at the array's
+last element.
+
+The definition of descending is strict, because the main routine reverses
+a descending run in-place, transforming a descending run into an ascending
+run.  Reversal is done via the obvious fast "swap elements starting at each
+end, and converge at the middle" method, and that can violate stability if
+the slice contains any equal elements.  Using a strict definition of
+descending ensures that a descending run contains distinct elements.
+
+If an array is random, it's very unlikely we'll see long runs.  If a natural
+run contains less than minrun elements (see next section), the main loop
+artificially boosts it to minrun elements, via a stable binary insertion sort
+applied to the right number of array elements following the short natural
+run.  In a random array, *all* runs are likely to be minrun long as a
+result.  This has two primary good effects:
+
+1. Random data strongly tends then toward perfectly balanced (both runs have
+   the same length) merges, which is the most efficient way to proceed when
+   data is random.
+
+2. Because runs are never very short, the rest of the code doesn't make
+   heroic efforts to shave a few cycles off per-merge overheads.  For
+   example, reasonable use of function calls is made, rather than trying to
+   inline everything.  Since there are no more than N/minrun runs to begin
+   with, a few "extra" function calls per merge is barely measurable.
+
+
+Computing minrun
+----------------
+If N < 64, minrun is N.  IOW, binary insertion sort is used for the whole
+array then; it's hard to beat that given the overheads of trying something
+fancier.
+
+When N is a power of 2, testing on random data showed that minrun values of
+16, 32, 64 and 128 worked about equally well.  At 256 the data-movement cost
+in binary insertion sort clearly hurt, and at 8 the increase in the number
+of function calls clearly hurt.  Picking *some* power of 2 is important
+here, so that the merges end up perfectly balanced (see next section).  We
+pick 32 as a good value in the sweet range; picking a value at the low end
+allows the adaptive gimmicks more opportunity to exploit shorter natural
+runs.
+
+Because sortperf.py only tries powers of 2, it took a long time to notice
+that 32 isn't a good choice for the general case!  Consider N=2112:
+
+>>> divmod(2112, 32)
+(66, 0)
+>>>
+
+If the data is randomly ordered, we're very likely to end up with 66 runs
+each of length 32.  The first 64 of these trigger a sequence of perfectly
+balanced merges (see next section), leaving runs of lengths 2048 and 64 to
+merge at the end.  The adaptive gimmicks can do that with fewer than 2048+64
+compares, but it's still more compares than necessary, and-- mergesort's
+bugaboo relative to samplesort --a lot more data movement (O(N) copies just
+to get 64 elements into place).
+
+If we take minrun=33 in this case, then we're very likely to end up with 64
+runs each of length 33, and then all merges are perfectly balanced.  Better!
+
+What we want to avoid is picking minrun such that in
+
+    q, r = divmod(N, minrun)
+
+q is a power of 2 and r>0 (then the last merge only gets r elements into
+place, and r < minrun is small compared to N), or q a little larger than a
+power of 2 regardless of r (then we've got a case similar to "2112", again
+leaving too little work for the last merge to do).
+
+Instead we pick a minrun in range(32, 65) such that N/minrun is exactly a
+power of 2, or if that isn't possible, is close to, but strictly less than,
+a power of 2.  This is easier to do than it may sound:  take the first 6
+bits of N, and add 1 if any of the remaining bits are set.  In fact, that
+rule covers every case in this section, including small N and exact powers
+of 2; merge_compute_minrun() is a deceptively simple function.
+
+
+The Merge Pattern
+-----------------
+In order to exploit regularities in the data, we're merging on natural
+run lengths, and they can become wildly unbalanced.  That's a Good Thing
+for this sort!  It means we have to find a way to manage an assortment of
+potentially very different run lengths, though.
+
+Stability constrains permissible merging patterns.  For example, if we have
+3 consecutive runs of lengths
+
+    A:10000  B:20000  C:10000
+
+we dare not merge A with C first, because if A, B and C happen to contain
+a common element, it would get out of order wrt its occurrence(s) in B.  The
+merging must be done as (A+B)+C or A+(B+C) instead.
+
+So merging is always done on two consecutive runs at a time, and in-place,
+although this may require some temp memory (more on that later).
+
+When a run is identified, its base address and length are pushed on a stack
+in the MergeState struct.  merge_collapse() is then called to see whether it
+should merge it with preceding run(s).  We would like to delay merging as
+long as possible in order to exploit patterns that may come up later, but we
+like even more to do merging as soon as possible to exploit that the run just
+found is still high in the memory hierarchy.  We also can't delay merging
+"too long" because it consumes memory to remember the runs that are still
+unmerged, and the stack has a fixed size.
+
+What turned out to be a good compromise maintains two invariants on the
+stack entries, where A, B and C are the lengths of the three righmost not-yet
+merged slices:
+
+1.  A > B+C
+2.  B > C
+
+Note that, by induction, #2 implies the lengths of pending runs form a
+decreasing sequence.  #1 implies that, reading the lengths right to left,
+the pending-run lengths grow at least as fast as the Fibonacci numbers.
+Therefore the stack can never grow larger than about log_base_phi(N) entries,
+where phi = (1+sqrt(5))/2 ~= 1.618.  Thus a small # of stack slots suffice
+for very large arrays.
+
+If A <= B+C, the smaller of A and C is merged with B (ties favor C, for the
+freshness-in-cache reason), and the new run replaces the A,B or B,C entries;
+e.g., if the last 3 entries are
+
+    A:30  B:20  C:10
+
+then B is merged with C, leaving
+
+    A:30  BC:30
+
+on the stack.  Or if they were
+
+    A:500  B:400:  C:1000
+
+then A is merged with B, leaving
+
+    AB:900  C:1000
+
+on the stack.
+
+In both examples, the stack configuration after the merge still violates
+invariant #2, and merge_collapse() goes on to continue merging runs until
+both invariants are satisfied.  As an extreme case, suppose we didn't do the
+minrun gimmick, and natural runs were of lengths 128, 64, 32, 16, 8, 4, 2,
+and 2.  Nothing would get merged until the final 2 was seen, and that would
+trigger 7 perfectly balanced merges.
+
+The thrust of these rules when they trigger merging is to balance the run
+lengths as closely as possible, while keeping a low bound on the number of
+runs we have to remember.  This is maximally effective for random data,
+where all runs are likely to be of (artificially forced) length minrun, and
+then we get a sequence of perfectly balanced merges (with, perhaps, some
+oddballs at the end).
+
+OTOH, one reason this sort is so good for partly ordered data has to do
+with wildly unbalanced run lengths.
+
+
+Merge Memory
+------------
+Merging adjacent runs of lengths A and B in-place is very difficult.
+Theoretical constructions are known that can do it, but they're too difficult
+and slow for practical use.  But if we have temp memory equal to min(A, B),
+it's easy.
+
+If A is smaller (function merge_lo), copy A to a temp array, leave B alone,
+and then we can do the obvious merge algorithm left to right, from the temp
+area and B, starting the stores into where A used to live.  There's always a
+free area in the original area comprising a number of elements equal to the
+number not yet merged from the temp array (trivially true at the start;
+proceed by induction).  The only tricky bit is that if a comparison raises an
+exception, we have to remember to copy the remaining elements back in from
+the temp area, lest the array end up with duplicate entries from B.  But
+that's exactly the same thing we need to do if we reach the end of B first,
+so the exit code is pleasantly common to both the normal and error cases.
+
+If B is smaller (function merge_hi, which is merge_lo's "mirror image"),
+much the same, except that we need to merge right to left, copying B into a
+temp array and starting the stores at the right end of where B used to live.
+
+A refinement:  When we're about to merge adjacent runs A and B, we first do
+a form of binary search (more on that later) to see where B[0] should end up
+in A.  Elements in A preceding that point are already in their final
+positions, effectively shrinking the size of A.  Likewise we also search to
+see where A[-1] should end up in B, and elements of B after that point can
+also be ignored.  This cuts the amount of temp memory needed by the same
+amount.
+
+These preliminary searches may not pay off, and can be expected *not* to
+repay their cost if the data is random.  But they can win huge in all of
+time, copying, and memory savings when they do pay, so this is one of the
+"per-merge overheads" mentioned above that we're happy to endure because
+there is at most one very short run.  It's generally true in this algorithm
+that we're willing to gamble a little to win a lot, even though the net
+expectation is negative for random data.
+
+
+Merge Algorithms
+----------------
+merge_lo() and merge_hi() are where the bulk of the time is spent.  merge_lo
+deals with runs where A <= B, and merge_hi where A > B.  They don't know
+whether the data is clustered or uniform, but a lovely thing about merging
+is that many kinds of clustering "reveal themselves" by how many times in a
+row the winning merge element comes from the same run.  We'll only discuss
+merge_lo here; merge_hi is exactly analogous.
+
+Merging begins in the usual, obvious way, comparing the first element of A
+to the first of B, and moving B[0] to the merge area if it's less than A[0],
+else moving A[0] to the merge area.  Call that the "one pair at a time"
+mode.  The only twist here is keeping track of how many times in a row "the
+winner" comes from the same run.
+
+If that count reaches MIN_GALLOP, we switch to "galloping mode".  Here
+we *search* B for where A[0] belongs, and move over all the B's before
+that point in one chunk to the merge area, then move A[0] to the merge
+area.  Then we search A for where B[0] belongs, and similarly move a
+slice of A in one chunk.  Then back to searching B for where A[0] belongs,
+etc.  We stay in galloping mode until both searches find slices to copy
+less than MIN_GALLOP elements long, at which point we go back to one-pair-
+at-a-time mode.
+
+A refinement:  The MergeState struct contains the value of min_gallop that
+controls when we enter galloping mode, initialized to MIN_GALLOP.
+merge_lo() and merge_hi() adjust this higher when galloping isn't paying
+off, and lower when it is.
+
+
+Galloping
+---------
+Still without loss of generality, assume A is the shorter run.  In galloping
+mode, we first look for A[0] in B.  We do this via "galloping", comparing
+A[0] in turn to B[0], B[1], B[3], B[7], ..., B[2**j - 1], ..., until finding
+the k such that B[2**(k-1) - 1] < A[0] <= B[2**k - 1].  This takes at most
+roughly lg(B) comparisons, and, unlike a straight binary search, favors
+finding the right spot early in B (more on that later).
+
+After finding such a k, the region of uncertainty is reduced to 2**(k-1) - 1
+consecutive elements, and a straight binary search requires exactly k-1
+additional comparisons to nail it.  Then we copy all the B's up to that
+point in one chunk, and then copy A[0].  Note that no matter where A[0]
+belongs in B, the combination of galloping + binary search finds it in no
+more than about 2*lg(B) comparisons.
+
+If we did a straight binary search, we could find it in no more than
+ceiling(lg(B+1)) comparisons -- but straight binary search takes that many
+comparisons no matter where A[0] belongs.  Straight binary search thus loses
+to galloping unless the run is quite long, and we simply can't guess
+whether it is in advance.
+
+If data is random and runs have the same length, A[0] belongs at B[0] half
+the time, at B[1] a quarter of the time, and so on:  a consecutive winning
+sub-run in B of length k occurs with probability 1/2**(k+1).  So long
+winning sub-runs are extremely unlikely in random data, and guessing that a
+winning sub-run is going to be long is a dangerous game.
+
+OTOH, if data is lopsided or lumpy or contains many duplicates, long
+stretches of winning sub-runs are very likely, and cutting the number of
+comparisons needed to find one from O(B) to O(log B) is a huge win.
+
+Galloping compromises by getting out fast if there isn't a long winning
+sub-run, yet finding such very efficiently when they exist.
+
+I first learned about the galloping strategy in a related context; see:
+
+    "Adaptive Set Intersections, Unions, and Differences" (2000)
+    Erik D. Demaine, Alejandro López-Ortiz, J. Ian Munro
+
+and its followup(s).  An earlier paper called the same strategy
+"exponential search":
+
+   "Optimistic Sorting and Information Theoretic Complexity"
+   Peter McIlroy
+   SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms), pp
+   467-474, Austin, Texas, 25-27 January 1993.
+
+and it probably dates back to an earlier paper by Bentley and Yao.  The
+McIlroy paper in particular has good analysis of a mergesort that's
+probably strongly related to this one in its galloping strategy.
+
+
+Galloping with a Broken Leg
+---------------------------
+So why don't we always gallop?  Because it can lose, on two counts:
+
+1. While we're willing to endure small per-merge overheads, per-comparison
+   overheads are a different story.  Calling Yet Another Function per
+   comparison is expensive, and gallop_left() and gallop_right() are
+   too long-winded for sane inlining.
+
+2. Galloping can-- alas --require more comparisons than linear one-at-time
+   search, depending on the data.
+
+#2 requires details.  If A[0] belongs before B[0], galloping requires 1
+compare to determine that, same as linear search, except it costs more
+to call the gallop function.  If A[0] belongs right before B[1], galloping
+requires 2 compares, again same as linear search.  On the third compare,
+galloping checks A[0] against B[3], and if it's <=, requires one more
+compare to determine whether A[0] belongs at B[2] or B[3].  That's a total
+of 4 compares, but if A[0] does belong at B[2], linear search would have
+discovered that in only 3 compares, and that's a huge loss!  Really.  It's
+an increase of 33% in the number of compares needed, and comparisons are
+expensive in Python.
+
+index in B where    # compares linear  # gallop  # binary  gallop
+A[0] belongs        search needs       compares  compares  total
+----------------    -----------------  --------  --------  ------
+               0                    1         1         0       1
+
+               1                    2         2         0       2
+
+               2                    3         3         1       4
+               3                    4         3         1       4
+
+               4                    5         4         2       6
+               5                    6         4         2       6
+               6                    7         4         2       6
+               7                    8         4         2       6
+
+               8                    9         5         3       8
+               9                   10         5         3       8
+              10                   11         5         3       8
+              11                   12         5         3       8
+                                        ...
+
+In general, if A[0] belongs at B[i], linear search requires i+1 comparisons
+to determine that, and galloping a total of 2*floor(lg(i))+2 comparisons.
+The advantage of galloping is unbounded as i grows, but it doesn't win at
+all until i=6.  Before then, it loses twice (at i=2 and i=4), and ties
+at the other values.  At and after i=6, galloping always wins.
+
+We can't guess in advance when it's going to win, though, so we do one pair
+at a time until the evidence seems strong that galloping may pay.  MIN_GALLOP
+is 7, and that's pretty strong evidence.  However, if the data is random, it
+simply will trigger galloping mode purely by luck every now and again, and
+it's quite likely to hit one of the losing cases next.  On the other hand,
+in cases like ~sort, galloping always pays, and MIN_GALLOP is larger than it
+"should be" then.  So the MergeState struct keeps a min_gallop variable
+that merge_lo and merge_hi adjust:  the longer we stay in galloping mode,
+the smaller min_gallop gets, making it easier to transition back to
+galloping mode (if we ever leave it in the current merge, and at the
+start of the next merge).  But whenever the gallop loop doesn't pay,
+min_gallop is increased by one, making it harder to transition back
+to galloping mode (and again both within a merge and across merges).  For
+random data, this all but eliminates the gallop penalty:  min_gallop grows
+large enough that we almost never get into galloping mode.  And for cases
+like ~sort, min_gallop can fall to as low as 1.  This seems to work well,
+but in all it's a minor improvement over using a fixed MIN_GALLOP value.
+
+
+Galloping Complication
+----------------------
+The description above was for merge_lo.  merge_hi has to merge "from the
+other end", and really needs to gallop starting at the last element in a run
+instead of the first.  Galloping from the first still works, but does more
+comparisons than it should (this is significant -- I timed it both ways).
+For this reason, the gallop_left() and gallop_right() functions have a
+"hint" argument, which is the index at which galloping should begin.  So
+galloping can actually start at any index, and proceed at offsets of 1, 3,
+7, 15, ... or -1, -3, -7, -15, ... from the starting index.
+
+In the code as I type it's always called with either 0 or n-1 (where n is
+the # of elements in a run).  It's tempting to try to do something fancier,
+melding galloping with some form of interpolation search; for example, if
+we're merging a run of length 1 with a run of length 10000, index 5000 is
+probably a better guess at the final result than either 0 or 9999.  But
+it's unclear how to generalize that intuition usefully, and merging of
+wildly unbalanced runs already enjoys excellent performance.
+
+~sort is a good example of when balanced runs could benefit from a better
+hint value:  to the extent possible, this would like to use a starting
+offset equal to the previous value of acount/bcount.  Doing so saves about
+10% of the compares in ~sort.  However, doing so is also a mixed bag,
+hurting other cases.
+
+
+Comparing Average # of Compares on Random Arrays
+------------------------------------------------
+[NOTE:  This was done when the new algorithm used about 0.1% more compares
+ on random data than does its current incarnation.]
+
+Here list.sort() is samplesort, and list.msort() this sort:
+
+"""
+import random
+from time import clock as now
+
+def fill(n):
+    from random import random
+    return [random() for i in xrange(n)]
+
+def mycmp(x, y):
+    global ncmp
+    ncmp += 1
+    return cmp(x, y)
+
+def timeit(values, method):
+    global ncmp
+    X = values[:]
+    bound = getattr(X, method)
+    ncmp = 0
+    t1 = now()
+    bound(mycmp)
+    t2 = now()
+    return t2-t1, ncmp
+
+format = "%5s  %9.2f  %11d"
+f2     = "%5s  %9.2f  %11.2f"
+
+def drive():
+    count = sst = sscmp = mst = mscmp = nelts = 0
+    while True:
+        n = random.randrange(100000)
+        nelts += n
+        x = fill(n)
+
+        t, c = timeit(x, 'sort')
+        sst += t
+        sscmp += c
+
+        t, c = timeit(x, 'msort')
+        mst += t
+        mscmp += c
+
+        count += 1
+        if count % 10:
+            continue
+
+        print "count", count, "nelts", nelts
+        print format % ("sort",  sst, sscmp)
+        print format % ("msort", mst, mscmp)
+        print f2     % ("", (sst-mst)*1e2/mst, (sscmp-mscmp)*1e2/mscmp)
+
+drive()
+"""
+
+I ran this on Windows and kept using the computer lightly while it was
+running.  time.clock() is wall-clock time on Windows, with better than
+microsecond resolution.  samplesort started with a 1.52% #-of-comparisons
+disadvantage, fell quickly to 1.48%, and then fluctuated within that small
+range.  Here's the last chunk of output before I killed the job:
+
+count 2630 nelts 130906543
+ sort    6110.80   1937887573
+msort    6002.78   1909389381
+            1.80         1.49
+
+We've done nearly 2 billion comparisons apiece at Python speed there, and
+that's enough <wink>.
+
+For random arrays of size 2 (yes, there are only 2 interesting ones),
+samplesort has a 50%(!) comparison disadvantage.  This is a consequence of
+samplesort special-casing at most one ascending run at the start, then
+falling back to the general case if it doesn't find an ascending run
+immediately.  The consequence is that it ends up using two compares to sort
+[2, 1].  Gratifyingly, timsort doesn't do any special-casing, so had to be
+taught how to deal with mixtures of ascending and descending runs
+efficiently in all cases.
diff --git a/Python-2.7.5/Objects/lnotab_notes.txt b/Python-2.7.5/Objects/lnotab_notes.txt
new file mode 100644
index 0000000..d247edd
--- /dev/null
+++ b/Python-2.7.5/Objects/lnotab_notes.txt
@@ -0,0 +1,124 @@
+All about co_lnotab, the line number table.
+
+Code objects store a field named co_lnotab.  This is an array of unsigned bytes
+disguised as a Python string.  It is used to map bytecode offsets to source code
+line #s for tracebacks and to identify line number boundaries for line tracing.
+
+The array is conceptually a compressed list of
+    (bytecode offset increment, line number increment)
+pairs.  The details are important and delicate, best illustrated by example:
+
+    byte code offset    source code line number
+        0		    1
+        6		    2
+       50		    7
+      350                 307
+      361                 308
+
+Instead of storing these numbers literally, we compress the list by storing only
+the increments from one row to the next.  Conceptually, the stored list might
+look like:
+
+    0, 1,  6, 1,  44, 5,  300, 300,  11, 1
+
+The above doesn't really work, but it's a start. Note that an unsigned byte
+can't hold negative values, or values larger than 255, and the above example
+contains two such values. So we make two tweaks:
+
+ (a) there's a deep assumption that byte code offsets and their corresponding
+ line #s both increase monotonically, and
+ (b) if at least one column jumps by more than 255 from one row to the next,
+ more than one pair is written to the table. In case #b, there's no way to know
+ from looking at the table later how many were written.  That's the delicate
+ part.  A user of co_lnotab desiring to find the source line number
+ corresponding to a bytecode address A should do something like this
+
+    lineno = addr = 0
+    for addr_incr, line_incr in co_lnotab:
+        addr += addr_incr
+        if addr > A:
+            return lineno
+        lineno += line_incr
+
+(In C, this is implemented by PyCode_Addr2Line().)  In order for this to work,
+when the addr field increments by more than 255, the line # increment in each
+pair generated must be 0 until the remaining addr increment is < 256.  So, in
+the example above, assemble_lnotab in compile.c should not (as was actually done
+until 2.2) expand 300, 300 to
+    255, 255, 45, 45,
+but to
+    255, 0, 45, 255, 0, 45.
+
+The above is sufficient to reconstruct line numbers for tracebacks, but not for
+line tracing.  Tracing is handled by PyCode_CheckLineNumber() in codeobject.c
+and maybe_call_line_trace() in ceval.c.
+
+*** Tracing ***
+
+To a first approximation, we want to call the tracing function when the line
+number of the current instruction changes.  Re-computing the current line for
+every instruction is a little slow, though, so each time we compute the line
+number we save the bytecode indices where it's valid:
+
+     *instr_lb <= frame->f_lasti < *instr_ub
+
+is true so long as execution does not change lines.  That is, *instr_lb holds
+the first bytecode index of the current line, and *instr_ub holds the first
+bytecode index of the next line.  As long as the above expression is true,
+maybe_call_line_trace() does not need to call PyCode_CheckLineNumber().  Note
+that the same line may appear multiple times in the lnotab, either because the
+bytecode jumped more than 255 indices between line number changes or because
+the compiler inserted the same line twice.  Even in that case, *instr_ub holds
+the first index of the next line.
+
+However, we don't *always* want to call the line trace function when the above
+test fails.
+
+Consider this code:
+
+1: def f(a):
+2:    while a:
+3:       print 1,
+4:       break
+5:    else:
+6:       print 2,
+
+which compiles to this:
+
+  2           0 SETUP_LOOP              19 (to 22)
+        >>    3 LOAD_FAST                0 (a)
+              6 POP_JUMP_IF_FALSE       17
+
+  3           9 LOAD_CONST               1 (1)
+             12 PRINT_ITEM          
+
+  4          13 BREAK_LOOP          
+             14 JUMP_ABSOLUTE            3
+        >>   17 POP_BLOCK           
+
+  6          18 LOAD_CONST               2 (2)
+             21 PRINT_ITEM          
+        >>   22 LOAD_CONST               0 (None)
+             25 RETURN_VALUE        
+
+If 'a' is false, execution will jump to the POP_BLOCK instruction at offset 17
+and the co_lnotab will claim that execution has moved to line 4, which is wrong.
+In this case, we could instead associate the POP_BLOCK with line 5, but that
+would break jumps around loops without else clauses.
+
+We fix this by only calling the line trace function for a forward jump if the
+co_lnotab indicates we have jumped to the *start* of a line, i.e. if the current
+instruction offset matches the offset given for the start of a line by the
+co_lnotab.  For backward jumps, however, we always call the line trace function,
+which lets a debugger stop on every evaluation of a loop guard (which usually
+won't be the first opcode in a line).
+
+Why do we set f_lineno when tracing, and only just before calling the trace
+function?  Well, consider the code above when 'a' is true.  If stepping through
+this with 'n' in pdb, you would stop at line 1 with a "call" type event, then
+line events on lines 2, 3, and 4, then a "return" type event -- but because the
+code for the return actually falls in the range of the "line 6" opcodes, you
+would be shown line 6 during this event.  This is a change from the behaviour in
+2.2 and before, and I've found it confusing in practice.  By setting and using
+f_lineno when tracing, one can report a line number different from that
+suggested by f_lasti on this one occasion where it's desirable.
diff --git a/Python-2.7.5/Objects/longobject.c b/Python-2.7.5/Objects/longobject.c
new file mode 100644
index 0000000..fb740dc
--- /dev/null
+++ b/Python-2.7.5/Objects/longobject.c
@@ -0,0 +1,4395 @@
+/* Long (arbitrary precision) integer object implementation */
+
+/* XXX The functional organization of this file is terrible */
+
+#include "Python.h"
+#include "longintrepr.h"
+#include "structseq.h"
+
+#include <float.h>
+#include <ctype.h>
+#include <stddef.h>
+
+/* For long multiplication, use the O(N**2) school algorithm unless
+ * both operands contain more than KARATSUBA_CUTOFF digits (this
+ * being an internal Python long digit, in base PyLong_BASE).
+ */
+#define KARATSUBA_CUTOFF 70
+#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)
+
+/* For exponentiation, use the binary left-to-right algorithm
+ * unless the exponent contains more than FIVEARY_CUTOFF digits.
+ * In that case, do 5 bits at a time.  The potential drawback is that
+ * a table of 2**5 intermediate results is computed.
+ */
+#define FIVEARY_CUTOFF 8
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+#undef MIN
+#undef MAX
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) > (y) ? (y) : (x))
+
+#define SIGCHECK(PyTryBlock)                            \
+    do {                                                \
+        if (--_Py_Ticker < 0) {                         \
+            _Py_Ticker = _Py_CheckInterval;             \
+            if (PyErr_CheckSignals()) PyTryBlock        \
+                                          }             \
+    } while(0)
+
+/* Normalize (remove leading zeros from) a long int object.
+   Doesn't attempt to free the storage--in most cases, due to the nature
+   of the algorithms used, this could save at most be one word anyway. */
+
+static PyLongObject *
+long_normalize(register PyLongObject *v)
+{
+    Py_ssize_t j = ABS(Py_SIZE(v));
+    Py_ssize_t i = j;
+
+    while (i > 0 && v->ob_digit[i-1] == 0)
+        --i;
+    if (i != j)
+        Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i;
+    return v;
+}
+
+/* Allocate a new long int object with size digits.
+   Return NULL and set exception if we run out of memory. */
+
+#define MAX_LONG_DIGITS \
+    ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit))
+
+PyLongObject *
+_PyLong_New(Py_ssize_t size)
+{
+    if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "too many digits in integer");
+        return NULL;
+    }
+    /* coverity[ampersand_in_size] */
+    /* XXX(nnorwitz): PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect
+       overflow */
+    return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
+}
+
+PyObject *
+_PyLong_Copy(PyLongObject *src)
+{
+    PyLongObject *result;
+    Py_ssize_t i;
+
+    assert(src != NULL);
+    i = src->ob_size;
+    if (i < 0)
+        i = -(i);
+    result = _PyLong_New(i);
+    if (result != NULL) {
+        result->ob_size = src->ob_size;
+        while (--i >= 0)
+            result->ob_digit[i] = src->ob_digit[i];
+    }
+    return (PyObject *)result;
+}
+
+/* Create a new long int object from a C long int */
+
+PyObject *
+PyLong_FromLong(long ival)
+{
+    PyLongObject *v;
+    unsigned long abs_ival;
+    unsigned long t;  /* unsigned so >> doesn't propagate sign bit */
+    int ndigits = 0;
+    int negative = 0;
+
+    if (ival < 0) {
+        /* if LONG_MIN == -LONG_MAX-1 (true on most platforms) then
+           ANSI C says that the result of -ival is undefined when ival
+           == LONG_MIN.  Hence the following workaround. */
+        abs_ival = (unsigned long)(-1-ival) + 1;
+        negative = 1;
+    }
+    else {
+        abs_ival = (unsigned long)ival;
+    }
+
+    /* Count the number of Python digits.
+       We used to pick 5 ("big enough for anything"), but that's a
+       waste of time and space given that 5*15 = 75 bits are rarely
+       needed. */
+    t = abs_ival;
+    while (t) {
+        ++ndigits;
+        t >>= PyLong_SHIFT;
+    }
+    v = _PyLong_New(ndigits);
+    if (v != NULL) {
+        digit *p = v->ob_digit;
+        v->ob_size = negative ? -ndigits : ndigits;
+        t = abs_ival;
+        while (t) {
+            *p++ = (digit)(t & PyLong_MASK);
+            t >>= PyLong_SHIFT;
+        }
+    }
+    return (PyObject *)v;
+}
+
+/* Create a new long int object from a C unsigned long int */
+
+PyObject *
+PyLong_FromUnsignedLong(unsigned long ival)
+{
+    PyLongObject *v;
+    unsigned long t;
+    int ndigits = 0;
+
+    /* Count the number of Python digits. */
+    t = (unsigned long)ival;
+    while (t) {
+        ++ndigits;
+        t >>= PyLong_SHIFT;
+    }
+    v = _PyLong_New(ndigits);
+    if (v != NULL) {
+        digit *p = v->ob_digit;
+        Py_SIZE(v) = ndigits;
+        while (ival) {
+            *p++ = (digit)(ival & PyLong_MASK);
+            ival >>= PyLong_SHIFT;
+        }
+    }
+    return (PyObject *)v;
+}
+
+/* Create a new long int object from a C double */
+
+PyObject *
+PyLong_FromDouble(double dval)
+{
+    PyLongObject *v;
+    double frac;
+    int i, ndig, expo, neg;
+    neg = 0;
+    if (Py_IS_INFINITY(dval)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "cannot convert float infinity to integer");
+        return NULL;
+    }
+    if (Py_IS_NAN(dval)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "cannot convert float NaN to integer");
+        return NULL;
+    }
+    if (dval < 0.0) {
+        neg = 1;
+        dval = -dval;
+    }
+    frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
+    if (expo <= 0)
+        return PyLong_FromLong(0L);
+    ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */
+    v = _PyLong_New(ndig);
+    if (v == NULL)
+        return NULL;
+    frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);
+    for (i = ndig; --i >= 0; ) {
+        digit bits = (digit)frac;
+        v->ob_digit[i] = bits;
+        frac = frac - (double)bits;
+        frac = ldexp(frac, PyLong_SHIFT);
+    }
+    if (neg)
+        Py_SIZE(v) = -(Py_SIZE(v));
+    return (PyObject *)v;
+}
+
+/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define
+ * anything about what happens when a signed integer operation overflows,
+ * and some compilers think they're doing you a favor by being "clever"
+ * then.  The bit pattern for the largest postive signed long is
+ * (unsigned long)LONG_MAX, and for the smallest negative signed long
+ * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.
+ * However, some other compilers warn about applying unary minus to an
+ * unsigned operand.  Hence the weird "0-".
+ */
+#define PY_ABS_LONG_MIN         (0-(unsigned long)LONG_MIN)
+#define PY_ABS_SSIZE_T_MIN      (0-(size_t)PY_SSIZE_T_MIN)
+
+/* Get a C long int from a Python long or Python int object.
+   On overflow, returns -1 and sets *overflow to 1 or -1 depending
+   on the sign of the result.  Otherwise *overflow is 0.
+
+   For other errors (e.g., type error), returns -1 and sets an error
+   condition.
+*/
+
+long
+PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
+{
+    /* This version by Tim Peters */
+    register PyLongObject *v;
+    unsigned long x, prev;
+    long res;
+    Py_ssize_t i;
+    int sign;
+    int do_decref = 0; /* if nb_int was called */
+
+    *overflow = 0;
+    if (vv == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+
+    if(PyInt_Check(vv))
+        return PyInt_AsLong(vv);
+
+    if (!PyLong_Check(vv)) {
+        PyNumberMethods *nb;
+        nb = vv->ob_type->tp_as_number;
+        if (nb == NULL || nb->nb_int == NULL) {
+            PyErr_SetString(PyExc_TypeError,
+                            "an integer is required");
+            return -1;
+        }
+        vv = (*nb->nb_int) (vv);
+        if (vv == NULL)
+            return -1;
+        do_decref = 1;
+        if(PyInt_Check(vv)) {
+            res = PyInt_AsLong(vv);
+            goto exit;
+        }
+        if (!PyLong_Check(vv)) {
+            Py_DECREF(vv);
+            PyErr_SetString(PyExc_TypeError,
+                            "nb_int should return int object");
+            return -1;
+        }
+    }
+
+    res = -1;
+    v = (PyLongObject *)vv;
+    i = Py_SIZE(v);
+
+    switch (i) {
+    case -1:
+        res = -(sdigit)v->ob_digit[0];
+        break;
+    case 0:
+        res = 0;
+        break;
+    case 1:
+        res = v->ob_digit[0];
+        break;
+    default:
+        sign = 1;
+        x = 0;
+        if (i < 0) {
+            sign = -1;
+            i = -(i);
+        }
+        while (--i >= 0) {
+            prev = x;
+            x = (x << PyLong_SHIFT) + v->ob_digit[i];
+            if ((x >> PyLong_SHIFT) != prev) {
+                *overflow = sign;
+                goto exit;
+            }
+        }
+        /* Haven't lost any bits, but casting to long requires extra
+         * care (see comment above).
+         */
+        if (x <= (unsigned long)LONG_MAX) {
+            res = (long)x * sign;
+        }
+        else if (sign < 0 && x == PY_ABS_LONG_MIN) {
+            res = LONG_MIN;
+        }
+        else {
+            *overflow = sign;
+            /* res is already set to -1 */
+        }
+    }
+  exit:
+    if (do_decref) {
+        Py_DECREF(vv);
+    }
+    return res;
+}
+
+/* Get a C long int from a long int object.
+   Returns -1 and sets an error condition if overflow occurs. */
+
+long
+PyLong_AsLong(PyObject *obj)
+{
+    int overflow;
+    long result = PyLong_AsLongAndOverflow(obj, &overflow);
+    if (overflow) {
+        /* XXX: could be cute and give a different
+           message for overflow == -1 */
+        PyErr_SetString(PyExc_OverflowError,
+                        "Python int too large to convert to C long");
+    }
+    return result;
+}
+
+/* Get a C int from a long int object or any object that has an __int__
+   method.  Return -1 and set an error if overflow occurs. */
+
+int
+_PyLong_AsInt(PyObject *obj)
+{
+    int overflow;
+    long result = PyLong_AsLongAndOverflow(obj, &overflow);
+    if (overflow || result > INT_MAX || result < INT_MIN) {
+        /* XXX: could be cute and give a different
+           message for overflow == -1 */
+        PyErr_SetString(PyExc_OverflowError,
+                        "Python int too large to convert to C int");
+        return -1;
+    }
+    return (int)result;
+}
+
+/* Get a Py_ssize_t from a long int object.
+   Returns -1 and sets an error condition if overflow occurs. */
+
+Py_ssize_t
+PyLong_AsSsize_t(PyObject *vv) {
+    register PyLongObject *v;
+    size_t x, prev;
+    Py_ssize_t i;
+    int sign;
+
+    if (vv == NULL || !PyLong_Check(vv)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    v = (PyLongObject *)vv;
+    i = v->ob_size;
+    sign = 1;
+    x = 0;
+    if (i < 0) {
+        sign = -1;
+        i = -(i);
+    }
+    while (--i >= 0) {
+        prev = x;
+        x = (x << PyLong_SHIFT) | v->ob_digit[i];
+        if ((x >> PyLong_SHIFT) != prev)
+            goto overflow;
+    }
+    /* Haven't lost any bits, but casting to a signed type requires
+     * extra care (see comment above).
+     */
+    if (x <= (size_t)PY_SSIZE_T_MAX) {
+        return (Py_ssize_t)x * sign;
+    }
+    else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {
+        return PY_SSIZE_T_MIN;
+    }
+    /* else overflow */
+
+  overflow:
+    PyErr_SetString(PyExc_OverflowError,
+                    "long int too large to convert to int");
+    return -1;
+}
+
+/* Get a C unsigned long int from a long int object.
+   Returns -1 and sets an error condition if overflow occurs. */
+
+unsigned long
+PyLong_AsUnsignedLong(PyObject *vv)
+{
+    register PyLongObject *v;
+    unsigned long x, prev;
+    Py_ssize_t i;
+
+    if (vv == NULL || !PyLong_Check(vv)) {
+        if (vv != NULL && PyInt_Check(vv)) {
+            long val = PyInt_AsLong(vv);
+            if (val < 0) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value "
+                                "to unsigned long");
+                return (unsigned long) -1;
+            }
+            return val;
+        }
+        PyErr_BadInternalCall();
+        return (unsigned long) -1;
+    }
+    v = (PyLongObject *)vv;
+    i = Py_SIZE(v);
+    x = 0;
+    if (i < 0) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "can't convert negative value to unsigned long");
+        return (unsigned long) -1;
+    }
+    while (--i >= 0) {
+        prev = x;
+        x = (x << PyLong_SHIFT) | v->ob_digit[i];
+        if ((x >> PyLong_SHIFT) != prev) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "long int too large to convert");
+            return (unsigned long) -1;
+        }
+    }
+    return x;
+}
+
+/* Get a C unsigned long int from a long int object, ignoring the high bits.
+   Returns -1 and sets an error condition if an error occurs. */
+
+unsigned long
+PyLong_AsUnsignedLongMask(PyObject *vv)
+{
+    register PyLongObject *v;
+    unsigned long x;
+    Py_ssize_t i;
+    int sign;
+
+    if (vv == NULL || !PyLong_Check(vv)) {
+        if (vv != NULL && PyInt_Check(vv))
+            return PyInt_AsUnsignedLongMask(vv);
+        PyErr_BadInternalCall();
+        return (unsigned long) -1;
+    }
+    v = (PyLongObject *)vv;
+    i = v->ob_size;
+    sign = 1;
+    x = 0;
+    if (i < 0) {
+        sign = -1;
+        i = -i;
+    }
+    while (--i >= 0) {
+        x = (x << PyLong_SHIFT) | v->ob_digit[i];
+    }
+    return x * sign;
+}
+
+int
+_PyLong_Sign(PyObject *vv)
+{
+    PyLongObject *v = (PyLongObject *)vv;
+
+    assert(v != NULL);
+    assert(PyLong_Check(v));
+
+    return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1);
+}
+
+size_t
+_PyLong_NumBits(PyObject *vv)
+{
+    PyLongObject *v = (PyLongObject *)vv;
+    size_t result = 0;
+    Py_ssize_t ndigits;
+
+    assert(v != NULL);
+    assert(PyLong_Check(v));
+    ndigits = ABS(Py_SIZE(v));
+    assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+    if (ndigits > 0) {
+        digit msd = v->ob_digit[ndigits - 1];
+
+        result = (ndigits - 1) * PyLong_SHIFT;
+        if (result / PyLong_SHIFT != (size_t)(ndigits - 1))
+            goto Overflow;
+        do {
+            ++result;
+            if (result == 0)
+                goto Overflow;
+            msd >>= 1;
+        } while (msd);
+    }
+    return result;
+
+  Overflow:
+    PyErr_SetString(PyExc_OverflowError, "long has too many bits "
+                    "to express in a platform size_t");
+    return (size_t)-1;
+}
+
+PyObject *
+_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
+                      int little_endian, int is_signed)
+{
+    const unsigned char* pstartbyte;    /* LSB of bytes */
+    int incr;                           /* direction to move pstartbyte */
+    const unsigned char* pendbyte;      /* MSB of bytes */
+    size_t numsignificantbytes;         /* number of bytes that matter */
+    Py_ssize_t ndigits;                 /* number of Python long digits */
+    PyLongObject* v;                    /* result */
+    Py_ssize_t idigit = 0;              /* next free index in v->ob_digit */
+
+    if (n == 0)
+        return PyLong_FromLong(0L);
+
+    if (little_endian) {
+        pstartbyte = bytes;
+        pendbyte = bytes + n - 1;
+        incr = 1;
+    }
+    else {
+        pstartbyte = bytes + n - 1;
+        pendbyte = bytes;
+        incr = -1;
+    }
+
+    if (is_signed)
+        is_signed = *pendbyte >= 0x80;
+
+    /* Compute numsignificantbytes.  This consists of finding the most
+       significant byte.  Leading 0 bytes are insignificant if the number
+       is positive, and leading 0xff bytes if negative. */
+    {
+        size_t i;
+        const unsigned char* p = pendbyte;
+        const int pincr = -incr;  /* search MSB to LSB */
+        const unsigned char insignficant = is_signed ? 0xff : 0x00;
+
+        for (i = 0; i < n; ++i, p += pincr) {
+            if (*p != insignficant)
+                break;
+        }
+        numsignificantbytes = n - i;
+        /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so
+           actually has 2 significant bytes.  OTOH, 0xff0001 ==
+           -0x00ffff, so we wouldn't *need* to bump it there; but we
+           do for 0xffff = -0x0001.  To be safe without bothering to
+           check every case, bump it regardless. */
+        if (is_signed && numsignificantbytes < n)
+            ++numsignificantbytes;
+    }
+
+    /* How many Python long digits do we need?  We have
+       8*numsignificantbytes bits, and each Python long digit has
+       PyLong_SHIFT bits, so it's the ceiling of the quotient. */
+    /* catch overflow before it happens */
+    if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "byte array too long to convert to int");
+        return NULL;
+    }
+    ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT;
+    v = _PyLong_New(ndigits);
+    if (v == NULL)
+        return NULL;
+
+    /* Copy the bits over.  The tricky parts are computing 2's-comp on
+       the fly for signed numbers, and dealing with the mismatch between
+       8-bit bytes and (probably) 15-bit Python digits.*/
+    {
+        size_t i;
+        twodigits carry = 1;                    /* for 2's-comp calculation */
+        twodigits accum = 0;                    /* sliding register */
+        unsigned int accumbits = 0;             /* number of bits in accum */
+        const unsigned char* p = pstartbyte;
+
+        for (i = 0; i < numsignificantbytes; ++i, p += incr) {
+            twodigits thisbyte = *p;
+            /* Compute correction for 2's comp, if needed. */
+            if (is_signed) {
+                thisbyte = (0xff ^ thisbyte) + carry;
+                carry = thisbyte >> 8;
+                thisbyte &= 0xff;
+            }
+            /* Because we're going LSB to MSB, thisbyte is
+               more significant than what's already in accum,
+               so needs to be prepended to accum. */
+            accum |= (twodigits)thisbyte << accumbits;
+            accumbits += 8;
+            if (accumbits >= PyLong_SHIFT) {
+                /* There's enough to fill a Python digit. */
+                assert(idigit < ndigits);
+                v->ob_digit[idigit] = (digit)(accum & PyLong_MASK);
+                ++idigit;
+                accum >>= PyLong_SHIFT;
+                accumbits -= PyLong_SHIFT;
+                assert(accumbits < PyLong_SHIFT);
+            }
+        }
+        assert(accumbits < PyLong_SHIFT);
+        if (accumbits) {
+            assert(idigit < ndigits);
+            v->ob_digit[idigit] = (digit)accum;
+            ++idigit;
+        }
+    }
+
+    Py_SIZE(v) = is_signed ? -idigit : idigit;
+    return (PyObject *)long_normalize(v);
+}
+
+int
+_PyLong_AsByteArray(PyLongObject* v,
+                    unsigned char* bytes, size_t n,
+                    int little_endian, int is_signed)
+{
+    Py_ssize_t i;               /* index into v->ob_digit */
+    Py_ssize_t ndigits;         /* |v->ob_size| */
+    twodigits accum;            /* sliding register */
+    unsigned int accumbits;     /* # bits in accum */
+    int do_twos_comp;           /* store 2's-comp?  is_signed and v < 0 */
+    digit carry;                /* for computing 2's-comp */
+    size_t j;                   /* # bytes filled */
+    unsigned char* p;           /* pointer to next byte in bytes */
+    int pincr;                  /* direction to move p */
+
+    assert(v != NULL && PyLong_Check(v));
+
+    if (Py_SIZE(v) < 0) {
+        ndigits = -(Py_SIZE(v));
+        if (!is_signed) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative long to unsigned");
+            return -1;
+        }
+        do_twos_comp = 1;
+    }
+    else {
+        ndigits = Py_SIZE(v);
+        do_twos_comp = 0;
+    }
+
+    if (little_endian) {
+        p = bytes;
+        pincr = 1;
+    }
+    else {
+        p = bytes + n - 1;
+        pincr = -1;
+    }
+
+    /* Copy over all the Python digits.
+       It's crucial that every Python digit except for the MSD contribute
+       exactly PyLong_SHIFT bits to the total, so first assert that the long is
+       normalized. */
+    assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+    j = 0;
+    accum = 0;
+    accumbits = 0;
+    carry = do_twos_comp ? 1 : 0;
+    for (i = 0; i < ndigits; ++i) {
+        digit thisdigit = v->ob_digit[i];
+        if (do_twos_comp) {
+            thisdigit = (thisdigit ^ PyLong_MASK) + carry;
+            carry = thisdigit >> PyLong_SHIFT;
+            thisdigit &= PyLong_MASK;
+        }
+        /* Because we're going LSB to MSB, thisdigit is more
+           significant than what's already in accum, so needs to be
+           prepended to accum. */
+        accum |= (twodigits)thisdigit << accumbits;
+
+        /* The most-significant digit may be (probably is) at least
+           partly empty. */
+        if (i == ndigits - 1) {
+            /* Count # of sign bits -- they needn't be stored,
+             * although for signed conversion we need later to
+             * make sure at least one sign bit gets stored. */
+            digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit;
+            while (s != 0) {
+                s >>= 1;
+                accumbits++;
+            }
+        }
+        else
+            accumbits += PyLong_SHIFT;
+
+        /* Store as many bytes as possible. */
+        while (accumbits >= 8) {
+            if (j >= n)
+                goto Overflow;
+            ++j;
+            *p = (unsigned char)(accum & 0xff);
+            p += pincr;
+            accumbits -= 8;
+            accum >>= 8;
+        }
+    }
+
+    /* Store the straggler (if any). */
+    assert(accumbits < 8);
+    assert(carry == 0);  /* else do_twos_comp and *every* digit was 0 */
+    if (accumbits > 0) {
+        if (j >= n)
+            goto Overflow;
+        ++j;
+        if (do_twos_comp) {
+            /* Fill leading bits of the byte with sign bits
+               (appropriately pretending that the long had an
+               infinite supply of sign bits). */
+            accum |= (~(twodigits)0) << accumbits;
+        }
+        *p = (unsigned char)(accum & 0xff);
+        p += pincr;
+    }
+    else if (j == n && n > 0 && is_signed) {
+        /* The main loop filled the byte array exactly, so the code
+           just above didn't get to ensure there's a sign bit, and the
+           loop below wouldn't add one either.  Make sure a sign bit
+           exists. */
+        unsigned char msb = *(p - pincr);
+        int sign_bit_set = msb >= 0x80;
+        assert(accumbits == 0);
+        if (sign_bit_set == do_twos_comp)
+            return 0;
+        else
+            goto Overflow;
+    }
+
+    /* Fill remaining bytes with copies of the sign bit. */
+    {
+        unsigned char signbyte = do_twos_comp ? 0xffU : 0U;
+        for ( ; j < n; ++j, p += pincr)
+            *p = signbyte;
+    }
+
+    return 0;
+
+  Overflow:
+    PyErr_SetString(PyExc_OverflowError, "long too big to convert");
+    return -1;
+
+}
+
+/* Create a new long (or int) object from a C pointer */
+
+PyObject *
+PyLong_FromVoidPtr(void *p)
+{
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+    if ((long)p < 0)
+        return PyLong_FromUnsignedLong((unsigned long)p);
+    return PyInt_FromLong((long)p);
+#else
+
+#ifndef HAVE_LONG_LONG
+#   error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#endif
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
+#   error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+    /* optimize null pointers */
+    if (p == NULL)
+        return PyInt_FromLong(0);
+    return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p);
+
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
+}
+
+/* Get a C pointer from a long object (or an int object in some cases) */
+
+void *
+PyLong_AsVoidPtr(PyObject *vv)
+{
+    /* This function will allow int or long objects. If vv is neither,
+       then the PyLong_AsLong*() functions will raise the exception:
+       PyExc_SystemError, "bad argument to internal function"
+    */
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+    long x;
+
+    if (PyInt_Check(vv))
+        x = PyInt_AS_LONG(vv);
+    else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
+        x = PyLong_AsLong(vv);
+    else
+        x = PyLong_AsUnsignedLong(vv);
+#else
+
+#ifndef HAVE_LONG_LONG
+#   error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#endif
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
+#   error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+    PY_LONG_LONG x;
+
+    if (PyInt_Check(vv))
+        x = PyInt_AS_LONG(vv);
+    else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
+        x = PyLong_AsLongLong(vv);
+    else
+        x = PyLong_AsUnsignedLongLong(vv);
+
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
+
+    if (x == -1 && PyErr_Occurred())
+        return NULL;
+    return (void *)x;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Initial PY_LONG_LONG support by Chris Herborth ([email protected]), later
+ * rewritten to use the newer PyLong_{As,From}ByteArray API.
+ */
+
+#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
+#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN)
+
+/* Create a new long int object from a C PY_LONG_LONG int. */
+
+PyObject *
+PyLong_FromLongLong(PY_LONG_LONG ival)
+{
+    PyLongObject *v;
+    unsigned PY_LONG_LONG abs_ival;
+    unsigned PY_LONG_LONG t;  /* unsigned so >> doesn't propagate sign bit */
+    int ndigits = 0;
+    int negative = 0;
+
+    if (ival < 0) {
+        /* avoid signed overflow on negation;  see comments
+           in PyLong_FromLong above. */
+        abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1;
+        negative = 1;
+    }
+    else {
+        abs_ival = (unsigned PY_LONG_LONG)ival;
+    }
+
+    /* Count the number of Python digits.
+       We used to pick 5 ("big enough for anything"), but that's a
+       waste of time and space given that 5*15 = 75 bits are rarely
+       needed. */
+    t = abs_ival;
+    while (t) {
+        ++ndigits;
+        t >>= PyLong_SHIFT;
+    }
+    v = _PyLong_New(ndigits);
+    if (v != NULL) {
+        digit *p = v->ob_digit;
+        Py_SIZE(v) = negative ? -ndigits : ndigits;
+        t = abs_ival;
+        while (t) {
+            *p++ = (digit)(t & PyLong_MASK);
+            t >>= PyLong_SHIFT;
+        }
+    }
+    return (PyObject *)v;
+}
+
+/* Create a new long int object from a C unsigned PY_LONG_LONG int. */
+
+PyObject *
+PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival)
+{
+    PyLongObject *v;
+    unsigned PY_LONG_LONG t;
+    int ndigits = 0;
+
+    /* Count the number of Python digits. */
+    t = (unsigned PY_LONG_LONG)ival;
+    while (t) {
+        ++ndigits;
+        t >>= PyLong_SHIFT;
+    }
+    v = _PyLong_New(ndigits);
+    if (v != NULL) {
+        digit *p = v->ob_digit;
+        Py_SIZE(v) = ndigits;
+        while (ival) {
+            *p++ = (digit)(ival & PyLong_MASK);
+            ival >>= PyLong_SHIFT;
+        }
+    }
+    return (PyObject *)v;
+}
+
+/* Create a new long int object from a C Py_ssize_t. */
+
+PyObject *
+PyLong_FromSsize_t(Py_ssize_t ival)
+{
+    Py_ssize_t bytes = ival;
+    int one = 1;
+    return _PyLong_FromByteArray((unsigned char *)&bytes,
+                                 SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
+}
+
+/* Create a new long int object from a C size_t. */
+
+PyObject *
+PyLong_FromSize_t(size_t ival)
+{
+    size_t bytes = ival;
+    int one = 1;
+    return _PyLong_FromByteArray((unsigned char *)&bytes,
+                                 SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
+}
+
+/* Get a C PY_LONG_LONG int from a long int object.
+   Return -1 and set an error if overflow occurs. */
+
+PY_LONG_LONG
+PyLong_AsLongLong(PyObject *vv)
+{
+    PY_LONG_LONG bytes;
+    int one = 1;
+    int res;
+
+    if (vv == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (!PyLong_Check(vv)) {
+        PyNumberMethods *nb;
+        PyObject *io;
+        if (PyInt_Check(vv))
+            return (PY_LONG_LONG)PyInt_AsLong(vv);
+        if ((nb = vv->ob_type->tp_as_number) == NULL ||
+            nb->nb_int == NULL) {
+            PyErr_SetString(PyExc_TypeError, "an integer is required");
+            return -1;
+        }
+        io = (*nb->nb_int) (vv);
+        if (io == NULL)
+            return -1;
+        if (PyInt_Check(io)) {
+            bytes = PyInt_AsLong(io);
+            Py_DECREF(io);
+            return bytes;
+        }
+        if (PyLong_Check(io)) {
+            bytes = PyLong_AsLongLong(io);
+            Py_DECREF(io);
+            return bytes;
+        }
+        Py_DECREF(io);
+        PyErr_SetString(PyExc_TypeError, "integer conversion failed");
+        return -1;
+    }
+
+    res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
+                              SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
+
+    /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
+    if (res < 0)
+        return (PY_LONG_LONG)-1;
+    else
+        return bytes;
+}
+
+/* Get a C unsigned PY_LONG_LONG int from a long int object.
+   Return -1 and set an error if overflow occurs. */
+
+unsigned PY_LONG_LONG
+PyLong_AsUnsignedLongLong(PyObject *vv)
+{
+    unsigned PY_LONG_LONG bytes;
+    int one = 1;
+    int res;
+
+    if (vv == NULL || !PyLong_Check(vv)) {
+        PyErr_BadInternalCall();
+        return (unsigned PY_LONG_LONG)-1;
+    }
+
+    res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
+                              SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
+
+    /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
+    if (res < 0)
+        return (unsigned PY_LONG_LONG)res;
+    else
+        return bytes;
+}
+
+/* Get a C unsigned long int from a long int object, ignoring the high bits.
+   Returns -1 and sets an error condition if an error occurs. */
+
+unsigned PY_LONG_LONG
+PyLong_AsUnsignedLongLongMask(PyObject *vv)
+{
+    register PyLongObject *v;
+    unsigned PY_LONG_LONG x;
+    Py_ssize_t i;
+    int sign;
+
+    if (vv == NULL || !PyLong_Check(vv)) {
+        PyErr_BadInternalCall();
+        return (unsigned long) -1;
+    }
+    v = (PyLongObject *)vv;
+    i = v->ob_size;
+    sign = 1;
+    x = 0;
+    if (i < 0) {
+        sign = -1;
+        i = -i;
+    }
+    while (--i >= 0) {
+        x = (x << PyLong_SHIFT) | v->ob_digit[i];
+    }
+    return x * sign;
+}
+
+/* Get a C long long int from a Python long or Python int object.
+   On overflow, returns -1 and sets *overflow to 1 or -1 depending
+   on the sign of the result.  Otherwise *overflow is 0.
+
+   For other errors (e.g., type error), returns -1 and sets an error
+   condition.
+*/
+
+PY_LONG_LONG
+PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
+{
+    /* This version by Tim Peters */
+    register PyLongObject *v;
+    unsigned PY_LONG_LONG x, prev;
+    PY_LONG_LONG res;
+    Py_ssize_t i;
+    int sign;
+    int do_decref = 0; /* if nb_int was called */
+
+    *overflow = 0;
+    if (vv == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+
+    if (PyInt_Check(vv))
+        return PyInt_AsLong(vv);
+
+    if (!PyLong_Check(vv)) {
+        PyNumberMethods *nb;
+        nb = vv->ob_type->tp_as_number;
+        if (nb == NULL || nb->nb_int == NULL) {
+            PyErr_SetString(PyExc_TypeError,
+                            "an integer is required");
+            return -1;
+        }
+        vv = (*nb->nb_int) (vv);
+        if (vv == NULL)
+            return -1;
+        do_decref = 1;
+        if(PyInt_Check(vv)) {
+            res = PyInt_AsLong(vv);
+            goto exit;
+        }
+        if (!PyLong_Check(vv)) {
+            Py_DECREF(vv);
+            PyErr_SetString(PyExc_TypeError,
+                            "nb_int should return int object");
+            return -1;
+        }
+    }
+
+    res = -1;
+    v = (PyLongObject *)vv;
+    i = Py_SIZE(v);
+
+    switch (i) {
+    case -1:
+        res = -(sdigit)v->ob_digit[0];
+        break;
+    case 0:
+        res = 0;
+        break;
+    case 1:
+        res = v->ob_digit[0];
+        break;
+    default:
+        sign = 1;
+        x = 0;
+        if (i < 0) {
+            sign = -1;
+            i = -(i);
+        }
+        while (--i >= 0) {
+            prev = x;
+            x = (x << PyLong_SHIFT) + v->ob_digit[i];
+            if ((x >> PyLong_SHIFT) != prev) {
+                *overflow = sign;
+                goto exit;
+            }
+        }
+        /* Haven't lost any bits, but casting to long requires extra
+         * care (see comment above).
+         */
+        if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) {
+            res = (PY_LONG_LONG)x * sign;
+        }
+        else if (sign < 0 && x == PY_ABS_LLONG_MIN) {
+            res = PY_LLONG_MIN;
+        }
+        else {
+            *overflow = sign;
+            /* res is already set to -1 */
+        }
+    }
+  exit:
+    if (do_decref) {
+        Py_DECREF(vv);
+    }
+    return res;
+}
+
+#undef IS_LITTLE_ENDIAN
+
+#endif /* HAVE_LONG_LONG */
+
+
+static int
+convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
+    if (PyLong_Check(v)) {
+        *a = (PyLongObject *) v;
+        Py_INCREF(v);
+    }
+    else if (PyInt_Check(v)) {
+        *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));
+    }
+    else {
+        return 0;
+    }
+    if (PyLong_Check(w)) {
+        *b = (PyLongObject *) w;
+        Py_INCREF(w);
+    }
+    else if (PyInt_Check(w)) {
+        *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));
+    }
+    else {
+        Py_DECREF(*a);
+        return 0;
+    }
+    return 1;
+}
+
+#define CONVERT_BINOP(v, w, a, b)               \
+    do {                                        \
+        if (!convert_binop(v, w, a, b)) {       \
+            Py_INCREF(Py_NotImplemented);       \
+            return Py_NotImplemented;           \
+        }                                       \
+    } while(0)                                  \
+
+/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
+   2**k if d is nonzero, else 0. */
+
+static const unsigned char BitLengthTable[32] = {
+    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_digit(digit d)
+{
+    int d_bits = 0;
+    while (d >= 32) {
+        d_bits += 6;
+        d >>= 6;
+    }
+    d_bits += (int)BitLengthTable[d];
+    return d_bits;
+}
+
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required.  x[0:n]
+ * is modified in place, by adding y to it.  Carries are propagated as far as
+ * x[m-1], and the remaining carry (0 or 1) is returned.
+ */
+static digit
+v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
+{
+    Py_ssize_t i;
+    digit carry = 0;
+
+    assert(m >= n);
+    for (i = 0; i < n; ++i) {
+        carry += x[i] + y[i];
+        x[i] = carry & PyLong_MASK;
+        carry >>= PyLong_SHIFT;
+        assert((carry & 1) == carry);
+    }
+    for (; carry && i < m; ++i) {
+        carry += x[i];
+        x[i] = carry & PyLong_MASK;
+        carry >>= PyLong_SHIFT;
+        assert((carry & 1) == carry);
+    }
+    return carry;
+}
+
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required.  x[0:n]
+ * is modified in place, by subtracting y from it.  Borrows are propagated as
+ * far as x[m-1], and the remaining borrow (0 or 1) is returned.
+ */
+static digit
+v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
+{
+    Py_ssize_t i;
+    digit borrow = 0;
+
+    assert(m >= n);
+    for (i = 0; i < n; ++i) {
+        borrow = x[i] - y[i] - borrow;
+        x[i] = borrow & PyLong_MASK;
+        borrow >>= PyLong_SHIFT;
+        borrow &= 1;            /* keep only 1 sign bit */
+    }
+    for (; borrow && i < m; ++i) {
+        borrow = x[i] - borrow;
+        x[i] = borrow & PyLong_MASK;
+        borrow >>= PyLong_SHIFT;
+        borrow &= 1;
+    }
+    return borrow;
+}
+
+/* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT.  Put
+ * result in z[0:m], and return the d bits shifted out of the top.
+ */
+static digit
+v_lshift(digit *z, digit *a, Py_ssize_t m, int d)
+{
+    Py_ssize_t i;
+    digit carry = 0;
+
+    assert(0 <= d && d < PyLong_SHIFT);
+    for (i=0; i < m; i++) {
+        twodigits acc = (twodigits)a[i] << d | carry;
+        z[i] = (digit)acc & PyLong_MASK;
+        carry = (digit)(acc >> PyLong_SHIFT);
+    }
+    return carry;
+}
+
+/* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT.  Put
+ * result in z[0:m], and return the d bits shifted out of the bottom.
+ */
+static digit
+v_rshift(digit *z, digit *a, Py_ssize_t m, int d)
+{
+    Py_ssize_t i;
+    digit carry = 0;
+    digit mask = ((digit)1 << d) - 1U;
+
+    assert(0 <= d && d < PyLong_SHIFT);
+    for (i=m; i-- > 0;) {
+        twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i];
+        carry = (digit)acc & mask;
+        z[i] = (digit)(acc >> d);
+    }
+    return carry;
+}
+
+/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
+   in pout, and returning the remainder.  pin and pout point at the LSD.
+   It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
+   _PyLong_Format, but that should be done with great care since longs are
+   immutable. */
+
+static digit
+inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
+{
+    twodigits rem = 0;
+
+    assert(n > 0 && n <= PyLong_MASK);
+    pin += size;
+    pout += size;
+    while (--size >= 0) {
+        digit hi;
+        rem = (rem << PyLong_SHIFT) | *--pin;
+        *--pout = hi = (digit)(rem / n);
+        rem -= (twodigits)hi * n;
+    }
+    return (digit)rem;
+}
+
+/* Divide a long integer by a digit, returning both the quotient
+   (as function result) and the remainder (through *prem).
+   The sign of a is ignored; n should not be zero. */
+
+static PyLongObject *
+divrem1(PyLongObject *a, digit n, digit *prem)
+{
+    const Py_ssize_t size = ABS(Py_SIZE(a));
+    PyLongObject *z;
+
+    assert(n > 0 && n <= PyLong_MASK);
+    z = _PyLong_New(size);
+    if (z == NULL)
+        return NULL;
+    *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);
+    return long_normalize(z);
+}
+
+/* Convert a long integer to a base 10 string.  Returns a new non-shared
+   string.  (Return value is non-shared so that callers can modify the
+   returned value if necessary.) */
+
+static PyObject *
+long_to_decimal_string(PyObject *aa, int addL)
+{
+    PyLongObject *scratch, *a;
+    PyObject *str;
+    Py_ssize_t size, strlen, size_a, i, j;
+    digit *pout, *pin, rem, tenpow;
+    char *p;
+    int negative;
+
+    a = (PyLongObject *)aa;
+    if (a == NULL || !PyLong_Check(a)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    size_a = ABS(Py_SIZE(a));
+    negative = Py_SIZE(a) < 0;
+
+    /* quick and dirty upper bound for the number of digits
+       required to express a in base _PyLong_DECIMAL_BASE:
+
+         #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))
+
+       But log2(a) < size_a * PyLong_SHIFT, and
+       log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
+                                  > 3 * _PyLong_DECIMAL_SHIFT
+    */
+    if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "long is too large to format");
+        return NULL;
+    }
+    /* the expression size_a * PyLong_SHIFT is now safe from overflow */
+    size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
+    scratch = _PyLong_New(size);
+    if (scratch == NULL)
+        return NULL;
+
+    /* convert array of base _PyLong_BASE digits in pin to an array of
+       base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
+       Volume 2 (3rd edn), section 4.4, Method 1b). */
+    pin = a->ob_digit;
+    pout = scratch->ob_digit;
+    size = 0;
+    for (i = size_a; --i >= 0; ) {
+        digit hi = pin[i];
+        for (j = 0; j < size; j++) {
+            twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;
+            hi = (digit)(z / _PyLong_DECIMAL_BASE);
+            pout[j] = (digit)(z - (twodigits)hi *
+                              _PyLong_DECIMAL_BASE);
+        }
+        while (hi) {
+            pout[size++] = hi % _PyLong_DECIMAL_BASE;
+            hi /= _PyLong_DECIMAL_BASE;
+        }
+        /* check for keyboard interrupt */
+        SIGCHECK({
+                Py_DECREF(scratch);
+                return NULL;
+            });
+    }
+    /* pout should have at least one digit, so that the case when a = 0
+       works correctly */
+    if (size == 0)
+        pout[size++] = 0;
+
+    /* calculate exact length of output string, and allocate */
+    strlen = (addL != 0) + negative +
+        1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
+    tenpow = 10;
+    rem = pout[size-1];
+    while (rem >= tenpow) {
+        tenpow *= 10;
+        strlen++;
+    }
+    str = PyString_FromStringAndSize(NULL, strlen);
+    if (str == NULL) {
+        Py_DECREF(scratch);
+        return NULL;
+    }
+
+    /* fill the string right-to-left */
+    p = PyString_AS_STRING(str) + strlen;
+    *p = '\0';
+    if (addL)
+        *--p = 'L';
+    /* pout[0] through pout[size-2] contribute exactly
+       _PyLong_DECIMAL_SHIFT digits each */
+    for (i=0; i < size - 1; i++) {
+        rem = pout[i];
+        for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) {
+            *--p = '0' + rem % 10;
+            rem /= 10;
+        }
+    }
+    /* pout[size-1]: always produce at least one decimal digit */
+    rem = pout[i];
+    do {
+        *--p = '0' + rem % 10;
+        rem /= 10;
+    } while (rem != 0);
+
+    /* and sign */
+    if (negative)
+        *--p = '-';
+
+    /* check we've counted correctly */
+    assert(p == PyString_AS_STRING(str));
+    Py_DECREF(scratch);
+    return (PyObject *)str;
+}
+
+/* Convert the long to a string object with given base,
+   appending a base prefix of 0[box] if base is 2, 8 or 16.
+   Add a trailing "L" if addL is non-zero.
+   If newstyle is zero, then use the pre-2.6 behavior of octal having
+   a leading "0", instead of the prefix "0o" */
+PyAPI_FUNC(PyObject *)
+_PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
+{
+    register PyLongObject *a = (PyLongObject *)aa;
+    PyStringObject *str;
+    Py_ssize_t i, sz;
+    Py_ssize_t size_a;
+    char *p;
+    int bits;
+    char sign = '\0';
+
+    if (base == 10)
+        return long_to_decimal_string((PyObject *)a, addL);
+
+    if (a == NULL || !PyLong_Check(a)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    assert(base >= 2 && base <= 36);
+    size_a = ABS(Py_SIZE(a));
+
+    /* Compute a rough upper bound for the length of the string */
+    i = base;
+    bits = 0;
+    while (i > 1) {
+        ++bits;
+        i >>= 1;
+    }
+    i = 5 + (addL ? 1 : 0);
+    /* ensure we don't get signed overflow in sz calculation */
+    if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "long is too large to format");
+        return NULL;
+    }
+    sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits;
+    assert(sz >= 0);
+    str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);
+    if (str == NULL)
+        return NULL;
+    p = PyString_AS_STRING(str) + sz;
+    *p = '\0';
+    if (addL)
+        *--p = 'L';
+    if (a->ob_size < 0)
+        sign = '-';
+
+    if (a->ob_size == 0) {
+        *--p = '0';
+    }
+    else if ((base & (base - 1)) == 0) {
+        /* JRH: special case for power-of-2 bases */
+        twodigits accum = 0;
+        int accumbits = 0;              /* # of bits in accum */
+        int basebits = 1;               /* # of bits in base-1 */
+        i = base;
+        while ((i >>= 1) > 1)
+            ++basebits;
+
+        for (i = 0; i < size_a; ++i) {
+            accum |= (twodigits)a->ob_digit[i] << accumbits;
+            accumbits += PyLong_SHIFT;
+            assert(accumbits >= basebits);
+            do {
+                char cdigit = (char)(accum & (base - 1));
+                cdigit += (cdigit < 10) ? '0' : 'a'-10;
+                assert(p > PyString_AS_STRING(str));
+                *--p = cdigit;
+                accumbits -= basebits;
+                accum >>= basebits;
+            } while (i < size_a-1 ? accumbits >= basebits : accum > 0);
+        }
+    }
+    else {
+        /* Not 0, and base not a power of 2.  Divide repeatedly by
+           base, but for speed use the highest power of base that
+           fits in a digit. */
+        Py_ssize_t size = size_a;
+        digit *pin = a->ob_digit;
+        PyLongObject *scratch;
+        /* powbasw <- largest power of base that fits in a digit. */
+        digit powbase = base;  /* powbase == base ** power */
+        int power = 1;
+        for (;;) {
+            twodigits newpow = powbase * (twodigits)base;
+            if (newpow >> PyLong_SHIFT)
+                /* doesn't fit in a digit */
+                break;
+            powbase = (digit)newpow;
+            ++power;
+        }
+
+        /* Get a scratch area for repeated division. */
+        scratch = _PyLong_New(size);
+        if (scratch == NULL) {
+            Py_DECREF(str);
+            return NULL;
+        }
+
+        /* Repeatedly divide by powbase. */
+        do {
+            int ntostore = power;
+            digit rem = inplace_divrem1(scratch->ob_digit,
+                                        pin, size, powbase);
+            pin = scratch->ob_digit; /* no need to use a again */
+            if (pin[size - 1] == 0)
+                --size;
+            SIGCHECK({
+                    Py_DECREF(scratch);
+                    Py_DECREF(str);
+                    return NULL;
+                });
+
+            /* Break rem into digits. */
+            assert(ntostore > 0);
+            do {
+                digit nextrem = (digit)(rem / base);
+                char c = (char)(rem - nextrem * base);
+                assert(p > PyString_AS_STRING(str));
+                c += (c < 10) ? '0' : 'a'-10;
+                *--p = c;
+                rem = nextrem;
+                --ntostore;
+                /* Termination is a bit delicate:  must not
+                   store leading zeroes, so must get out if
+                   remaining quotient and rem are both 0. */
+            } while (ntostore && (size || rem));
+        } while (size != 0);
+        Py_DECREF(scratch);
+    }
+
+    if (base == 2) {
+        *--p = 'b';
+        *--p = '0';
+    }
+    else if (base == 8) {
+        if (newstyle) {
+            *--p = 'o';
+            *--p = '0';
+        }
+        else
+            if (size_a != 0)
+                *--p = '0';
+    }
+    else if (base == 16) {
+        *--p = 'x';
+        *--p = '0';
+    }
+    else if (base != 10) {
+        *--p = '#';
+        *--p = '0' + base%10;
+        if (base > 10)
+            *--p = '0' + base/10;
+    }
+    if (sign)
+        *--p = sign;
+    if (p != PyString_AS_STRING(str)) {
+        char *q = PyString_AS_STRING(str);
+        assert(p > q);
+        do {
+        } while ((*q++ = *p++) != '\0');
+        q--;
+        _PyString_Resize((PyObject **)&str,
+                         (Py_ssize_t) (q - PyString_AS_STRING(str)));
+    }
+    return (PyObject *)str;
+}
+
+/* Table of digit values for 8-bit string -> integer conversion.
+ * '0' maps to 0, ..., '9' maps to 9.
+ * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
+ * All other indices map to 37.
+ * Note that when converting a base B string, a char c is a legitimate
+ * base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.
+ */
+int _PyLong_DigitValue[256] = {
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  37, 37, 37, 37, 37, 37,
+    37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+    37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+};
+
+/* *str points to the first digit in a string of base `base` digits.  base
+ * is a power of 2 (2, 4, 8, 16, or 32).  *str is set to point to the first
+ * non-digit (which may be *str!).  A normalized long is returned.
+ * The point to this routine is that it takes time linear in the number of
+ * string characters.
+ */
+static PyLongObject *
+long_from_binary_base(char **str, int base)
+{
+    char *p = *str;
+    char *start = p;
+    int bits_per_char;
+    Py_ssize_t n;
+    PyLongObject *z;
+    twodigits accum;
+    int bits_in_accum;
+    digit *pdigit;
+
+    assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
+    n = base;
+    for (bits_per_char = -1; n; ++bits_per_char)
+        n >>= 1;
+    /* n <- total # of bits needed, while setting p to end-of-string */
+    while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
+        ++p;
+    *str = p;
+    /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
+    n = (p - start) * bits_per_char + PyLong_SHIFT - 1;
+    if (n / bits_per_char < p - start) {
+        PyErr_SetString(PyExc_ValueError,
+                        "long string too large to convert");
+        return NULL;
+    }
+    n = n / PyLong_SHIFT;
+    z = _PyLong_New(n);
+    if (z == NULL)
+        return NULL;
+    /* Read string from right, and fill in long from left; i.e.,
+     * from least to most significant in both.
+     */
+    accum = 0;
+    bits_in_accum = 0;
+    pdigit = z->ob_digit;
+    while (--p >= start) {
+        int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
+        assert(k >= 0 && k < base);
+        accum |= (twodigits)k << bits_in_accum;
+        bits_in_accum += bits_per_char;
+        if (bits_in_accum >= PyLong_SHIFT) {
+            *pdigit++ = (digit)(accum & PyLong_MASK);
+            assert(pdigit - z->ob_digit <= n);
+            accum >>= PyLong_SHIFT;
+            bits_in_accum -= PyLong_SHIFT;
+            assert(bits_in_accum < PyLong_SHIFT);
+        }
+    }
+    if (bits_in_accum) {
+        assert(bits_in_accum <= PyLong_SHIFT);
+        *pdigit++ = (digit)accum;
+        assert(pdigit - z->ob_digit <= n);
+    }
+    while (pdigit - z->ob_digit < n)
+        *pdigit++ = 0;
+    return long_normalize(z);
+}
+
+PyObject *
+PyLong_FromString(char *str, char **pend, int base)
+{
+    int sign = 1;
+    char *start, *orig_str = str;
+    PyLongObject *z;
+    PyObject *strobj, *strrepr;
+    Py_ssize_t slen;
+
+    if ((base != 0 && base < 2) || base > 36) {
+        PyErr_SetString(PyExc_ValueError,
+                        "long() arg 2 must be >= 2 and <= 36");
+        return NULL;
+    }
+    while (*str != '\0' && isspace(Py_CHARMASK(*str)))
+        str++;
+    if (*str == '+')
+        ++str;
+    else if (*str == '-') {
+        ++str;
+        sign = -1;
+    }
+    while (*str != '\0' && isspace(Py_CHARMASK(*str)))
+        str++;
+    if (base == 0) {
+        /* No base given.  Deduce the base from the contents
+           of the string */
+        if (str[0] != '0')
+            base = 10;
+        else if (str[1] == 'x' || str[1] == 'X')
+            base = 16;
+        else if (str[1] == 'o' || str[1] == 'O')
+            base = 8;
+        else if (str[1] == 'b' || str[1] == 'B')
+            base = 2;
+        else
+            /* "old" (C-style) octal literal, still valid in
+               2.x, although illegal in 3.x */
+            base = 8;
+    }
+    /* Whether or not we were deducing the base, skip leading chars
+       as needed */
+    if (str[0] == '0' &&
+        ((base == 16 && (str[1] == 'x' || str[1] == 'X')) ||
+         (base == 8  && (str[1] == 'o' || str[1] == 'O')) ||
+         (base == 2  && (str[1] == 'b' || str[1] == 'B'))))
+        str += 2;
+
+    start = str;
+    if ((base & (base - 1)) == 0)
+        z = long_from_binary_base(&str, base);
+    else {
+/***
+Binary bases can be converted in time linear in the number of digits, because
+Python's representation base is binary.  Other bases (including decimal!) use
+the simple quadratic-time algorithm below, complicated by some speed tricks.
+
+First some math:  the largest integer that can be expressed in N base-B digits
+is B**N-1.  Consequently, if we have an N-digit input in base B, the worst-
+case number of Python digits needed to hold it is the smallest integer n s.t.
+
+    PyLong_BASE**n-1 >= B**N-1  [or, adding 1 to both sides]
+    PyLong_BASE**n >= B**N      [taking logs to base PyLong_BASE]
+    n >= log(B**N)/log(PyLong_BASE) = N * log(B)/log(PyLong_BASE)
+
+The static array log_base_PyLong_BASE[base] == log(base)/log(PyLong_BASE) so
+we can compute this quickly.  A Python long with that much space is reserved
+near the start, and the result is computed into it.
+
+The input string is actually treated as being in base base**i (i.e., i digits
+are processed at a time), where two more static arrays hold:
+
+    convwidth_base[base] = the largest integer i such that
+                           base**i <= PyLong_BASE
+    convmultmax_base[base] = base ** convwidth_base[base]
+
+The first of these is the largest i such that i consecutive input digits
+must fit in a single Python digit.  The second is effectively the input
+base we're really using.
+
+Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base
+convmultmax_base[base], the result is "simply"
+
+   (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1
+
+where B = convmultmax_base[base].
+
+Error analysis:  as above, the number of Python digits `n` needed is worst-
+case
+
+    n >= N * log(B)/log(PyLong_BASE)
+
+where `N` is the number of input digits in base `B`.  This is computed via
+
+    size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
+
+below.  Two numeric concerns are how much space this can waste, and whether
+the computed result can be too small.  To be concrete, assume PyLong_BASE =
+2**15, which is the default (and it's unlikely anyone changes that).
+
+Waste isn't a problem: provided the first input digit isn't 0, the difference
+between the worst-case input with N digits and the smallest input with N
+digits is about a factor of B, but B is small compared to PyLong_BASE so at
+most one allocated Python digit can remain unused on that count.  If
+N*log(B)/log(PyLong_BASE) is mathematically an exact integer, then truncating
+that and adding 1 returns a result 1 larger than necessary.  However, that
+can't happen: whenever B is a power of 2, long_from_binary_base() is called
+instead, and it's impossible for B**i to be an integer power of 2**15 when B
+is not a power of 2 (i.e., it's impossible for N*log(B)/log(PyLong_BASE) to be
+an exact integer when B is not a power of 2, since B**i has a prime factor
+other than 2 in that case, but (2**15)**j's only prime factor is 2).
+
+The computed result can be too small if the true value of
+N*log(B)/log(PyLong_BASE) is a little bit larger than an exact integer, but
+due to roundoff errors (in computing log(B), log(PyLong_BASE), their quotient,
+and/or multiplying that by N) yields a numeric result a little less than that
+integer.  Unfortunately, "how close can a transcendental function get to an
+integer over some range?"  questions are generally theoretically intractable.
+Computer analysis via continued fractions is practical: expand
+log(B)/log(PyLong_BASE) via continued fractions, giving a sequence i/j of "the
+best" rational approximations.  Then j*log(B)/log(PyLong_BASE) is
+approximately equal to (the integer) i.  This shows that we can get very close
+to being in trouble, but very rarely.  For example, 76573 is a denominator in
+one of the continued-fraction approximations to log(10)/log(2**15), and
+indeed:
+
+    >>> log(10)/log(2**15)*76573
+    16958.000000654003
+
+is very close to an integer.  If we were working with IEEE single-precision,
+rounding errors could kill us.  Finding worst cases in IEEE double-precision
+requires better-than-double-precision log() functions, and Tim didn't bother.
+Instead the code checks to see whether the allocated space is enough as each
+new Python digit is added, and copies the whole thing to a larger long if not.
+This should happen extremely rarely, and in fact I don't have a test case
+that triggers it(!).  Instead the code was tested by artificially allocating
+just 1 digit at the start, so that the copying code was exercised for every
+digit beyond the first.
+***/
+        register twodigits c;           /* current input character */
+        Py_ssize_t size_z;
+        int i;
+        int convwidth;
+        twodigits convmultmax, convmult;
+        digit *pz, *pzstop;
+        char* scan;
+
+        static double log_base_PyLong_BASE[37] = {0.0e0,};
+        static int convwidth_base[37] = {0,};
+        static twodigits convmultmax_base[37] = {0,};
+
+        if (log_base_PyLong_BASE[base] == 0.0) {
+            twodigits convmax = base;
+            int i = 1;
+
+            log_base_PyLong_BASE[base] = (log((double)base) /
+                                          log((double)PyLong_BASE));
+            for (;;) {
+                twodigits next = convmax * base;
+                if (next > PyLong_BASE)
+                    break;
+                convmax = next;
+                ++i;
+            }
+            convmultmax_base[base] = convmax;
+            assert(i > 0);
+            convwidth_base[base] = i;
+        }
+
+        /* Find length of the string of numeric characters. */
+        scan = str;
+        while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
+            ++scan;
+
+        /* Create a long object that can contain the largest possible
+         * integer with this base and length.  Note that there's no
+         * need to initialize z->ob_digit -- no slot is read up before
+         * being stored into.
+         */
+        size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
+        /* Uncomment next line to test exceedingly rare copy code */
+        /* size_z = 1; */
+        assert(size_z > 0);
+        z = _PyLong_New(size_z);
+        if (z == NULL)
+            return NULL;
+        Py_SIZE(z) = 0;
+
+        /* `convwidth` consecutive input digits are treated as a single
+         * digit in base `convmultmax`.
+         */
+        convwidth = convwidth_base[base];
+        convmultmax = convmultmax_base[base];
+
+        /* Work ;-) */
+        while (str < scan) {
+            /* grab up to convwidth digits from the input string */
+            c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
+            for (i = 1; i < convwidth && str != scan; ++i, ++str) {
+                c = (twodigits)(c *  base +
+                                _PyLong_DigitValue[Py_CHARMASK(*str)]);
+                assert(c < PyLong_BASE);
+            }
+
+            convmult = convmultmax;
+            /* Calculate the shift only if we couldn't get
+             * convwidth digits.
+             */
+            if (i != convwidth) {
+                convmult = base;
+                for ( ; i > 1; --i)
+                    convmult *= base;
+            }
+
+            /* Multiply z by convmult, and add c. */
+            pz = z->ob_digit;
+            pzstop = pz + Py_SIZE(z);
+            for (; pz < pzstop; ++pz) {
+                c += (twodigits)*pz * convmult;
+                *pz = (digit)(c & PyLong_MASK);
+                c >>= PyLong_SHIFT;
+            }
+            /* carry off the current end? */
+            if (c) {
+                assert(c < PyLong_BASE);
+                if (Py_SIZE(z) < size_z) {
+                    *pz = (digit)c;
+                    ++Py_SIZE(z);
+                }
+                else {
+                    PyLongObject *tmp;
+                    /* Extremely rare.  Get more space. */
+                    assert(Py_SIZE(z) == size_z);
+                    tmp = _PyLong_New(size_z + 1);
+                    if (tmp == NULL) {
+                        Py_DECREF(z);
+                        return NULL;
+                    }
+                    memcpy(tmp->ob_digit,
+                           z->ob_digit,
+                           sizeof(digit) * size_z);
+                    Py_DECREF(z);
+                    z = tmp;
+                    z->ob_digit[size_z] = (digit)c;
+                    ++size_z;
+                }
+            }
+        }
+    }
+    if (z == NULL)
+        return NULL;
+    if (str == start)
+        goto onError;
+    if (sign < 0)
+        Py_SIZE(z) = -(Py_SIZE(z));
+    if (*str == 'L' || *str == 'l')
+        str++;
+    while (*str && isspace(Py_CHARMASK(*str)))
+        str++;
+    if (*str != '\0')
+        goto onError;
+    if (pend)
+        *pend = str;
+    return (PyObject *) z;
+
+  onError:
+    Py_XDECREF(z);
+    slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
+    strobj = PyString_FromStringAndSize(orig_str, slen);
+    if (strobj == NULL)
+        return NULL;
+    strrepr = PyObject_Repr(strobj);
+    Py_DECREF(strobj);
+    if (strrepr == NULL)
+        return NULL;
+    PyErr_Format(PyExc_ValueError,
+                 "invalid literal for long() with base %d: %s",
+                 base, PyString_AS_STRING(strrepr));
+    Py_DECREF(strrepr);
+    return NULL;
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
+{
+    PyObject *result;
+    char *buffer = (char *)PyMem_MALLOC(length+1);
+
+    if (buffer == NULL)
+        return NULL;
+
+    if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {
+        PyMem_FREE(buffer);
+        return NULL;
+    }
+    result = PyLong_FromString(buffer, NULL, base);
+    PyMem_FREE(buffer);
+    return result;
+}
+#endif
+
+/* forward */
+static PyLongObject *x_divrem
+    (PyLongObject *, PyLongObject *, PyLongObject **);
+static PyObject *long_long(PyObject *v);
+
+/* Long division with remainder, top-level routine */
+
+static int
+long_divrem(PyLongObject *a, PyLongObject *b,
+            PyLongObject **pdiv, PyLongObject **prem)
+{
+    Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
+    PyLongObject *z;
+
+    if (size_b == 0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "long division or modulo by zero");
+        return -1;
+    }
+    if (size_a < size_b ||
+        (size_a == size_b &&
+         a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
+        /* |a| < |b|. */
+        *pdiv = _PyLong_New(0);
+        if (*pdiv == NULL)
+            return -1;
+        Py_INCREF(a);
+        *prem = (PyLongObject *) a;
+        return 0;
+    }
+    if (size_b == 1) {
+        digit rem = 0;
+        z = divrem1(a, b->ob_digit[0], &rem);
+        if (z == NULL)
+            return -1;
+        *prem = (PyLongObject *) PyLong_FromLong((long)rem);
+        if (*prem == NULL) {
+            Py_DECREF(z);
+            return -1;
+        }
+    }
+    else {
+        z = x_divrem(a, b, prem);
+        if (z == NULL)
+            return -1;
+    }
+    /* Set the signs.
+       The quotient z has the sign of a*b;
+       the remainder r has the sign of a,
+       so a = b*z + r. */
+    if ((a->ob_size < 0) != (b->ob_size < 0))
+        z->ob_size = -(z->ob_size);
+    if (a->ob_size < 0 && (*prem)->ob_size != 0)
+        (*prem)->ob_size = -((*prem)->ob_size);
+    *pdiv = z;
+    return 0;
+}
+
+/* Unsigned long division with remainder -- the algorithm.  The arguments v1
+   and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */
+
+static PyLongObject *
+x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
+{
+    PyLongObject *v, *w, *a;
+    Py_ssize_t i, k, size_v, size_w;
+    int d;
+    digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak;
+    twodigits vv;
+    sdigit zhi;
+    stwodigits z;
+
+    /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd
+       edn.), section 4.3.1, Algorithm D], except that we don't explicitly
+       handle the special case when the initial estimate q for a quotient
+       digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and
+       that won't overflow a digit. */
+
+    /* allocate space; w will also be used to hold the final remainder */
+    size_v = ABS(Py_SIZE(v1));
+    size_w = ABS(Py_SIZE(w1));
+    assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */
+    v = _PyLong_New(size_v+1);
+    if (v == NULL) {
+        *prem = NULL;
+        return NULL;
+    }
+    w = _PyLong_New(size_w);
+    if (w == NULL) {
+        Py_DECREF(v);
+        *prem = NULL;
+        return NULL;
+    }
+
+    /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2.
+       shift v1 left by the same amount.  Results go into w and v. */
+    d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]);
+    carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d);
+    assert(carry == 0);
+    carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d);
+    if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) {
+        v->ob_digit[size_v] = carry;
+        size_v++;
+    }
+
+    /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has
+       at most (and usually exactly) k = size_v - size_w digits. */
+    k = size_v - size_w;
+    assert(k >= 0);
+    a = _PyLong_New(k);
+    if (a == NULL) {
+        Py_DECREF(w);
+        Py_DECREF(v);
+        *prem = NULL;
+        return NULL;
+    }
+    v0 = v->ob_digit;
+    w0 = w->ob_digit;
+    wm1 = w0[size_w-1];
+    wm2 = w0[size_w-2];
+    for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) {
+        /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving
+           single-digit quotient q, remainder in vk[0:size_w]. */
+
+        SIGCHECK({
+                Py_DECREF(a);
+                Py_DECREF(w);
+                Py_DECREF(v);
+                *prem = NULL;
+                return NULL;
+            });
+
+        /* estimate quotient digit q; may overestimate by 1 (rare) */
+        vtop = vk[size_w];
+        assert(vtop <= wm1);
+        vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1];
+        q = (digit)(vv / wm1);
+        r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */
+        while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT)
+                                     | vk[size_w-2])) {
+            --q;
+            r += wm1;
+            if (r >= PyLong_BASE)
+                break;
+        }
+        assert(q <= PyLong_BASE);
+
+        /* subtract q*w0[0:size_w] from vk[0:size_w+1] */
+        zhi = 0;
+        for (i = 0; i < size_w; ++i) {
+            /* invariants: -PyLong_BASE <= -q <= zhi <= 0;
+               -PyLong_BASE * q <= z < PyLong_BASE */
+            z = (sdigit)vk[i] + zhi -
+                (stwodigits)q * (stwodigits)w0[i];
+            vk[i] = (digit)z & PyLong_MASK;
+            zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,
+                                                    z, PyLong_SHIFT);
+        }
+
+        /* add w back if q was too large (this branch taken rarely) */
+        assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0);
+        if ((sdigit)vtop + zhi < 0) {
+            carry = 0;
+            for (i = 0; i < size_w; ++i) {
+                carry += vk[i] + w0[i];
+                vk[i] = carry & PyLong_MASK;
+                carry >>= PyLong_SHIFT;
+            }
+            --q;
+        }
+
+        /* store quotient digit */
+        assert(q < PyLong_BASE);
+        *--ak = q;
+    }
+
+    /* unshift remainder; we reuse w to store the result */
+    carry = v_rshift(w0, v0, size_w, d);
+    assert(carry==0);
+    Py_DECREF(v);
+
+    *prem = long_normalize(w);
+    return long_normalize(a);
+}
+
+/* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <=
+   abs(x) < 1.0 and e >= 0; return x and put e in *e.  Here x is
+   rounded to DBL_MANT_DIG significant bits using round-half-to-even.
+   If a == 0, return 0.0 and set *e = 0.  If the resulting exponent
+   e is larger than PY_SSIZE_T_MAX, raise OverflowError and return
+   -1.0. */
+
+/* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */
+#if DBL_MANT_DIG == 53
+#define EXP2_DBL_MANT_DIG 9007199254740992.0
+#else
+#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG))
+#endif
+
+double
+_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
+{
+    Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size;
+    /* See below for why x_digits is always large enough. */
+    digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT];
+    double dx;
+    /* Correction term for round-half-to-even rounding.  For a digit x,
+       "x + half_even_correction[x & 7]" gives x rounded to the nearest
+       multiple of 4, rounding ties to a multiple of 8. */
+    static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};
+
+    a_size = ABS(Py_SIZE(a));
+    if (a_size == 0) {
+        /* Special case for 0: significand 0.0, exponent 0. */
+        *e = 0;
+        return 0.0;
+    }
+    a_bits = bits_in_digit(a->ob_digit[a_size-1]);
+    /* The following is an overflow-free version of the check
+       "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */
+    if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 &&
+        (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 ||
+         a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1))
+        goto overflow;
+    a_bits = (a_size - 1) * PyLong_SHIFT + a_bits;
+
+    /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size]
+       (shifting left if a_bits <= DBL_MANT_DIG + 2).
+
+       Number of digits needed for result: write // for floor division.
+       Then if shifting left, we end up using
+
+         1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT
+
+       digits.  If shifting right, we use
+
+         a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT
+
+       digits.  Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with
+       the inequalities
+
+         m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT
+         m // PyLong_SHIFT - n // PyLong_SHIFT <=
+                                          1 + (m - n - 1) // PyLong_SHIFT,
+
+       valid for any integers m and n, we find that x_size satisfies
+
+         x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT
+
+       in both cases.
+    */
+    if (a_bits <= DBL_MANT_DIG + 2) {
+        shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT;
+        shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT;
+        x_size = 0;
+        while (x_size < shift_digits)
+            x_digits[x_size++] = 0;
+        rem = v_lshift(x_digits + x_size, a->ob_digit, a_size,
+                       (int)shift_bits);
+        x_size += a_size;
+        x_digits[x_size++] = rem;
+    }
+    else {
+        shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT;
+        shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT;
+        rem = v_rshift(x_digits, a->ob_digit + shift_digits,
+                       a_size - shift_digits, (int)shift_bits);
+        x_size = a_size - shift_digits;
+        /* For correct rounding below, we need the least significant
+           bit of x to be 'sticky' for this shift: if any of the bits
+           shifted out was nonzero, we set the least significant bit
+           of x. */
+        if (rem)
+            x_digits[0] |= 1;
+        else
+            while (shift_digits > 0)
+                if (a->ob_digit[--shift_digits]) {
+                    x_digits[0] |= 1;
+                    break;
+                }
+    }
+    assert(1 <= x_size &&
+           x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit)));
+
+    /* Round, and convert to double. */
+    x_digits[0] += half_even_correction[x_digits[0] & 7];
+    dx = x_digits[--x_size];
+    while (x_size > 0)
+        dx = dx * PyLong_BASE + x_digits[--x_size];
+
+    /* Rescale;  make correction if result is 1.0. */
+    dx /= 4.0 * EXP2_DBL_MANT_DIG;
+    if (dx == 1.0) {
+        if (a_bits == PY_SSIZE_T_MAX)
+            goto overflow;
+        dx = 0.5;
+        a_bits += 1;
+    }
+
+    *e = a_bits;
+    return Py_SIZE(a) < 0 ? -dx : dx;
+
+  overflow:
+    /* exponent > PY_SSIZE_T_MAX */
+    PyErr_SetString(PyExc_OverflowError,
+                    "huge integer: number of bits overflows a Py_ssize_t");
+    *e = 0;
+    return -1.0;
+}
+
+/* Get a C double from a long int object.  Rounds to the nearest double,
+   using the round-half-to-even rule in the case of a tie. */
+
+double
+PyLong_AsDouble(PyObject *v)
+{
+    Py_ssize_t exponent;
+    double x;
+
+    if (v == NULL || !PyLong_Check(v)) {
+        PyErr_BadInternalCall();
+        return -1.0;
+    }
+    x = _PyLong_Frexp((PyLongObject *)v, &exponent);
+    if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "long int too large to convert to float");
+        return -1.0;
+    }
+    return ldexp(x, (int)exponent);
+}
+
+/* Methods */
+
+static void
+long_dealloc(PyObject *v)
+{
+    Py_TYPE(v)->tp_free(v);
+}
+
+static PyObject *
+long_repr(PyObject *v)
+{
+    return _PyLong_Format(v, 10, 1, 0);
+}
+
+static PyObject *
+long_str(PyObject *v)
+{
+    return _PyLong_Format(v, 10, 0, 0);
+}
+
+static int
+long_compare(PyLongObject *a, PyLongObject *b)
+{
+    Py_ssize_t sign;
+
+    if (Py_SIZE(a) != Py_SIZE(b)) {
+        sign = Py_SIZE(a) - Py_SIZE(b);
+    }
+    else {
+        Py_ssize_t i = ABS(Py_SIZE(a));
+        while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
+            ;
+        if (i < 0)
+            sign = 0;
+        else {
+            sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i];
+            if (Py_SIZE(a) < 0)
+                sign = -sign;
+        }
+    }
+    return sign < 0 ? -1 : sign > 0 ? 1 : 0;
+}
+
+static long
+long_hash(PyLongObject *v)
+{
+    unsigned long x;
+    Py_ssize_t i;
+    int sign;
+
+    /* This is designed so that Python ints and longs with the
+       same value hash to the same value, otherwise comparisons
+       of mapping keys will turn out weird */
+    i = v->ob_size;
+    sign = 1;
+    x = 0;
+    if (i < 0) {
+        sign = -1;
+        i = -(i);
+    }
+    /* The following loop produces a C unsigned long x such that x is
+       congruent to the absolute value of v modulo ULONG_MAX.  The
+       resulting x is nonzero if and only if v is. */
+    while (--i >= 0) {
+        /* Force a native long #-bits (32 or 64) circular shift */
+        x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT);
+        x += v->ob_digit[i];
+        /* If the addition above overflowed we compensate by
+           incrementing.  This preserves the value modulo
+           ULONG_MAX. */
+        if (x < v->ob_digit[i])
+            x++;
+    }
+    x = x * sign;
+    if (x == (unsigned long)-1)
+        x = (unsigned long)-2;
+    return (long)x;
+}
+
+
+/* Add the absolute values of two long integers. */
+
+static PyLongObject *
+x_add(PyLongObject *a, PyLongObject *b)
+{
+    Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
+    PyLongObject *z;
+    Py_ssize_t i;
+    digit carry = 0;
+
+    /* Ensure a is the larger of the two: */
+    if (size_a < size_b) {
+        { PyLongObject *temp = a; a = b; b = temp; }
+        { Py_ssize_t size_temp = size_a;
+            size_a = size_b;
+            size_b = size_temp; }
+    }
+    z = _PyLong_New(size_a+1);
+    if (z == NULL)
+        return NULL;
+    for (i = 0; i < size_b; ++i) {
+        carry += a->ob_digit[i] + b->ob_digit[i];
+        z->ob_digit[i] = carry & PyLong_MASK;
+        carry >>= PyLong_SHIFT;
+    }
+    for (; i < size_a; ++i) {
+        carry += a->ob_digit[i];
+        z->ob_digit[i] = carry & PyLong_MASK;
+        carry >>= PyLong_SHIFT;
+    }
+    z->ob_digit[i] = carry;
+    return long_normalize(z);
+}
+
+/* Subtract the absolute values of two integers. */
+
+static PyLongObject *
+x_sub(PyLongObject *a, PyLongObject *b)
+{
+    Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
+    PyLongObject *z;
+    Py_ssize_t i;
+    int sign = 1;
+    digit borrow = 0;
+
+    /* Ensure a is the larger of the two: */
+    if (size_a < size_b) {
+        sign = -1;
+        { PyLongObject *temp = a; a = b; b = temp; }
+        { Py_ssize_t size_temp = size_a;
+            size_a = size_b;
+            size_b = size_temp; }
+    }
+    else if (size_a == size_b) {
+        /* Find highest digit where a and b differ: */
+        i = size_a;
+        while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
+            ;
+        if (i < 0)
+            return _PyLong_New(0);
+        if (a->ob_digit[i] < b->ob_digit[i]) {
+            sign = -1;
+            { PyLongObject *temp = a; a = b; b = temp; }
+        }
+        size_a = size_b = i+1;
+    }
+    z = _PyLong_New(size_a);
+    if (z == NULL)
+        return NULL;
+    for (i = 0; i < size_b; ++i) {
+        /* The following assumes unsigned arithmetic
+           works module 2**N for some N>PyLong_SHIFT. */
+        borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
+        z->ob_digit[i] = borrow & PyLong_MASK;
+        borrow >>= PyLong_SHIFT;
+        borrow &= 1; /* Keep only one sign bit */
+    }
+    for (; i < size_a; ++i) {
+        borrow = a->ob_digit[i] - borrow;
+        z->ob_digit[i] = borrow & PyLong_MASK;
+        borrow >>= PyLong_SHIFT;
+        borrow &= 1; /* Keep only one sign bit */
+    }
+    assert(borrow == 0);
+    if (sign < 0)
+        z->ob_size = -(z->ob_size);
+    return long_normalize(z);
+}
+
+static PyObject *
+long_add(PyLongObject *v, PyLongObject *w)
+{
+    PyLongObject *a, *b, *z;
+
+    CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+    if (a->ob_size < 0) {
+        if (b->ob_size < 0) {
+            z = x_add(a, b);
+            if (z != NULL && z->ob_size != 0)
+                z->ob_size = -(z->ob_size);
+        }
+        else
+            z = x_sub(b, a);
+    }
+    else {
+        if (b->ob_size < 0)
+            z = x_sub(a, b);
+        else
+            z = x_add(a, b);
+    }
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)z;
+}
+
+static PyObject *
+long_sub(PyLongObject *v, PyLongObject *w)
+{
+    PyLongObject *a, *b, *z;
+
+    CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+    if (a->ob_size < 0) {
+        if (b->ob_size < 0)
+            z = x_sub(a, b);
+        else
+            z = x_add(a, b);
+        if (z != NULL && z->ob_size != 0)
+            z->ob_size = -(z->ob_size);
+    }
+    else {
+        if (b->ob_size < 0)
+            z = x_add(a, b);
+        else
+            z = x_sub(a, b);
+    }
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)z;
+}
+
+/* Grade school multiplication, ignoring the signs.
+ * Returns the absolute value of the product, or NULL if error.
+ */
+static PyLongObject *
+x_mul(PyLongObject *a, PyLongObject *b)
+{
+    PyLongObject *z;
+    Py_ssize_t size_a = ABS(Py_SIZE(a));
+    Py_ssize_t size_b = ABS(Py_SIZE(b));
+    Py_ssize_t i;
+
+    z = _PyLong_New(size_a + size_b);
+    if (z == NULL)
+        return NULL;
+
+    memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit));
+    if (a == b) {
+        /* Efficient squaring per HAC, Algorithm 14.16:
+         * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+         * Gives slightly less than a 2x speedup when a == b,
+         * via exploiting that each entry in the multiplication
+         * pyramid appears twice (except for the size_a squares).
+         */
+        for (i = 0; i < size_a; ++i) {
+            twodigits carry;
+            twodigits f = a->ob_digit[i];
+            digit *pz = z->ob_digit + (i << 1);
+            digit *pa = a->ob_digit + i + 1;
+            digit *paend = a->ob_digit + size_a;
+
+            SIGCHECK({
+                    Py_DECREF(z);
+                    return NULL;
+                });
+
+            carry = *pz + f * f;
+            *pz++ = (digit)(carry & PyLong_MASK);
+            carry >>= PyLong_SHIFT;
+            assert(carry <= PyLong_MASK);
+
+            /* Now f is added in twice in each column of the
+             * pyramid it appears.  Same as adding f<<1 once.
+             */
+            f <<= 1;
+            while (pa < paend) {
+                carry += *pz + *pa++ * f;
+                *pz++ = (digit)(carry & PyLong_MASK);
+                carry >>= PyLong_SHIFT;
+                assert(carry <= (PyLong_MASK << 1));
+            }
+            if (carry) {
+                carry += *pz;
+                *pz++ = (digit)(carry & PyLong_MASK);
+                carry >>= PyLong_SHIFT;
+            }
+            if (carry)
+                *pz += (digit)(carry & PyLong_MASK);
+            assert((carry >> PyLong_SHIFT) == 0);
+        }
+    }
+    else {      /* a is not the same as b -- gradeschool long mult */
+        for (i = 0; i < size_a; ++i) {
+            twodigits carry = 0;
+            twodigits f = a->ob_digit[i];
+            digit *pz = z->ob_digit + i;
+            digit *pb = b->ob_digit;
+            digit *pbend = b->ob_digit + size_b;
+
+            SIGCHECK({
+                    Py_DECREF(z);
+                    return NULL;
+                });
+
+            while (pb < pbend) {
+                carry += *pz + *pb++ * f;
+                *pz++ = (digit)(carry & PyLong_MASK);
+                carry >>= PyLong_SHIFT;
+                assert(carry <= PyLong_MASK);
+            }
+            if (carry)
+                *pz += (digit)(carry & PyLong_MASK);
+            assert((carry >> PyLong_SHIFT) == 0);
+        }
+    }
+    return long_normalize(z);
+}
+
+/* A helper for Karatsuba multiplication (k_mul).
+   Takes a long "n" and an integer "size" representing the place to
+   split, and sets low and high such that abs(n) == (high << size) + low,
+   viewing the shift as being by digits.  The sign bit is ignored, and
+   the return values are >= 0.
+   Returns 0 on success, -1 on failure.
+*/
+static int
+kmul_split(PyLongObject *n,
+           Py_ssize_t size,
+           PyLongObject **high,
+           PyLongObject **low)
+{
+    PyLongObject *hi, *lo;
+    Py_ssize_t size_lo, size_hi;
+    const Py_ssize_t size_n = ABS(Py_SIZE(n));
+
+    size_lo = MIN(size_n, size);
+    size_hi = size_n - size_lo;
+
+    if ((hi = _PyLong_New(size_hi)) == NULL)
+        return -1;
+    if ((lo = _PyLong_New(size_lo)) == NULL) {
+        Py_DECREF(hi);
+        return -1;
+    }
+
+    memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));
+    memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));
+
+    *high = long_normalize(hi);
+    *low = long_normalize(lo);
+    return 0;
+}
+
+static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b);
+
+/* Karatsuba multiplication.  Ignores the input signs, and returns the
+ * absolute value of the product (or NULL if error).
+ * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).
+ */
+static PyLongObject *
+k_mul(PyLongObject *a, PyLongObject *b)
+{
+    Py_ssize_t asize = ABS(Py_SIZE(a));
+    Py_ssize_t bsize = ABS(Py_SIZE(b));
+    PyLongObject *ah = NULL;
+    PyLongObject *al = NULL;
+    PyLongObject *bh = NULL;
+    PyLongObject *bl = NULL;
+    PyLongObject *ret = NULL;
+    PyLongObject *t1, *t2, *t3;
+    Py_ssize_t shift;           /* the number of digits we split off */
+    Py_ssize_t i;
+
+    /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
+     * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh  + ah*bh + al*bl
+     * Then the original product is
+     *     ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl
+     * By picking X to be a power of 2, "*X" is just shifting, and it's
+     * been reduced to 3 multiplies on numbers half the size.
+     */
+
+    /* We want to split based on the larger number; fiddle so that b
+     * is largest.
+     */
+    if (asize > bsize) {
+        t1 = a;
+        a = b;
+        b = t1;
+
+        i = asize;
+        asize = bsize;
+        bsize = i;
+    }
+
+    /* Use gradeschool math when either number is too small. */
+    i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;
+    if (asize <= i) {
+        if (asize == 0)
+            return _PyLong_New(0);
+        else
+            return x_mul(a, b);
+    }
+
+    /* If a is small compared to b, splitting on b gives a degenerate
+     * case with ah==0, and Karatsuba may be (even much) less efficient
+     * than "grade school" then.  However, we can still win, by viewing
+     * b as a string of "big digits", each of width a->ob_size.  That
+     * leads to a sequence of balanced calls to k_mul.
+     */
+    if (2 * asize <= bsize)
+        return k_lopsided_mul(a, b);
+
+    /* Split a & b into hi & lo pieces. */
+    shift = bsize >> 1;
+    if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
+    assert(Py_SIZE(ah) > 0);            /* the split isn't degenerate */
+
+    if (a == b) {
+        bh = ah;
+        bl = al;
+        Py_INCREF(bh);
+        Py_INCREF(bl);
+    }
+    else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
+
+    /* The plan:
+     * 1. Allocate result space (asize + bsize digits:  that's always
+     *    enough).
+     * 2. Compute ah*bh, and copy into result at 2*shift.
+     * 3. Compute al*bl, and copy into result at 0.  Note that this
+     *    can't overlap with #2.
+     * 4. Subtract al*bl from the result, starting at shift.  This may
+     *    underflow (borrow out of the high digit), but we don't care:
+     *    we're effectively doing unsigned arithmetic mod
+     *    PyLong_BASE**(sizea + sizeb), and so long as the *final* result fits,
+     *    borrows and carries out of the high digit can be ignored.
+     * 5. Subtract ah*bh from the result, starting at shift.
+     * 6. Compute (ah+al)*(bh+bl), and add it into the result starting
+     *    at shift.
+     */
+
+    /* 1. Allocate result space. */
+    ret = _PyLong_New(asize + bsize);
+    if (ret == NULL) goto fail;
+#ifdef Py_DEBUG
+    /* Fill with trash, to catch reference to uninitialized digits. */
+    memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit));
+#endif
+
+    /* 2. t1 <- ah*bh, and copy into high digits of result. */
+    if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
+    assert(Py_SIZE(t1) >= 0);
+    assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret));
+    memcpy(ret->ob_digit + 2*shift, t1->ob_digit,
+           Py_SIZE(t1) * sizeof(digit));
+
+    /* Zero-out the digits higher than the ah*bh copy. */
+    i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1);
+    if (i)
+        memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0,
+               i * sizeof(digit));
+
+    /* 3. t2 <- al*bl, and copy into the low digits. */
+    if ((t2 = k_mul(al, bl)) == NULL) {
+        Py_DECREF(t1);
+        goto fail;
+    }
+    assert(Py_SIZE(t2) >= 0);
+    assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */
+    memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit));
+
+    /* Zero out remaining digits. */
+    i = 2*shift - Py_SIZE(t2);          /* number of uninitialized digits */
+    if (i)
+        memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit));
+
+    /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2).  We do al*bl first
+     * because it's fresher in cache.
+     */
+    i = Py_SIZE(ret) - shift;  /* # digits after shift */
+    (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2));
+    Py_DECREF(t2);
+
+    (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1));
+    Py_DECREF(t1);
+
+    /* 6. t3 <- (ah+al)(bh+bl), and add into result. */
+    if ((t1 = x_add(ah, al)) == NULL) goto fail;
+    Py_DECREF(ah);
+    Py_DECREF(al);
+    ah = al = NULL;
+
+    if (a == b) {
+        t2 = t1;
+        Py_INCREF(t2);
+    }
+    else if ((t2 = x_add(bh, bl)) == NULL) {
+        Py_DECREF(t1);
+        goto fail;
+    }
+    Py_DECREF(bh);
+    Py_DECREF(bl);
+    bh = bl = NULL;
+
+    t3 = k_mul(t1, t2);
+    Py_DECREF(t1);
+    Py_DECREF(t2);
+    if (t3 == NULL) goto fail;
+    assert(Py_SIZE(t3) >= 0);
+
+    /* Add t3.  It's not obvious why we can't run out of room here.
+     * See the (*) comment after this function.
+     */
+    (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3));
+    Py_DECREF(t3);
+
+    return long_normalize(ret);
+
+  fail:
+    Py_XDECREF(ret);
+    Py_XDECREF(ah);
+    Py_XDECREF(al);
+    Py_XDECREF(bh);
+    Py_XDECREF(bl);
+    return NULL;
+}
+
+/* (*) Why adding t3 can't "run out of room" above.
+
+Let f(x) mean the floor of x and c(x) mean the ceiling of x.  Some facts
+to start with:
+
+1. For any integer i, i = c(i/2) + f(i/2).  In particular,
+   bsize = c(bsize/2) + f(bsize/2).
+2. shift = f(bsize/2)
+3. asize <= bsize
+4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this
+   routine, so asize > bsize/2 >= f(bsize/2) in this routine.
+
+We allocated asize + bsize result digits, and add t3 into them at an offset
+of shift.  This leaves asize+bsize-shift allocated digit positions for t3
+to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) =
+asize + c(bsize/2) available digit positions.
+
+bh has c(bsize/2) digits, and bl at most f(size/2) digits.  So bh+hl has
+at most c(bsize/2) digits + 1 bit.
+
+If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2)
+digits, and al has at most f(bsize/2) digits in any case.  So ah+al has at
+most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit.
+
+The product (ah+al)*(bh+bl) therefore has at most
+
+    c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits
+
+and we have asize + c(bsize/2) available digit positions.  We need to show
+this is always enough.  An instance of c(bsize/2) cancels out in both, so
+the question reduces to whether asize digits is enough to hold
+(asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits.  If asize < bsize,
+then we're asking whether asize digits >= f(bsize/2) digits + 2 bits.  By #4,
+asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1
+digit is enough to hold 2 bits.  This is so since PyLong_SHIFT=15 >= 2.  If
+asize == bsize, then we're asking whether bsize digits is enough to hold
+c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits
+is enough to hold 2 bits.  This is so if bsize >= 2, which holds because
+bsize >= KARATSUBA_CUTOFF >= 2.
+
+Note that since there's always enough room for (ah+al)*(bh+bl), and that's
+clearly >= each of ah*bh and al*bl, there's always enough room to subtract
+ah*bh and al*bl too.
+*/
+
+/* b has at least twice the digits of a, and a is big enough that Karatsuba
+ * would pay off *if* the inputs had balanced sizes.  View b as a sequence
+ * of slices, each with a->ob_size digits, and multiply the slices by a,
+ * one at a time.  This gives k_mul balanced inputs to work with, and is
+ * also cache-friendly (we compute one double-width slice of the result
+ * at a time, then move on, never backtracking except for the helpful
+ * single-width slice overlap between successive partial sums).
+ */
+static PyLongObject *
+k_lopsided_mul(PyLongObject *a, PyLongObject *b)
+{
+    const Py_ssize_t asize = ABS(Py_SIZE(a));
+    Py_ssize_t bsize = ABS(Py_SIZE(b));
+    Py_ssize_t nbdone;          /* # of b digits already multiplied */
+    PyLongObject *ret;
+    PyLongObject *bslice = NULL;
+
+    assert(asize > KARATSUBA_CUTOFF);
+    assert(2 * asize <= bsize);
+
+    /* Allocate result space, and zero it out. */
+    ret = _PyLong_New(asize + bsize);
+    if (ret == NULL)
+        return NULL;
+    memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit));
+
+    /* Successive slices of b are copied into bslice. */
+    bslice = _PyLong_New(asize);
+    if (bslice == NULL)
+        goto fail;
+
+    nbdone = 0;
+    while (bsize > 0) {
+        PyLongObject *product;
+        const Py_ssize_t nbtouse = MIN(bsize, asize);
+
+        /* Multiply the next slice of b by a. */
+        memcpy(bslice->ob_digit, b->ob_digit + nbdone,
+               nbtouse * sizeof(digit));
+        Py_SIZE(bslice) = nbtouse;
+        product = k_mul(a, bslice);
+        if (product == NULL)
+            goto fail;
+
+        /* Add into result. */
+        (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone,
+                     product->ob_digit, Py_SIZE(product));
+        Py_DECREF(product);
+
+        bsize -= nbtouse;
+        nbdone += nbtouse;
+    }
+
+    Py_DECREF(bslice);
+    return long_normalize(ret);
+
+  fail:
+    Py_DECREF(ret);
+    Py_XDECREF(bslice);
+    return NULL;
+}
+
+static PyObject *
+long_mul(PyLongObject *v, PyLongObject *w)
+{
+    PyLongObject *a, *b, *z;
+
+    if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    z = k_mul(a, b);
+    /* Negate if exactly one of the inputs is negative. */
+    if (((a->ob_size ^ b->ob_size) < 0) && z)
+        z->ob_size = -(z->ob_size);
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)z;
+}
+
+/* The / and % operators are now defined in terms of divmod().
+   The expression a mod b has the value a - b*floor(a/b).
+   The long_divrem function gives the remainder after division of
+   |a| by |b|, with the sign of a.  This is also expressed
+   as a - b*trunc(a/b), if trunc truncates towards zero.
+   Some examples:
+     a           b      a rem b         a mod b
+     13          10      3               3
+    -13          10     -3               7
+     13         -10      3              -7
+    -13         -10     -3              -3
+   So, to get from rem to mod, we have to add b if a and b
+   have different signs.  We then subtract one from the 'div'
+   part of the outcome to keep the invariant intact. */
+
+/* Compute
+ *     *pdiv, *pmod = divmod(v, w)
+ * NULL can be passed for pdiv or pmod, in which case that part of
+ * the result is simply thrown away.  The caller owns a reference to
+ * each of these it requests (does not pass NULL for).
+ */
+static int
+l_divmod(PyLongObject *v, PyLongObject *w,
+         PyLongObject **pdiv, PyLongObject **pmod)
+{
+    PyLongObject *div, *mod;
+
+    if (long_divrem(v, w, &div, &mod) < 0)
+        return -1;
+    if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) ||
+        (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) {
+        PyLongObject *temp;
+        PyLongObject *one;
+        temp = (PyLongObject *) long_add(mod, w);
+        Py_DECREF(mod);
+        mod = temp;
+        if (mod == NULL) {
+            Py_DECREF(div);
+            return -1;
+        }
+        one = (PyLongObject *) PyLong_FromLong(1L);
+        if (one == NULL ||
+            (temp = (PyLongObject *) long_sub(div, one)) == NULL) {
+            Py_DECREF(mod);
+            Py_DECREF(div);
+            Py_XDECREF(one);
+            return -1;
+        }
+        Py_DECREF(one);
+        Py_DECREF(div);
+        div = temp;
+    }
+    if (pdiv != NULL)
+        *pdiv = div;
+    else
+        Py_DECREF(div);
+
+    if (pmod != NULL)
+        *pmod = mod;
+    else
+        Py_DECREF(mod);
+
+    return 0;
+}
+
+static PyObject *
+long_div(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b, *div;
+
+    CONVERT_BINOP(v, w, &a, &b);
+    if (l_divmod(a, b, &div, NULL) < 0)
+        div = NULL;
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)div;
+}
+
+static PyObject *
+long_classic_div(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b, *div;
+
+    CONVERT_BINOP(v, w, &a, &b);
+    if (Py_DivisionWarningFlag &&
+        PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)
+        div = NULL;
+    else if (l_divmod(a, b, &div, NULL) < 0)
+        div = NULL;
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)div;
+}
+
+/* PyLong/PyLong -> float, with correctly rounded result. */
+
+#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)
+#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)
+
+static PyObject *
+long_true_divide(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b, *x;
+    Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits;
+    digit mask, low;
+    int inexact, negate, a_is_small, b_is_small;
+    double dx, result;
+
+    CONVERT_BINOP(v, w, &a, &b);
+
+    /*
+       Method in a nutshell:
+
+         0. reduce to case a, b > 0; filter out obvious underflow/overflow
+         1. choose a suitable integer 'shift'
+         2. use integer arithmetic to compute x = floor(2**-shift*a/b)
+         3. adjust x for correct rounding
+         4. convert x to a double dx with the same value
+         5. return ldexp(dx, shift).
+
+       In more detail:
+
+       0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b
+       returns either 0.0 or -0.0, depending on the sign of b.  For a and
+       b both nonzero, ignore signs of a and b, and add the sign back in
+       at the end.  Now write a_bits and b_bits for the bit lengths of a
+       and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise
+       for b).  Then
+
+          2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1).
+
+       So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and
+       so overflows.  Similarly, if a_bits - b_bits < DBL_MIN_EXP -
+       DBL_MANT_DIG - 1 then a/b underflows to 0.  With these cases out of
+       the way, we can assume that
+
+          DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP.
+
+       1. The integer 'shift' is chosen so that x has the right number of
+       bits for a double, plus two or three extra bits that will be used
+       in the rounding decisions.  Writing a_bits and b_bits for the
+       number of significant bits in a and b respectively, a
+       straightforward formula for shift is:
+
+          shift = a_bits - b_bits - DBL_MANT_DIG - 2
+
+       This is fine in the usual case, but if a/b is smaller than the
+       smallest normal float then it can lead to double rounding on an
+       IEEE 754 platform, giving incorrectly rounded results.  So we
+       adjust the formula slightly.  The actual formula used is:
+
+           shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2
+
+       2. The quantity x is computed by first shifting a (left -shift bits
+       if shift <= 0, right shift bits if shift > 0) and then dividing by
+       b.  For both the shift and the division, we keep track of whether
+       the result is inexact, in a flag 'inexact'; this information is
+       needed at the rounding stage.
+
+       With the choice of shift above, together with our assumption that
+       a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows
+       that x >= 1.
+
+       3. Now x * 2**shift <= a/b < (x+1) * 2**shift.  We want to replace
+       this with an exactly representable float of the form
+
+          round(x/2**extra_bits) * 2**(extra_bits+shift).
+
+       For float representability, we need x/2**extra_bits <
+       2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP -
+       DBL_MANT_DIG.  This translates to the condition:
+
+          extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG
+
+       To round, we just modify the bottom digit of x in-place; this can
+       end up giving a digit with value > PyLONG_MASK, but that's not a
+       problem since digits can hold values up to 2*PyLONG_MASK+1.
+
+       With the original choices for shift above, extra_bits will always
+       be 2 or 3.  Then rounding under the round-half-to-even rule, we
+       round up iff the most significant of the extra bits is 1, and
+       either: (a) the computation of x in step 2 had an inexact result,
+       or (b) at least one other of the extra bits is 1, or (c) the least
+       significant bit of x (above those to be rounded) is 1.
+
+       4. Conversion to a double is straightforward; all floating-point
+       operations involved in the conversion are exact, so there's no
+       danger of rounding errors.
+
+       5. Use ldexp(x, shift) to compute x*2**shift, the final result.
+       The result will always be exactly representable as a double, except
+       in the case that it overflows.  To avoid dependence on the exact
+       behaviour of ldexp on overflow, we check for overflow before
+       applying ldexp.  The result of ldexp is adjusted for sign before
+       returning.
+    */
+
+    /* Reduce to case where a and b are both positive. */
+    a_size = ABS(Py_SIZE(a));
+    b_size = ABS(Py_SIZE(b));
+    negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0);
+    if (b_size == 0) {
+        PyErr_SetString(PyExc_ZeroDivisionError,
+                        "division by zero");
+        goto error;
+    }
+    if (a_size == 0)
+        goto underflow_or_zero;
+
+    /* Fast path for a and b small (exactly representable in a double).
+       Relies on floating-point division being correctly rounded; results
+       may be subject to double rounding on x86 machines that operate with
+       the x87 FPU set to 64-bit precision. */
+    a_is_small = a_size <= MANT_DIG_DIGITS ||
+        (a_size == MANT_DIG_DIGITS+1 &&
+         a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
+    b_is_small = b_size <= MANT_DIG_DIGITS ||
+        (b_size == MANT_DIG_DIGITS+1 &&
+         b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
+    if (a_is_small && b_is_small) {
+        double da, db;
+        da = a->ob_digit[--a_size];
+        while (a_size > 0)
+            da = da * PyLong_BASE + a->ob_digit[--a_size];
+        db = b->ob_digit[--b_size];
+        while (b_size > 0)
+            db = db * PyLong_BASE + b->ob_digit[--b_size];
+        result = da / db;
+        goto success;
+    }
+
+    /* Catch obvious cases of underflow and overflow */
+    diff = a_size - b_size;
+    if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1)
+        /* Extreme overflow */
+        goto overflow;
+    else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT)
+        /* Extreme underflow */
+        goto underflow_or_zero;
+    /* Next line is now safe from overflowing a Py_ssize_t */
+    diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) -
+        bits_in_digit(b->ob_digit[b_size - 1]);
+    /* Now diff = a_bits - b_bits. */
+    if (diff > DBL_MAX_EXP)
+        goto overflow;
+    else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1)
+        goto underflow_or_zero;
+
+    /* Choose value for shift; see comments for step 1 above. */
+    shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2;
+
+    inexact = 0;
+
+    /* x = abs(a * 2**-shift) */
+    if (shift <= 0) {
+        Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT;
+        digit rem;
+        /* x = a << -shift */
+        if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) {
+            /* In practice, it's probably impossible to end up
+               here.  Both a and b would have to be enormous,
+               using close to SIZE_T_MAX bytes of memory each. */
+            PyErr_SetString(PyExc_OverflowError,
+                            "intermediate overflow during division");
+            goto error;
+        }
+        x = _PyLong_New(a_size + shift_digits + 1);
+        if (x == NULL)
+            goto error;
+        for (i = 0; i < shift_digits; i++)
+            x->ob_digit[i] = 0;
+        rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit,
+                       a_size, -shift % PyLong_SHIFT);
+        x->ob_digit[a_size + shift_digits] = rem;
+    }
+    else {
+        Py_ssize_t shift_digits = shift / PyLong_SHIFT;
+        digit rem;
+        /* x = a >> shift */
+        assert(a_size >= shift_digits);
+        x = _PyLong_New(a_size - shift_digits);
+        if (x == NULL)
+            goto error;
+        rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits,
+                       a_size - shift_digits, shift % PyLong_SHIFT);
+        /* set inexact if any of the bits shifted out is nonzero */
+        if (rem)
+            inexact = 1;
+        while (!inexact && shift_digits > 0)
+            if (a->ob_digit[--shift_digits])
+                inexact = 1;
+    }
+    long_normalize(x);
+    x_size = Py_SIZE(x);
+
+    /* x //= b. If the remainder is nonzero, set inexact.  We own the only
+       reference to x, so it's safe to modify it in-place. */
+    if (b_size == 1) {
+        digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size,
+                              b->ob_digit[0]);
+        long_normalize(x);
+        if (rem)
+            inexact = 1;
+    }
+    else {
+        PyLongObject *div, *rem;
+        div = x_divrem(x, b, &rem);
+        Py_DECREF(x);
+        x = div;
+        if (x == NULL)
+            goto error;
+        if (Py_SIZE(rem))
+            inexact = 1;
+        Py_DECREF(rem);
+    }
+    x_size = ABS(Py_SIZE(x));
+    assert(x_size > 0); /* result of division is never zero */
+    x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]);
+
+    /* The number of extra bits that have to be rounded away. */
+    extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG;
+    assert(extra_bits == 2 || extra_bits == 3);
+
+    /* Round by directly modifying the low digit of x. */
+    mask = (digit)1 << (extra_bits - 1);
+    low = x->ob_digit[0] | inexact;
+    if (low & mask && low & (3*mask-1))
+        low += mask;
+    x->ob_digit[0] = low & ~(mask-1U);
+
+    /* Convert x to a double dx; the conversion is exact. */
+    dx = x->ob_digit[--x_size];
+    while (x_size > 0)
+        dx = dx * PyLong_BASE + x->ob_digit[--x_size];
+    Py_DECREF(x);
+
+    /* Check whether ldexp result will overflow a double. */
+    if (shift + x_bits >= DBL_MAX_EXP &&
+        (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits)))
+        goto overflow;
+    result = ldexp(dx, (int)shift);
+
+  success:
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return PyFloat_FromDouble(negate ? -result : result);
+
+  underflow_or_zero:
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return PyFloat_FromDouble(negate ? -0.0 : 0.0);
+
+  overflow:
+    PyErr_SetString(PyExc_OverflowError,
+                    "integer division result too large for a float");
+  error:
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return NULL;
+}
+
+static PyObject *
+long_mod(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b, *mod;
+
+    CONVERT_BINOP(v, w, &a, &b);
+
+    if (l_divmod(a, b, NULL, &mod) < 0)
+        mod = NULL;
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)mod;
+}
+
+static PyObject *
+long_divmod(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b, *div, *mod;
+    PyObject *z;
+
+    CONVERT_BINOP(v, w, &a, &b);
+
+    if (l_divmod(a, b, &div, &mod) < 0) {
+        Py_DECREF(a);
+        Py_DECREF(b);
+        return NULL;
+    }
+    z = PyTuple_New(2);
+    if (z != NULL) {
+        PyTuple_SetItem(z, 0, (PyObject *) div);
+        PyTuple_SetItem(z, 1, (PyObject *) mod);
+    }
+    else {
+        Py_DECREF(div);
+        Py_DECREF(mod);
+    }
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return z;
+}
+
+/* pow(v, w, x) */
+static PyObject *
+long_pow(PyObject *v, PyObject *w, PyObject *x)
+{
+    PyLongObject *a, *b, *c; /* a,b,c = v,w,x */
+    int negativeOutput = 0;  /* if x<0 return negative output */
+
+    PyLongObject *z = NULL;  /* accumulated result */
+    Py_ssize_t i, j, k;             /* counters */
+    PyLongObject *temp = NULL;
+
+    /* 5-ary values.  If the exponent is large enough, table is
+     * precomputed so that table[i] == a**i % c for i in range(32).
+     */
+    PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+    /* a, b, c = v, w, x */
+    CONVERT_BINOP(v, w, &a, &b);
+    if (PyLong_Check(x)) {
+        c = (PyLongObject *)x;
+        Py_INCREF(x);
+    }
+    else if (PyInt_Check(x)) {
+        c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));
+        if (c == NULL)
+            goto Error;
+    }
+    else if (x == Py_None)
+        c = NULL;
+    else {
+        Py_DECREF(a);
+        Py_DECREF(b);
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    if (Py_SIZE(b) < 0) {  /* if exponent is negative */
+        if (c) {
+            PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
+                            "cannot be negative when 3rd argument specified");
+            goto Error;
+        }
+        else {
+            /* else return a float.  This works because we know
+               that this calls float_pow() which converts its
+               arguments to double. */
+            Py_DECREF(a);
+            Py_DECREF(b);
+            return PyFloat_Type.tp_as_number->nb_power(v, w, x);
+        }
+    }
+
+    if (c) {
+        /* if modulus == 0:
+               raise ValueError() */
+        if (Py_SIZE(c) == 0) {
+            PyErr_SetString(PyExc_ValueError,
+                            "pow() 3rd argument cannot be 0");
+            goto Error;
+        }
+
+        /* if modulus < 0:
+               negativeOutput = True
+               modulus = -modulus */
+        if (Py_SIZE(c) < 0) {
+            negativeOutput = 1;
+            temp = (PyLongObject *)_PyLong_Copy(c);
+            if (temp == NULL)
+                goto Error;
+            Py_DECREF(c);
+            c = temp;
+            temp = NULL;
+            c->ob_size = - c->ob_size;
+        }
+
+        /* if modulus == 1:
+               return 0 */
+        if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) {
+            z = (PyLongObject *)PyLong_FromLong(0L);
+            goto Done;
+        }
+
+        /* if base < 0:
+               base = base % modulus
+           Having the base positive just makes things easier. */
+        if (Py_SIZE(a) < 0) {
+            if (l_divmod(a, c, NULL, &temp) < 0)
+                goto Error;
+            Py_DECREF(a);
+            a = temp;
+            temp = NULL;
+        }
+    }
+
+    /* At this point a, b, and c are guaranteed non-negative UNLESS
+       c is NULL, in which case a may be negative. */
+
+    z = (PyLongObject *)PyLong_FromLong(1L);
+    if (z == NULL)
+        goto Error;
+
+    /* Perform a modular reduction, X = X % c, but leave X alone if c
+     * is NULL.
+     */
+#define REDUCE(X)                                       \
+    do {                                                \
+        if (c != NULL) {                                \
+            if (l_divmod(X, c, NULL, &temp) < 0)        \
+                goto Error;                             \
+            Py_XDECREF(X);                              \
+            X = temp;                                   \
+            temp = NULL;                                \
+        }                                               \
+    } while(0)
+
+    /* Multiply two values, then reduce the result:
+       result = X*Y % c.  If c is NULL, skip the mod. */
+#define MULT(X, Y, result)                      \
+    do {                                        \
+        temp = (PyLongObject *)long_mul(X, Y);  \
+        if (temp == NULL)                       \
+            goto Error;                         \
+        Py_XDECREF(result);                     \
+        result = temp;                          \
+        temp = NULL;                            \
+        REDUCE(result);                         \
+    } while(0)
+
+    if (Py_SIZE(b) <= FIVEARY_CUTOFF) {
+        /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
+        /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf    */
+        for (i = Py_SIZE(b) - 1; i >= 0; --i) {
+            digit bi = b->ob_digit[i];
+
+            for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
+                MULT(z, z, z);
+                if (bi & j)
+                    MULT(z, a, z);
+            }
+        }
+    }
+    else {
+        /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */
+        Py_INCREF(z);           /* still holds 1L */
+        table[0] = z;
+        for (i = 1; i < 32; ++i)
+            MULT(table[i-1], a, table[i]);
+
+        for (i = Py_SIZE(b) - 1; i >= 0; --i) {
+            const digit bi = b->ob_digit[i];
+
+            for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) {
+                const int index = (bi >> j) & 0x1f;
+                for (k = 0; k < 5; ++k)
+                    MULT(z, z, z);
+                if (index)
+                    MULT(z, table[index], z);
+            }
+        }
+    }
+
+    if (negativeOutput && (Py_SIZE(z) != 0)) {
+        temp = (PyLongObject *)long_sub(z, c);
+        if (temp == NULL)
+            goto Error;
+        Py_DECREF(z);
+        z = temp;
+        temp = NULL;
+    }
+    goto Done;
+
+  Error:
+    if (z != NULL) {
+        Py_DECREF(z);
+        z = NULL;
+    }
+    /* fall through */
+  Done:
+    if (Py_SIZE(b) > FIVEARY_CUTOFF) {
+        for (i = 0; i < 32; ++i)
+            Py_XDECREF(table[i]);
+    }
+    Py_DECREF(a);
+    Py_DECREF(b);
+    Py_XDECREF(c);
+    Py_XDECREF(temp);
+    return (PyObject *)z;
+}
+
+static PyObject *
+long_invert(PyLongObject *v)
+{
+    /* Implement ~x as -(x+1) */
+    PyLongObject *x;
+    PyLongObject *w;
+    w = (PyLongObject *)PyLong_FromLong(1L);
+    if (w == NULL)
+        return NULL;
+    x = (PyLongObject *) long_add(v, w);
+    Py_DECREF(w);
+    if (x == NULL)
+        return NULL;
+    Py_SIZE(x) = -(Py_SIZE(x));
+    return (PyObject *)x;
+}
+
+static PyObject *
+long_neg(PyLongObject *v)
+{
+    PyLongObject *z;
+    if (v->ob_size == 0 && PyLong_CheckExact(v)) {
+        /* -0 == 0 */
+        Py_INCREF(v);
+        return (PyObject *) v;
+    }
+    z = (PyLongObject *)_PyLong_Copy(v);
+    if (z != NULL)
+        z->ob_size = -(v->ob_size);
+    return (PyObject *)z;
+}
+
+static PyObject *
+long_abs(PyLongObject *v)
+{
+    if (v->ob_size < 0)
+        return long_neg(v);
+    else
+        return long_long((PyObject *)v);
+}
+
+static int
+long_nonzero(PyLongObject *v)
+{
+    return Py_SIZE(v) != 0;
+}
+
+static PyObject *
+long_rshift(PyLongObject *v, PyLongObject *w)
+{
+    PyLongObject *a, *b;
+    PyLongObject *z = NULL;
+    Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j;
+    digit lomask, himask;
+
+    CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+    if (Py_SIZE(a) < 0) {
+        /* Right shifting negative numbers is harder */
+        PyLongObject *a1, *a2;
+        a1 = (PyLongObject *) long_invert(a);
+        if (a1 == NULL)
+            goto rshift_error;
+        a2 = (PyLongObject *) long_rshift(a1, b);
+        Py_DECREF(a1);
+        if (a2 == NULL)
+            goto rshift_error;
+        z = (PyLongObject *) long_invert(a2);
+        Py_DECREF(a2);
+    }
+    else {
+        shiftby = PyLong_AsSsize_t((PyObject *)b);
+        if (shiftby == -1L && PyErr_Occurred())
+            goto rshift_error;
+        if (shiftby < 0) {
+            PyErr_SetString(PyExc_ValueError,
+                            "negative shift count");
+            goto rshift_error;
+        }
+        wordshift = shiftby / PyLong_SHIFT;
+        newsize = ABS(Py_SIZE(a)) - wordshift;
+        if (newsize <= 0) {
+            z = _PyLong_New(0);
+            Py_DECREF(a);
+            Py_DECREF(b);
+            return (PyObject *)z;
+        }
+        loshift = shiftby % PyLong_SHIFT;
+        hishift = PyLong_SHIFT - loshift;
+        lomask = ((digit)1 << hishift) - 1;
+        himask = PyLong_MASK ^ lomask;
+        z = _PyLong_New(newsize);
+        if (z == NULL)
+            goto rshift_error;
+        if (Py_SIZE(a) < 0)
+            Py_SIZE(z) = -(Py_SIZE(z));
+        for (i = 0, j = wordshift; i < newsize; i++, j++) {
+            z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
+            if (i+1 < newsize)
+                z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask;
+        }
+        z = long_normalize(z);
+    }
+  rshift_error:
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *) z;
+
+}
+
+static PyObject *
+long_lshift(PyObject *v, PyObject *w)
+{
+    /* This version due to Tim Peters */
+    PyLongObject *a, *b;
+    PyLongObject *z = NULL;
+    Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j;
+    twodigits accum;
+
+    CONVERT_BINOP(v, w, &a, &b);
+
+    shiftby = PyLong_AsSsize_t((PyObject *)b);
+    if (shiftby == -1L && PyErr_Occurred())
+        goto lshift_error;
+    if (shiftby < 0) {
+        PyErr_SetString(PyExc_ValueError, "negative shift count");
+        goto lshift_error;
+    }
+    /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
+    wordshift = shiftby / PyLong_SHIFT;
+    remshift  = shiftby - wordshift * PyLong_SHIFT;
+
+    oldsize = ABS(a->ob_size);
+    newsize = oldsize + wordshift;
+    if (remshift)
+        ++newsize;
+    z = _PyLong_New(newsize);
+    if (z == NULL)
+        goto lshift_error;
+    if (a->ob_size < 0)
+        z->ob_size = -(z->ob_size);
+    for (i = 0; i < wordshift; i++)
+        z->ob_digit[i] = 0;
+    accum = 0;
+    for (i = wordshift, j = 0; j < oldsize; i++, j++) {
+        accum |= (twodigits)a->ob_digit[j] << remshift;
+        z->ob_digit[i] = (digit)(accum & PyLong_MASK);
+        accum >>= PyLong_SHIFT;
+    }
+    if (remshift)
+        z->ob_digit[newsize-1] = (digit)accum;
+    else
+        assert(!accum);
+    z = long_normalize(z);
+  lshift_error:
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *) z;
+}
+
+/* Compute two's complement of digit vector a[0:m], writing result to
+   z[0:m].  The digit vector a need not be normalized, but should not
+   be entirely zero.  a and z may point to the same digit vector. */
+
+static void
+v_complement(digit *z, digit *a, Py_ssize_t m)
+{
+    Py_ssize_t i;
+    digit carry = 1;
+    for (i = 0; i < m; ++i) {
+        carry += a[i] ^ PyLong_MASK;
+        z[i] = carry & PyLong_MASK;
+        carry >>= PyLong_SHIFT;
+    }
+    assert(carry == 0);
+}
+
+/* Bitwise and/xor/or operations */
+
+static PyObject *
+long_bitwise(PyLongObject *a,
+             int op,  /* '&', '|', '^' */
+             PyLongObject *b)
+{
+    int nega, negb, negz;
+    Py_ssize_t size_a, size_b, size_z, i;
+    PyLongObject *z;
+
+    /* Bitwise operations for negative numbers operate as though
+       on a two's complement representation.  So convert arguments
+       from sign-magnitude to two's complement, and convert the
+       result back to sign-magnitude at the end. */
+
+    /* If a is negative, replace it by its two's complement. */
+    size_a = ABS(Py_SIZE(a));
+    nega = Py_SIZE(a) < 0;
+    if (nega) {
+        z = _PyLong_New(size_a);
+        if (z == NULL)
+            return NULL;
+        v_complement(z->ob_digit, a->ob_digit, size_a);
+        a = z;
+    }
+    else
+        /* Keep reference count consistent. */
+        Py_INCREF(a);
+
+    /* Same for b. */
+    size_b = ABS(Py_SIZE(b));
+    negb = Py_SIZE(b) < 0;
+    if (negb) {
+        z = _PyLong_New(size_b);
+        if (z == NULL) {
+            Py_DECREF(a);
+            return NULL;
+        }
+        v_complement(z->ob_digit, b->ob_digit, size_b);
+        b = z;
+    }
+    else
+        Py_INCREF(b);
+
+    /* Swap a and b if necessary to ensure size_a >= size_b. */
+    if (size_a < size_b) {
+        z = a; a = b; b = z;
+        size_z = size_a; size_a = size_b; size_b = size_z;
+        negz = nega; nega = negb; negb = negz;
+    }
+
+    /* JRH: The original logic here was to allocate the result value (z)
+       as the longer of the two operands.  However, there are some cases
+       where the result is guaranteed to be shorter than that: AND of two
+       positives, OR of two negatives: use the shorter number.  AND with
+       mixed signs: use the positive number.  OR with mixed signs: use the
+       negative number.
+    */
+    switch (op) {
+    case '^':
+        negz = nega ^ negb;
+        size_z = size_a;
+        break;
+    case '&':
+        negz = nega & negb;
+        size_z = negb ? size_a : size_b;
+        break;
+    case '|':
+        negz = nega | negb;
+        size_z = negb ? size_b : size_a;
+        break;
+    default:
+        PyErr_BadArgument();
+        return NULL;
+    }
+
+    /* We allow an extra digit if z is negative, to make sure that
+       the final two's complement of z doesn't overflow. */
+    z = _PyLong_New(size_z + negz);
+    if (z == NULL) {
+        Py_DECREF(a);
+        Py_DECREF(b);
+        return NULL;
+    }
+
+    /* Compute digits for overlap of a and b. */
+    switch(op) {
+    case '&':
+        for (i = 0; i < size_b; ++i)
+            z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];
+        break;
+    case '|':
+        for (i = 0; i < size_b; ++i)
+            z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i];
+        break;
+    case '^':
+        for (i = 0; i < size_b; ++i)
+            z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i];
+        break;
+    default:
+        PyErr_BadArgument();
+        return NULL;
+    }
+
+    /* Copy any remaining digits of a, inverting if necessary. */
+    if (op == '^' && negb)
+        for (; i < size_z; ++i)
+            z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK;
+    else if (i < size_z)
+        memcpy(&z->ob_digit[i], &a->ob_digit[i],
+               (size_z-i)*sizeof(digit));
+
+    /* Complement result if negative. */
+    if (negz) {
+        Py_SIZE(z) = -(Py_SIZE(z));
+        z->ob_digit[size_z] = PyLong_MASK;
+        v_complement(z->ob_digit, z->ob_digit, size_z+1);
+    }
+
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return (PyObject *)long_normalize(z);
+}
+
+static PyObject *
+long_and(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b;
+    PyObject *c;
+    CONVERT_BINOP(v, w, &a, &b);
+    c = long_bitwise(a, '&', b);
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return c;
+}
+
+static PyObject *
+long_xor(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b;
+    PyObject *c;
+    CONVERT_BINOP(v, w, &a, &b);
+    c = long_bitwise(a, '^', b);
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return c;
+}
+
+static PyObject *
+long_or(PyObject *v, PyObject *w)
+{
+    PyLongObject *a, *b;
+    PyObject *c;
+    CONVERT_BINOP(v, w, &a, &b);
+    c = long_bitwise(a, '|', b);
+    Py_DECREF(a);
+    Py_DECREF(b);
+    return c;
+}
+
+static int
+long_coerce(PyObject **pv, PyObject **pw)
+{
+    if (PyInt_Check(*pw)) {
+        *pw = PyLong_FromLong(PyInt_AS_LONG(*pw));
+        if (*pw == NULL)
+            return -1;
+        Py_INCREF(*pv);
+        return 0;
+    }
+    else if (PyLong_Check(*pw)) {
+        Py_INCREF(*pv);
+        Py_INCREF(*pw);
+        return 0;
+    }
+    return 1; /* Can't do it */
+}
+
+static PyObject *
+long_long(PyObject *v)
+{
+    if (PyLong_CheckExact(v))
+        Py_INCREF(v);
+    else
+        v = _PyLong_Copy((PyLongObject *)v);
+    return v;
+}
+
+static PyObject *
+long_int(PyObject *v)
+{
+    long x;
+    x = PyLong_AsLong(v);
+    if (PyErr_Occurred()) {
+        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+            PyErr_Clear();
+            if (PyLong_CheckExact(v)) {
+                Py_INCREF(v);
+                return v;
+            }
+            else
+                return _PyLong_Copy((PyLongObject *)v);
+        }
+        else
+            return NULL;
+    }
+    return PyInt_FromLong(x);
+}
+
+static PyObject *
+long_float(PyObject *v)
+{
+    double result;
+    result = PyLong_AsDouble(v);
+    if (result == -1.0 && PyErr_Occurred())
+        return NULL;
+    return PyFloat_FromDouble(result);
+}
+
+static PyObject *
+long_oct(PyObject *v)
+{
+    return _PyLong_Format(v, 8, 1, 0);
+}
+
+static PyObject *
+long_hex(PyObject *v)
+{
+    return _PyLong_Format(v, 16, 1, 0);
+}
+
+static PyObject *
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *x = NULL;
+    int base = -909;                         /* unlikely! */
+    static char *kwlist[] = {"x", "base", 0};
+
+    if (type != &PyLong_Type)
+        return long_subtype_new(type, args, kwds); /* Wimp out */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
+                                     &x, &base))
+        return NULL;
+    if (x == NULL) {
+        if (base != -909) {
+            PyErr_SetString(PyExc_TypeError,
+                            "long() missing string argument");
+            return NULL;
+        }
+        return PyLong_FromLong(0L);
+    }
+    if (base == -909)
+        return PyNumber_Long(x);
+    else if (PyString_Check(x)) {
+        /* Since PyLong_FromString doesn't have a length parameter,
+         * check here for possible NULs in the string. */
+        char *string = PyString_AS_STRING(x);
+        if (strlen(string) != (size_t)PyString_Size(x)) {
+            /* create a repr() of the input string,
+             * just like PyLong_FromString does. */
+            PyObject *srepr;
+            srepr = PyObject_Repr(x);
+            if (srepr == NULL)
+                return NULL;
+            PyErr_Format(PyExc_ValueError,
+                         "invalid literal for long() with base %d: %s",
+                         base, PyString_AS_STRING(srepr));
+            Py_DECREF(srepr);
+            return NULL;
+        }
+        return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(x))
+        return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
+                                  PyUnicode_GET_SIZE(x),
+                                  base);
+#endif
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "long() can't convert non-string with explicit base");
+        return NULL;
+    }
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of long:
+   first create a regular long from whatever arguments we got,
+   then allocate a subtype instance and initialize it from
+   the regular long.  The regular long is then thrown away.
+*/
+static PyObject *
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyLongObject *tmp, *newobj;
+    Py_ssize_t i, n;
+
+    assert(PyType_IsSubtype(type, &PyLong_Type));
+    tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
+    if (tmp == NULL)
+        return NULL;
+    assert(PyLong_CheckExact(tmp));
+    n = Py_SIZE(tmp);
+    if (n < 0)
+        n = -n;
+    newobj = (PyLongObject *)type->tp_alloc(type, n);
+    if (newobj == NULL) {
+        Py_DECREF(tmp);
+        return NULL;
+    }
+    assert(PyLong_Check(newobj));
+    Py_SIZE(newobj) = Py_SIZE(tmp);
+    for (i = 0; i < n; i++)
+        newobj->ob_digit[i] = tmp->ob_digit[i];
+    Py_DECREF(tmp);
+    return (PyObject *)newobj;
+}
+
+static PyObject *
+long_getnewargs(PyLongObject *v)
+{
+    return Py_BuildValue("(N)", _PyLong_Copy(v));
+}
+
+static PyObject *
+long_get0(PyLongObject *v, void *context) {
+    return PyLong_FromLong(0L);
+}
+
+static PyObject *
+long_get1(PyLongObject *v, void *context) {
+    return PyLong_FromLong(1L);
+}
+
+static PyObject *
+long__format__(PyObject *self, PyObject *args)
+{
+    PyObject *format_spec;
+
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+        return NULL;
+    if (PyBytes_Check(format_spec))
+        return _PyLong_FormatAdvanced(self,
+                                      PyBytes_AS_STRING(format_spec),
+                                      PyBytes_GET_SIZE(format_spec));
+    if (PyUnicode_Check(format_spec)) {
+        /* Convert format_spec to a str */
+        PyObject *result;
+        PyObject *str_spec = PyObject_Str(format_spec);
+
+        if (str_spec == NULL)
+            return NULL;
+
+        result = _PyLong_FormatAdvanced(self,
+                                        PyBytes_AS_STRING(str_spec),
+                                        PyBytes_GET_SIZE(str_spec));
+
+        Py_DECREF(str_spec);
+        return result;
+    }
+    PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+    return NULL;
+}
+
+static PyObject *
+long_sizeof(PyLongObject *v)
+{
+    Py_ssize_t res;
+
+    res = v->ob_type->tp_basicsize + ABS(Py_SIZE(v))*sizeof(digit);
+    return PyInt_FromSsize_t(res);
+}
+
+static PyObject *
+long_bit_length(PyLongObject *v)
+{
+    PyLongObject *result, *x, *y;
+    Py_ssize_t ndigits, msd_bits = 0;
+    digit msd;
+
+    assert(v != NULL);
+    assert(PyLong_Check(v));
+
+    ndigits = ABS(Py_SIZE(v));
+    if (ndigits == 0)
+        return PyInt_FromLong(0);
+
+    msd = v->ob_digit[ndigits-1];
+    while (msd >= 32) {
+        msd_bits += 6;
+        msd >>= 6;
+    }
+    msd_bits += (long)(BitLengthTable[msd]);
+
+    if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
+        return PyInt_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);
+
+    /* expression above may overflow; use Python integers instead */
+    result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1);
+    if (result == NULL)
+        return NULL;
+    x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT);
+    if (x == NULL)
+        goto error;
+    y = (PyLongObject *)long_mul(result, x);
+    Py_DECREF(x);
+    if (y == NULL)
+        goto error;
+    Py_DECREF(result);
+    result = y;
+
+    x = (PyLongObject *)PyLong_FromLong((long)msd_bits);
+    if (x == NULL)
+        goto error;
+    y = (PyLongObject *)long_add(result, x);
+    Py_DECREF(x);
+    if (y == NULL)
+        goto error;
+    Py_DECREF(result);
+    result = y;
+
+    return (PyObject *)result;
+
+  error:
+    Py_DECREF(result);
+    return NULL;
+}
+
+PyDoc_STRVAR(long_bit_length_doc,
+"long.bit_length() -> int or long\n\
+\n\
+Number of bits necessary to represent self in binary.\n\
+>>> bin(37L)\n\
+'0b100101'\n\
+>>> (37L).bit_length()\n\
+6");
+
+#if 0
+static PyObject *
+long_is_finite(PyObject *v)
+{
+    Py_RETURN_TRUE;
+}
+#endif
+
+static PyMethodDef long_methods[] = {
+    {"conjugate",       (PyCFunction)long_long, METH_NOARGS,
+     "Returns self, the complex conjugate of any long."},
+    {"bit_length",      (PyCFunction)long_bit_length, METH_NOARGS,
+     long_bit_length_doc},
+#if 0
+    {"is_finite",       (PyCFunction)long_is_finite,    METH_NOARGS,
+     "Returns always True."},
+#endif
+    {"__trunc__",       (PyCFunction)long_long, METH_NOARGS,
+     "Truncating an Integral returns itself."},
+    {"__getnewargs__",          (PyCFunction)long_getnewargs,   METH_NOARGS},
+    {"__format__", (PyCFunction)long__format__, METH_VARARGS},
+    {"__sizeof__",      (PyCFunction)long_sizeof, METH_NOARGS,
+     "Returns size in memory, in bytes"},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyGetSetDef long_getset[] = {
+    {"real",
+     (getter)long_long, (setter)NULL,
+     "the real part of a complex number",
+     NULL},
+    {"imag",
+     (getter)long_get0, (setter)NULL,
+     "the imaginary part of a complex number",
+     NULL},
+    {"numerator",
+     (getter)long_long, (setter)NULL,
+     "the numerator of a rational number in lowest terms",
+     NULL},
+    {"denominator",
+     (getter)long_get1, (setter)NULL,
+     "the denominator of a rational number in lowest terms",
+     NULL},
+    {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(long_doc,
+"long(x=0) -> long\n\
+long(x, base=10) -> long\n\
+\n\
+Convert a number or string to a long integer, or return 0L if no arguments\n\
+are given.  If x is floating point, the conversion truncates towards zero.\n\
+\n\
+If x is not a number or if base is given, then x must be a string or\n\
+Unicode object representing an integer literal in the given base.  The\n\
+literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\
+The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to\n\
+interpret the base from the string as an integer literal.\n\
+>>> int('0b100', base=0)\n\
+4L");
+
+static PyNumberMethods long_as_number = {
+    (binaryfunc)long_add,       /*nb_add*/
+    (binaryfunc)long_sub,       /*nb_subtract*/
+    (binaryfunc)long_mul,       /*nb_multiply*/
+    long_classic_div,           /*nb_divide*/
+    long_mod,                   /*nb_remainder*/
+    long_divmod,                /*nb_divmod*/
+    long_pow,                   /*nb_power*/
+    (unaryfunc)long_neg,        /*nb_negative*/
+    (unaryfunc)long_long,       /*tp_positive*/
+    (unaryfunc)long_abs,        /*tp_absolute*/
+    (inquiry)long_nonzero,      /*tp_nonzero*/
+    (unaryfunc)long_invert,     /*nb_invert*/
+    long_lshift,                /*nb_lshift*/
+    (binaryfunc)long_rshift,    /*nb_rshift*/
+    long_and,                   /*nb_and*/
+    long_xor,                   /*nb_xor*/
+    long_or,                    /*nb_or*/
+    long_coerce,                /*nb_coerce*/
+    long_int,                   /*nb_int*/
+    long_long,                  /*nb_long*/
+    long_float,                 /*nb_float*/
+    long_oct,                   /*nb_oct*/
+    long_hex,                   /*nb_hex*/
+    0,                          /* nb_inplace_add */
+    0,                          /* nb_inplace_subtract */
+    0,                          /* nb_inplace_multiply */
+    0,                          /* nb_inplace_divide */
+    0,                          /* nb_inplace_remainder */
+    0,                          /* nb_inplace_power */
+    0,                          /* nb_inplace_lshift */
+    0,                          /* nb_inplace_rshift */
+    0,                          /* nb_inplace_and */
+    0,                          /* nb_inplace_xor */
+    0,                          /* nb_inplace_or */
+    long_div,                   /* nb_floor_divide */
+    long_true_divide,           /* nb_true_divide */
+    0,                          /* nb_inplace_floor_divide */
+    0,                          /* nb_inplace_true_divide */
+    long_long,                  /* nb_index */
+};
+
+PyTypeObject PyLong_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                                          /* ob_size */
+    "long",                                     /* tp_name */
+    offsetof(PyLongObject, ob_digit),           /* tp_basicsize */
+    sizeof(digit),                              /* tp_itemsize */
+    long_dealloc,                               /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)long_compare,                      /* tp_compare */
+    long_repr,                                  /* tp_repr */
+    &long_as_number,                            /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)long_hash,                        /* tp_hash */
+    0,                                          /* tp_call */
+    long_str,                                   /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */
+    long_doc,                                   /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    long_methods,                               /* tp_methods */
+    0,                                          /* tp_members */
+    long_getset,                                /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    long_new,                                   /* tp_new */
+    PyObject_Del,                               /* tp_free */
+};
+
+static PyTypeObject Long_InfoType;
+
+PyDoc_STRVAR(long_info__doc__,
+"sys.long_info\n\
+\n\
+A struct sequence that holds information about Python's\n\
+internal representation of integers.  The attributes are read only.");
+
+static PyStructSequence_Field long_info_fields[] = {
+    {"bits_per_digit", "size of a digit in bits"},
+    {"sizeof_digit", "size in bytes of the C type used to represent a digit"},
+    {NULL, NULL}
+};
+
+static PyStructSequence_Desc long_info_desc = {
+    "sys.long_info",   /* name */
+    long_info__doc__,  /* doc */
+    long_info_fields,  /* fields */
+    2                  /* number of fields */
+};
+
+PyObject *
+PyLong_GetInfo(void)
+{
+    PyObject* long_info;
+    int field = 0;
+    long_info = PyStructSequence_New(&Long_InfoType);
+    if (long_info == NULL)
+        return NULL;
+    PyStructSequence_SET_ITEM(long_info, field++,
+                              PyInt_FromLong(PyLong_SHIFT));
+    PyStructSequence_SET_ITEM(long_info, field++,
+                              PyInt_FromLong(sizeof(digit)));
+    if (PyErr_Occurred()) {
+        Py_CLEAR(long_info);
+        return NULL;
+    }
+    return long_info;
+}
+
+int
+_PyLong_Init(void)
+{
+    /* initialize long_info */
+    if (Long_InfoType.tp_name == 0)
+        PyStructSequence_InitType(&Long_InfoType, &long_info_desc);
+    return 1;
+}
diff --git a/Python-2.7.5/Objects/memoryobject.c b/Python-2.7.5/Objects/memoryobject.c
new file mode 100644
index 0000000..2bac266
--- /dev/null
+++ b/Python-2.7.5/Objects/memoryobject.c
@@ -0,0 +1,842 @@
+
+/* Memoryview object implementation */
+
+#include "Python.h"
+
+static Py_ssize_t
+get_shape0(Py_buffer *buf)
+{
+    if (buf->shape != NULL)
+        return buf->shape[0];
+    if (buf->ndim == 0)
+        return 1;
+    PyErr_SetString(PyExc_TypeError,
+        "exported buffer does not have any shape information associated "
+        "to it");
+    return -1;
+}
+
+static void
+dup_buffer(Py_buffer *dest, Py_buffer *src)
+{
+    *dest = *src;
+    if (src->ndim == 1 && src->shape != NULL) {
+        dest->shape = &(dest->smalltable[0]);
+        dest->shape[0] = get_shape0(src);
+    }
+    if (src->ndim == 1 && src->strides != NULL) {
+        dest->strides = &(dest->smalltable[1]);
+        dest->strides[0] = src->strides[0];
+    }
+}
+
+static int
+memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
+{
+    int res = 0;
+    if (self->view.obj != NULL)
+        res = PyObject_GetBuffer(self->view.obj, view, flags);
+    if (view)
+        dup_buffer(view, &self->view);
+    return res;
+}
+
+static void
+memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
+{
+    PyBuffer_Release(view);
+}
+
+PyDoc_STRVAR(memory_doc,
+"memoryview(object)\n\
+\n\
+Create a new memoryview object which references the given object.");
+
+PyObject *
+PyMemoryView_FromBuffer(Py_buffer *info)
+{
+    PyMemoryViewObject *mview;
+
+    mview = (PyMemoryViewObject *)
+        PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+    if (mview == NULL)
+        return NULL;
+    mview->base = NULL;
+    dup_buffer(&mview->view, info);
+    /* NOTE: mview->view.obj should already have been incref'ed as
+       part of PyBuffer_FillInfo(). */
+    _PyObject_GC_TRACK(mview);
+    return (PyObject *)mview;
+}
+
+PyObject *
+PyMemoryView_FromObject(PyObject *base)
+{
+    PyMemoryViewObject *mview;
+    Py_buffer view;
+
+    if (!PyObject_CheckBuffer(base)) {
+        PyErr_SetString(PyExc_TypeError,
+            "cannot make memory view because object does "
+            "not have the buffer interface");
+        return NULL;
+    }
+
+    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
+        return NULL;
+
+    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
+    if (mview == NULL) {
+        PyBuffer_Release(&view);
+        return NULL;
+    }
+
+    mview->base = base;
+    Py_INCREF(base);
+    return (PyObject *)mview;
+}
+
+static PyObject *
+memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+{
+    PyObject *obj;
+    static char *kwlist[] = {"object", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
+                                     &obj)) {
+        return NULL;
+    }
+
+    return PyMemoryView_FromObject(obj);
+}
+
+
+static void
+_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
+                 Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
+{
+    int k;
+    Py_ssize_t outstride;
+
+    if (nd==0) {
+        memcpy(dest, src, itemsize);
+    }
+    else if (nd == 1) {
+        for (k = 0; k<shape[0]; k++) {
+            memcpy(dest, src, itemsize);
+            dest += itemsize;
+            src += strides[0];
+        }
+    }
+    else {
+        if (fort == 'F') {
+            /* Copy first dimension first,
+               second dimension second, etc...
+               Set up the recursive loop backwards so that final
+               dimension is actually copied last.
+            */
+            outstride = itemsize;
+            for (k=1; k<nd-1;k++) {
+                outstride *= shape[k];
+            }
+            for (k=0; k<shape[nd-1]; k++) {
+                _strided_copy_nd(dest, src, nd-1, shape,
+                                 strides, itemsize, fort);
+                dest += outstride;
+                src += strides[nd-1];
+            }
+        }
+
+        else {
+            /* Copy last dimension first,
+               second-to-last dimension second, etc.
+               Set up the recursion so that the
+               first dimension is copied last
+            */
+            outstride = itemsize;
+            for (k=1; k < nd; k++) {
+                outstride *= shape[k];
+            }
+            for (k=0; k<shape[0]; k++) {
+                _strided_copy_nd(dest, src, nd-1, shape+1,
+                                 strides+1, itemsize,
+                                 fort);
+                dest += outstride;
+                src += strides[0];
+            }
+        }
+    }
+    return;
+}
+
+static int
+_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
+{
+    Py_ssize_t *indices;
+    int k;
+    Py_ssize_t elements;
+    char *ptr;
+    void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
+
+    if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
+        PyErr_NoMemory();
+        return -1;
+    }
+
+    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
+    if (indices == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    for (k=0; k<view->ndim;k++) {
+        indices[k] = 0;
+    }
+
+    elements = 1;
+    for (k=0; k<view->ndim; k++) {
+        elements *= view->shape[k];
+    }
+    if (fort == 'F') {
+        func = _Py_add_one_to_index_F;
+    }
+    else {
+        func = _Py_add_one_to_index_C;
+    }
+    while (elements--) {
+        func(view->ndim, indices, view->shape);
+        ptr = PyBuffer_GetPointer(view, indices);
+        memcpy(dest, ptr, view->itemsize);
+        dest += view->itemsize;
+    }
+
+    PyMem_Free(indices);
+    return 0;
+}
+
+/*
+   Get a the data from an object as a contiguous chunk of memory (in
+   either 'C' or 'F'ortran order) even if it means copying it into a
+   separate memory area.
+
+   Returns a new reference to a Memory view object.  If no copy is needed,
+   the memory view object points to the original memory and holds a
+   lock on the original.  If a copy is needed, then the memory view object
+   points to a brand-new Bytes object (and holds a memory lock on it).
+
+   buffertype
+
+   PyBUF_READ  buffer only needs to be read-only
+   PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
+   PyBUF_SHADOW buffer needs to be writable so shadow it with
+                a contiguous buffer if it is not. The view will point to
+                the shadow buffer which can be written to and then
+                will be copied back into the other buffer when the memory
+                view is de-allocated.  While the shadow buffer is
+                being used, it will have an exclusive write lock on
+                the original buffer.
+ */
+
+PyObject *
+PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
+{
+    PyMemoryViewObject *mem;
+    PyObject *bytes;
+    Py_buffer *view;
+    int flags;
+    char *dest;
+
+    if (!PyObject_CheckBuffer(obj)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "object does not have the buffer interface");
+        return NULL;
+    }
+
+    mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+    if (mem == NULL)
+        return NULL;
+
+    view = &mem->view;
+    flags = PyBUF_FULL_RO;
+    switch(buffertype) {
+    case PyBUF_WRITE:
+        flags = PyBUF_FULL;
+        break;
+    }
+
+    if (PyObject_GetBuffer(obj, view, flags) != 0) {
+        Py_DECREF(mem);
+        return NULL;
+    }
+
+    if (PyBuffer_IsContiguous(view, fort)) {
+        /* no copy needed */
+        Py_INCREF(obj);
+        mem->base = obj;
+        _PyObject_GC_TRACK(mem);
+        return (PyObject *)mem;
+    }
+    /* otherwise a copy is needed */
+    if (buffertype == PyBUF_WRITE) {
+        Py_DECREF(mem);
+        PyErr_SetString(PyExc_BufferError,
+                        "writable contiguous buffer requested "
+                        "for a non-contiguousobject.");
+        return NULL;
+    }
+    bytes = PyBytes_FromStringAndSize(NULL, view->len);
+    if (bytes == NULL) {
+        Py_DECREF(mem);
+        return NULL;
+    }
+    dest = PyBytes_AS_STRING(bytes);
+    /* different copying strategy depending on whether
+       or not any pointer de-referencing is needed
+    */
+    /* strided or in-direct copy */
+    if (view->suboffsets==NULL) {
+        _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
+                         view->strides, view->itemsize, fort);
+    }
+    else {
+        if (_indirect_copy_nd(dest, view, fort) < 0) {
+            Py_DECREF(bytes);
+            Py_DECREF(mem);
+            return NULL;
+        }
+    }
+    if (buffertype == PyBUF_SHADOW) {
+        /* return a shadowed memory-view object */
+        view->buf = dest;
+        mem->base = PyTuple_Pack(2, obj, bytes);
+        Py_DECREF(bytes);
+        if (mem->base == NULL) {
+            Py_DECREF(mem);
+            return NULL;
+        }
+    }
+    else {
+        PyBuffer_Release(view);  /* XXX ? */
+        /* steal the reference */
+        mem->base = bytes;
+    }
+    _PyObject_GC_TRACK(mem);
+    return (PyObject *)mem;
+}
+
+
+static PyObject *
+memory_format_get(PyMemoryViewObject *self)
+{
+    return PyString_FromString(self->view.format);
+}
+
+static PyObject *
+memory_itemsize_get(PyMemoryViewObject *self)
+{
+    return PyLong_FromSsize_t(self->view.itemsize);
+}
+
+static PyObject *
+_IntTupleFromSsizet(int len, Py_ssize_t *vals)
+{
+    int i;
+    PyObject *o;
+    PyObject *intTuple;
+
+    if (vals == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    intTuple = PyTuple_New(len);
+    if (!intTuple) return NULL;
+    for(i=0; i<len; i++) {
+        o = PyLong_FromSsize_t(vals[i]);
+        if (!o) {
+            Py_DECREF(intTuple);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(intTuple, i, o);
+    }
+    return intTuple;
+}
+
+static PyObject *
+memory_shape_get(PyMemoryViewObject *self)
+{
+    return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
+}
+
+static PyObject *
+memory_strides_get(PyMemoryViewObject *self)
+{
+    return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
+}
+
+static PyObject *
+memory_suboffsets_get(PyMemoryViewObject *self)
+{
+    return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
+}
+
+static PyObject *
+memory_readonly_get(PyMemoryViewObject *self)
+{
+    return PyBool_FromLong(self->view.readonly);
+}
+
+static PyObject *
+memory_ndim_get(PyMemoryViewObject *self)
+{
+    return PyLong_FromLong(self->view.ndim);
+}
+
+static PyGetSetDef memory_getsetlist[] ={
+    {"format",          (getter)memory_format_get,      NULL, NULL},
+    {"itemsize",        (getter)memory_itemsize_get,    NULL, NULL},
+    {"shape",           (getter)memory_shape_get,       NULL, NULL},
+    {"strides",         (getter)memory_strides_get,     NULL, NULL},
+    {"suboffsets",      (getter)memory_suboffsets_get,  NULL, NULL},
+    {"readonly",        (getter)memory_readonly_get,    NULL, NULL},
+    {"ndim",            (getter)memory_ndim_get,        NULL, NULL},
+    {NULL, NULL, NULL, NULL},
+};
+
+
+static PyObject *
+memory_tobytes(PyMemoryViewObject *self, PyObject *noargs)
+{
+    Py_buffer view;
+    PyObject *res;
+
+    if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_SIMPLE) < 0)
+        return NULL;
+
+    res = PyBytes_FromStringAndSize(NULL, view.len);
+    PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
+    PyBuffer_Release(&view);
+    return res;
+}
+
+/* TODO: rewrite this function using the struct module to unpack
+   each buffer item */
+
+static PyObject *
+memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
+{
+    Py_buffer *view = &(mem->view);
+    Py_ssize_t i;
+    PyObject *res, *item;
+    char *buf;
+
+    if (strcmp(view->format, "B") || view->itemsize != 1) {
+        PyErr_SetString(PyExc_NotImplementedError, 
+                "tolist() only supports byte views");
+        return NULL;
+    }
+    if (view->ndim != 1) {
+        PyErr_SetString(PyExc_NotImplementedError, 
+                "tolist() only supports one-dimensional objects");
+        return NULL;
+    }
+    res = PyList_New(view->len);
+    if (res == NULL)
+        return NULL;
+    buf = view->buf;
+    for (i = 0; i < view->len; i++) {
+        item = PyInt_FromLong((unsigned char) *buf);
+        if (item == NULL) {
+            Py_DECREF(res);
+            return NULL;
+        }
+        PyList_SET_ITEM(res, i, item);
+        buf++;
+    }
+    return res;
+}
+
+static PyMethodDef memory_methods[] = {
+    {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
+    {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
+    {NULL,          NULL}           /* sentinel */
+};
+
+
+static void
+memory_dealloc(PyMemoryViewObject *self)
+{
+    _PyObject_GC_UNTRACK(self);
+    if (self->view.obj != NULL) {
+        if (self->base && PyTuple_Check(self->base)) {
+            /* Special case when first element is generic object
+               with buffer interface and the second element is a
+               contiguous "shadow" that must be copied back into
+               the data areay of the first tuple element before
+               releasing the buffer on the first element.
+            */
+
+            PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
+                              PyTuple_GET_ITEM(self->base,1));
+
+            /* The view member should have readonly == -1 in
+               this instance indicating that the memory can
+               be "locked" and was locked and will be unlocked
+               again after this call.
+            */
+            PyBuffer_Release(&(self->view));
+        }
+        else {
+            PyBuffer_Release(&(self->view));
+        }
+        Py_CLEAR(self->base);
+    }
+    PyObject_GC_Del(self);
+}
+
+static PyObject *
+memory_repr(PyMemoryViewObject *self)
+{
+    return PyString_FromFormat("<memory at %p>", self);
+}
+
+/* Sequence methods */
+static Py_ssize_t
+memory_length(PyMemoryViewObject *self)
+{
+    return get_shape0(&self->view);
+}
+
+/* Alternate version of memory_subcript that only accepts indices.
+   Used by PySeqIter_New().
+*/
+static PyObject *
+memory_item(PyMemoryViewObject *self, Py_ssize_t result)
+{
+    Py_buffer *view = &(self->view);
+
+    if (view->ndim == 0) {
+        PyErr_SetString(PyExc_IndexError,
+                        "invalid indexing of 0-dim memory");
+        return NULL;
+    }
+    if (view->ndim == 1) {
+        /* Return a bytes object */
+        char *ptr;
+        ptr = (char *)view->buf;
+        if (result < 0) {
+            result += get_shape0(view);
+        }
+        if ((result < 0) || (result >= get_shape0(view))) {
+            PyErr_SetString(PyExc_IndexError,
+                                "index out of bounds");
+            return NULL;
+        }
+        if (view->strides == NULL)
+            ptr += view->itemsize * result;
+        else
+            ptr += view->strides[0] * result;
+        if (view->suboffsets != NULL &&
+            view->suboffsets[0] >= 0) {
+            ptr = *((char **)ptr) + view->suboffsets[0];
+        }
+        return PyBytes_FromStringAndSize(ptr, view->itemsize);
+    } else {
+        /* Return a new memory-view object */
+        Py_buffer newview;
+        memset(&newview, 0, sizeof(newview));
+        /* XXX:  This needs to be fixed so it actually returns a sub-view */
+        return PyMemoryView_FromBuffer(&newview);
+    }
+}
+
+/*
+  mem[obj] returns a bytes object holding the data for one element if
+           obj fully indexes the memory view or another memory-view object
+           if it does not.
+
+           0-d memory-view objects can be referenced using ... or () but
+           not with anything else.
+ */
+static PyObject *
+memory_subscript(PyMemoryViewObject *self, PyObject *key)
+{
+    Py_buffer *view;
+    view = &(self->view);
+    
+    if (view->ndim == 0) {
+        if (key == Py_Ellipsis ||
+            (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
+            Py_INCREF(self);
+            return (PyObject *)self;
+        }
+        else {
+            PyErr_SetString(PyExc_IndexError,
+                                "invalid indexing of 0-dim memory");
+            return NULL;
+        }
+    }
+    if (PyIndex_Check(key)) {
+        Py_ssize_t result;
+        result = PyNumber_AsSsize_t(key, NULL);
+        if (result == -1 && PyErr_Occurred())
+                return NULL;
+        return memory_item(self, result);
+    }
+    else if (PySlice_Check(key)) {
+        Py_ssize_t start, stop, step, slicelength;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+                                 &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+    
+        if (step == 1 && view->ndim == 1) {
+            Py_buffer newview;
+            void *newbuf = (char *) view->buf
+                                    + start * view->itemsize;
+            int newflags = view->readonly
+                    ? PyBUF_CONTIG_RO : PyBUF_CONTIG;
+    
+            /* XXX There should be an API to create a subbuffer */
+            if (view->obj != NULL) {
+                if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)
+                    return NULL;
+            }
+            else {
+                newview = *view;
+            }
+            newview.buf = newbuf;
+            newview.len = slicelength * newview.itemsize;
+            newview.format = view->format;
+            newview.shape = &(newview.smalltable[0]);
+            newview.shape[0] = slicelength;
+            newview.strides = &(newview.itemsize);
+            return PyMemoryView_FromBuffer(&newview);
+        }
+        PyErr_SetNone(PyExc_NotImplementedError);
+        return NULL;
+    }
+    PyErr_Format(PyExc_TypeError,
+        "cannot index memory using \"%.200s\"", 
+        key->ob_type->tp_name);
+    return NULL;
+}
+
+
+/* Need to support assigning memory if we can */
+static int
+memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
+{
+    Py_ssize_t start, len, bytelen;
+    Py_buffer srcview;
+    Py_buffer *view = &(self->view);
+    char *srcbuf, *destbuf;
+
+    if (view->readonly) {
+        PyErr_SetString(PyExc_TypeError,
+            "cannot modify read-only memory");
+        return -1;
+    }
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "cannot delete memory");
+        return -1;
+    }
+    if (view->ndim != 1) {
+        PyErr_SetNone(PyExc_NotImplementedError);
+        return -1;
+    }
+    if (PyIndex_Check(key)) {
+        start = PyNumber_AsSsize_t(key, NULL);
+        if (start == -1 && PyErr_Occurred())
+            return -1;
+        if (start < 0) {
+            start += get_shape0(view);
+        }
+        if ((start < 0) || (start >= get_shape0(view))) {
+            PyErr_SetString(PyExc_IndexError,
+                            "index out of bounds");
+            return -1;
+        }
+        len = 1;
+    }
+    else if (PySlice_Check(key)) {
+        Py_ssize_t stop, step;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+                         &start, &stop, &step, &len) < 0) {
+            return -1;
+        }
+        if (step != 1) {
+            PyErr_SetNone(PyExc_NotImplementedError);
+            return -1;
+        }
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+            "cannot index memory using \"%.200s\"", 
+            key->ob_type->tp_name);
+        return -1;
+    }
+    if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
+        return -1;
+    }
+    /* XXX should we allow assignment of different item sizes
+       as long as the byte length is the same?
+       (e.g. assign 2 shorts to a 4-byte slice) */
+    if (srcview.itemsize != view->itemsize) {
+        PyErr_Format(PyExc_TypeError,
+            "mismatching item sizes for \"%.200s\" and \"%.200s\"", 
+            view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
+        goto _error;
+    }
+    bytelen = len * view->itemsize;
+    if (bytelen != srcview.len) {
+        PyErr_SetString(PyExc_ValueError,
+            "cannot modify size of memoryview object");
+        goto _error;
+    }
+    /* Do the actual copy */
+    destbuf = (char *) view->buf + start * view->itemsize;
+    srcbuf = (char *) srcview.buf;
+    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
+        /* No overlapping */
+        memcpy(destbuf, srcbuf, bytelen);
+    else
+        memmove(destbuf, srcbuf, bytelen);
+
+    PyBuffer_Release(&srcview);
+    return 0;
+
+_error:
+    PyBuffer_Release(&srcview);
+    return -1;
+}
+
+static PyObject *
+memory_richcompare(PyObject *v, PyObject *w, int op)
+{
+    Py_buffer vv, ww;
+    int equal = 0;
+    PyObject *res;
+
+    vv.obj = NULL;
+    ww.obj = NULL;
+    if (op != Py_EQ && op != Py_NE)
+        goto _notimpl;
+    if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
+        PyErr_Clear();
+        goto _notimpl;
+    }
+    if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
+        PyErr_Clear();
+        goto _notimpl;
+    }
+
+    if (vv.itemsize != ww.itemsize || vv.len != ww.len)
+        goto _end;
+
+    equal = !memcmp(vv.buf, ww.buf, vv.len);
+
+_end:
+    PyBuffer_Release(&vv);
+    PyBuffer_Release(&ww);
+    if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
+        res = Py_True;
+    else
+        res = Py_False;
+    Py_INCREF(res);
+    return res;
+
+_notimpl:
+    PyBuffer_Release(&vv);
+    PyBuffer_Release(&ww);
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+
+static int
+memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
+{
+    if (self->base != NULL)
+        Py_VISIT(self->base);
+    if (self->view.obj != NULL)
+        Py_VISIT(self->view.obj);
+    return 0;
+}
+
+static int
+memory_clear(PyMemoryViewObject *self)
+{
+    Py_CLEAR(self->base);
+    PyBuffer_Release(&self->view);
+    return 0;
+}
+
+
+/* As mapping */
+static PyMappingMethods memory_as_mapping = {
+    (lenfunc)memory_length,               /* mp_length */
+    (binaryfunc)memory_subscript,         /* mp_subscript */
+    (objobjargproc)memory_ass_sub,        /* mp_ass_subscript */
+};
+
+static PySequenceMethods memory_as_sequence = {
+	0,                                  /* sq_length */
+	0,                                  /* sq_concat */
+	0,                                  /* sq_repeat */
+	(ssizeargfunc)memory_item,          /* sq_item */
+};
+
+/* Buffer methods */
+static PyBufferProcs memory_as_buffer = {
+    0,                                    /* bf_getreadbuffer */
+    0,                                    /* bf_getwritebuffer */
+    0,                                    /* bf_getsegcount */
+    0,                                    /* bf_getcharbuffer */
+    (getbufferproc)memory_getbuf,         /* bf_getbuffer */
+    (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
+};
+
+
+PyTypeObject PyMemoryView_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "memoryview",
+    sizeof(PyMemoryViewObject),
+    0,
+    (destructor)memory_dealloc,               /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    (reprfunc)memory_repr,                    /* tp_repr */
+    0,                                        /* tp_as_number */
+    &memory_as_sequence,                      /* tp_as_sequence */
+    &memory_as_mapping,                       /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    PyObject_GenericGetAttr,                  /* tp_getattro */
+    0,                                        /* tp_setattro */
+    &memory_as_buffer,                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_HAVE_NEWBUFFER,            /* tp_flags */
+    memory_doc,                               /* tp_doc */
+    (traverseproc)memory_traverse,            /* tp_traverse */
+    (inquiry)memory_clear,                    /* tp_clear */
+    memory_richcompare,                       /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    memory_methods,                           /* tp_methods */
+    0,                                        /* tp_members */
+    memory_getsetlist,                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    memory_new,                               /* tp_new */
+};
diff --git a/Python-2.7.5/Objects/methodobject.c b/Python-2.7.5/Objects/methodobject.c
new file mode 100644
index 0000000..0b60ca3
--- /dev/null
+++ b/Python-2.7.5/Objects/methodobject.c
@@ -0,0 +1,427 @@
+
+/* Method object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Free list for method objects to safe malloc/free overhead
+ * The m_self element is used to chain the objects.
+ */
+static PyCFunctionObject *free_list = NULL;
+static int numfree = 0;
+#ifndef PyCFunction_MAXFREELIST
+#define PyCFunction_MAXFREELIST 256
+#endif
+
+PyObject *
+PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
+{
+    PyCFunctionObject *op;
+    op = free_list;
+    if (op != NULL) {
+        free_list = (PyCFunctionObject *)(op->m_self);
+        PyObject_INIT(op, &PyCFunction_Type);
+        numfree--;
+    }
+    else {
+        op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
+        if (op == NULL)
+            return NULL;
+    }
+    op->m_ml = ml;
+    Py_XINCREF(self);
+    op->m_self = self;
+    Py_XINCREF(module);
+    op->m_module = module;
+    _PyObject_GC_TRACK(op);
+    return (PyObject *)op;
+}
+
+PyCFunction
+PyCFunction_GetFunction(PyObject *op)
+{
+    if (!PyCFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
+}
+
+PyObject *
+PyCFunction_GetSelf(PyObject *op)
+{
+    if (!PyCFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return ((PyCFunctionObject *)op) -> m_self;
+}
+
+int
+PyCFunction_GetFlags(PyObject *op)
+{
+    if (!PyCFunction_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
+}
+
+PyObject *
+PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+    PyCFunctionObject* f = (PyCFunctionObject*)func;
+    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+    PyObject *self = PyCFunction_GET_SELF(func);
+    Py_ssize_t size;
+
+    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+    case METH_VARARGS:
+        if (kw == NULL || PyDict_Size(kw) == 0)
+            return (*meth)(self, arg);
+        break;
+    case METH_VARARGS | METH_KEYWORDS:
+    case METH_OLDARGS | METH_KEYWORDS:
+        return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+    case METH_NOARGS:
+        if (kw == NULL || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 0)
+                return (*meth)(self, NULL);
+            PyErr_Format(PyExc_TypeError,
+                "%.200s() takes no arguments (%zd given)",
+                f->m_ml->ml_name, size);
+            return NULL;
+        }
+        break;
+    case METH_O:
+        if (kw == NULL || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 1)
+                return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+            PyErr_Format(PyExc_TypeError,
+                "%.200s() takes exactly one argument (%zd given)",
+                f->m_ml->ml_name, size);
+            return NULL;
+        }
+        break;
+    case METH_OLDARGS:
+        /* the really old style */
+        if (kw == NULL || PyDict_Size(kw) == 0) {
+            size = PyTuple_GET_SIZE(arg);
+            if (size == 1)
+                arg = PyTuple_GET_ITEM(arg, 0);
+            else if (size == 0)
+                arg = NULL;
+            return (*meth)(self, arg);
+        }
+        break;
+    default:
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+                 f->m_ml->ml_name);
+    return NULL;
+}
+
+/* Methods (the standard built-in methods, that is) */
+
+static void
+meth_dealloc(PyCFunctionObject *m)
+{
+    _PyObject_GC_UNTRACK(m);
+    Py_XDECREF(m->m_self);
+    Py_XDECREF(m->m_module);
+    if (numfree < PyCFunction_MAXFREELIST) {
+        m->m_self = (PyObject *)free_list;
+        free_list = m;
+        numfree++;
+    }
+    else {
+        PyObject_GC_Del(m);
+    }
+}
+
+static PyObject *
+meth_get__doc__(PyCFunctionObject *m, void *closure)
+{
+    const char *doc = m->m_ml->ml_doc;
+
+    if (doc != NULL)
+        return PyString_FromString(doc);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+meth_get__name__(PyCFunctionObject *m, void *closure)
+{
+    return PyString_FromString(m->m_ml->ml_name);
+}
+
+static int
+meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
+{
+    Py_VISIT(m->m_self);
+    Py_VISIT(m->m_module);
+    return 0;
+}
+
+static PyObject *
+meth_get__self__(PyCFunctionObject *m, void *closure)
+{
+    PyObject *self;
+    if (PyEval_GetRestricted()) {
+        PyErr_SetString(PyExc_RuntimeError,
+            "method.__self__ not accessible in restricted mode");
+        return NULL;
+    }
+    self = m->m_self;
+    if (self == NULL)
+        self = Py_None;
+    Py_INCREF(self);
+    return self;
+}
+
+static PyGetSetDef meth_getsets [] = {
+    {"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
+    {"__name__", (getter)meth_get__name__, NULL, NULL},
+    {"__self__", (getter)meth_get__self__, NULL, NULL},
+    {0}
+};
+
+#define OFF(x) offsetof(PyCFunctionObject, x)
+
+static PyMemberDef meth_members[] = {
+    {"__module__",    T_OBJECT,     OFF(m_module), PY_WRITE_RESTRICTED},
+    {NULL}
+};
+
+static PyObject *
+meth_repr(PyCFunctionObject *m)
+{
+    if (m->m_self == NULL)
+        return PyString_FromFormat("<built-in function %s>",
+                                   m->m_ml->ml_name);
+    return PyString_FromFormat("<built-in method %s of %s object at %p>",
+                               m->m_ml->ml_name,
+                               m->m_self->ob_type->tp_name,
+                               m->m_self);
+}
+
+static int
+meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
+{
+    if (a->m_self != b->m_self)
+        return (a->m_self < b->m_self) ? -1 : 1;
+    if (a->m_ml->ml_meth == b->m_ml->ml_meth)
+        return 0;
+    if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
+        return -1;
+    else
+        return 1;
+}
+
+static PyObject *
+meth_richcompare(PyObject *self, PyObject *other, int op)
+{
+    PyCFunctionObject *a, *b;
+    PyObject *res;
+    int eq;
+
+    if (op != Py_EQ && op != Py_NE) {
+        /* Py3K warning if comparison isn't == or !=.  */
+        if (PyErr_WarnPy3k("builtin_function_or_method order "
+                           "comparisons not supported in 3.x", 1) < 0) {
+            return NULL;
+        }
+
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    else if (!PyCFunction_Check(self) || !PyCFunction_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    a = (PyCFunctionObject *)self;
+    b = (PyCFunctionObject *)other;
+    eq = a->m_self == b->m_self;
+    if (eq)
+        eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
+    if (op == Py_EQ)
+        res = eq ? Py_True : Py_False;
+    else
+        res = eq ? Py_False : Py_True;
+    Py_INCREF(res);
+    return res;
+}
+
+static long
+meth_hash(PyCFunctionObject *a)
+{
+    long x,y;
+    if (a->m_self == NULL)
+        x = 0;
+    else {
+        x = PyObject_Hash(a->m_self);
+        if (x == -1)
+            return -1;
+    }
+    y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
+    if (y == -1)
+        return -1;
+    x ^= y;
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+
+PyTypeObject PyCFunction_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "builtin_function_or_method",
+    sizeof(PyCFunctionObject),
+    0,
+    (destructor)meth_dealloc,                   /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)meth_compare,                      /* tp_compare */
+    (reprfunc)meth_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)meth_hash,                        /* tp_hash */
+    PyCFunction_Call,                           /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)meth_traverse,                /* tp_traverse */
+    0,                                          /* tp_clear */
+    meth_richcompare,                                           /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    meth_members,                               /* tp_members */
+    meth_getsets,                               /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+};
+
+/* List all methods in a chain -- helper for findmethodinchain */
+
+static PyObject *
+listmethodchain(PyMethodChain *chain)
+{
+    PyMethodChain *c;
+    PyMethodDef *ml;
+    int i, n;
+    PyObject *v;
+
+    n = 0;
+    for (c = chain; c != NULL; c = c->link) {
+        for (ml = c->methods; ml->ml_name != NULL; ml++)
+            n++;
+    }
+    v = PyList_New(n);
+    if (v == NULL)
+        return NULL;
+    i = 0;
+    for (c = chain; c != NULL; c = c->link) {
+        for (ml = c->methods; ml->ml_name != NULL; ml++) {
+            PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
+            i++;
+        }
+    }
+    if (PyErr_Occurred()) {
+        Py_DECREF(v);
+        return NULL;
+    }
+    PyList_Sort(v);
+    return v;
+}
+
+/* Find a method in a method chain */
+
+PyObject *
+Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name)
+{
+    if (name[0] == '_' && name[1] == '_') {
+        if (strcmp(name, "__methods__") == 0) {
+            if (PyErr_WarnPy3k("__methods__ not supported in 3.x",
+                               1) < 0)
+                return NULL;
+            return listmethodchain(chain);
+        }
+        if (strcmp(name, "__doc__") == 0) {
+            const char *doc = self->ob_type->tp_doc;
+            if (doc != NULL)
+                return PyString_FromString(doc);
+        }
+    }
+    while (chain != NULL) {
+        PyMethodDef *ml = chain->methods;
+        for (; ml->ml_name != NULL; ml++) {
+            if (name[0] == ml->ml_name[0] &&
+                strcmp(name+1, ml->ml_name+1) == 0)
+                /* XXX */
+                return PyCFunction_New(ml, self);
+        }
+        chain = chain->link;
+    }
+    PyErr_SetString(PyExc_AttributeError, name);
+    return NULL;
+}
+
+/* Find a method in a single method list */
+
+PyObject *
+Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name)
+{
+    PyMethodChain chain;
+    chain.methods = methods;
+    chain.link = NULL;
+    return Py_FindMethodInChain(&chain, self, name);
+}
+
+/* Clear out the free list */
+
+int
+PyCFunction_ClearFreeList(void)
+{
+    int freelist_size = numfree;
+
+    while (free_list) {
+        PyCFunctionObject *v = free_list;
+        free_list = (PyCFunctionObject *)(v->m_self);
+        PyObject_GC_Del(v);
+        numfree--;
+    }
+    assert(numfree == 0);
+    return freelist_size;
+}
+
+void
+PyCFunction_Fini(void)
+{
+    (void)PyCFunction_ClearFreeList();
+}
+
+/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
+   but it's part of the API so we need to keep a function around that
+   existing C extensions can call.
+*/
+
+#undef PyCFunction_New
+PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
+
+PyObject *
+PyCFunction_New(PyMethodDef *ml, PyObject *self)
+{
+    return PyCFunction_NewEx(ml, self, NULL);
+}
diff --git a/Python-2.7.5/Objects/moduleobject.c b/Python-2.7.5/Objects/moduleobject.c
new file mode 100644
index 0000000..08e9740
--- /dev/null
+++ b/Python-2.7.5/Objects/moduleobject.c
@@ -0,0 +1,260 @@
+
+/* Module object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *md_dict;
+} PyModuleObject;
+
+static PyMemberDef module_members[] = {
+    {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
+    {0}
+};
+
+PyObject *
+PyModule_New(const char *name)
+{
+    PyModuleObject *m;
+    PyObject *nameobj;
+    m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
+    if (m == NULL)
+        return NULL;
+    nameobj = PyString_FromString(name);
+    m->md_dict = PyDict_New();
+    if (m->md_dict == NULL || nameobj == NULL)
+        goto fail;
+    if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
+        goto fail;
+    if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
+        goto fail;
+    if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)
+        goto fail;
+    Py_DECREF(nameobj);
+    PyObject_GC_Track(m);
+    return (PyObject *)m;
+
+ fail:
+    Py_XDECREF(nameobj);
+    Py_DECREF(m);
+    return NULL;
+}
+
+PyObject *
+PyModule_GetDict(PyObject *m)
+{
+    PyObject *d;
+    if (!PyModule_Check(m)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    d = ((PyModuleObject *)m) -> md_dict;
+    if (d == NULL)
+        ((PyModuleObject *)m) -> md_dict = d = PyDict_New();
+    return d;
+}
+
+char *
+PyModule_GetName(PyObject *m)
+{
+    PyObject *d;
+    PyObject *nameobj;
+    if (!PyModule_Check(m)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    d = ((PyModuleObject *)m)->md_dict;
+    if (d == NULL ||
+        (nameobj = PyDict_GetItemString(d, "__name__")) == NULL ||
+        !PyString_Check(nameobj))
+    {
+        PyErr_SetString(PyExc_SystemError, "nameless module");
+        return NULL;
+    }
+    return PyString_AsString(nameobj);
+}
+
+char *
+PyModule_GetFilename(PyObject *m)
+{
+    PyObject *d;
+    PyObject *fileobj;
+    if (!PyModule_Check(m)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    d = ((PyModuleObject *)m)->md_dict;
+    if (d == NULL ||
+        (fileobj = PyDict_GetItemString(d, "__file__")) == NULL ||
+        !PyString_Check(fileobj))
+    {
+        PyErr_SetString(PyExc_SystemError, "module filename missing");
+        return NULL;
+    }
+    return PyString_AsString(fileobj);
+}
+
+void
+_PyModule_Clear(PyObject *m)
+{
+    /* To make the execution order of destructors for global
+       objects a bit more predictable, we first zap all objects
+       whose name starts with a single underscore, before we clear
+       the entire dictionary.  We zap them by replacing them with
+       None, rather than deleting them from the dictionary, to
+       avoid rehashing the dictionary (to some extent). */
+
+    Py_ssize_t pos;
+    PyObject *key, *value;
+    PyObject *d;
+
+    d = ((PyModuleObject *)m)->md_dict;
+    if (d == NULL)
+        return;
+
+    /* First, clear only names starting with a single underscore */
+    pos = 0;
+    while (PyDict_Next(d, &pos, &key, &value)) {
+        if (value != Py_None && PyString_Check(key)) {
+            char *s = PyString_AsString(key);
+            if (s[0] == '_' && s[1] != '_') {
+                if (Py_VerboseFlag > 1)
+                    PySys_WriteStderr("#   clear[1] %s\n", s);
+                PyDict_SetItem(d, key, Py_None);
+            }
+        }
+    }
+
+    /* Next, clear all names except for __builtins__ */
+    pos = 0;
+    while (PyDict_Next(d, &pos, &key, &value)) {
+        if (value != Py_None && PyString_Check(key)) {
+            char *s = PyString_AsString(key);
+            if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
+                if (Py_VerboseFlag > 1)
+                    PySys_WriteStderr("#   clear[2] %s\n", s);
+                PyDict_SetItem(d, key, Py_None);
+            }
+        }
+    }
+
+    /* Note: we leave __builtins__ in place, so that destructors
+       of non-global objects defined in this module can still use
+       builtins, in particularly 'None'. */
+
+}
+
+/* Methods */
+
+static int
+module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"name", "doc", NULL};
+    PyObject *dict, *name = Py_None, *doc = Py_None;
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
+                                     kwlist, &name, &doc))
+        return -1;
+    dict = m->md_dict;
+    if (dict == NULL) {
+        dict = PyDict_New();
+        if (dict == NULL)
+            return -1;
+        m->md_dict = dict;
+    }
+    if (PyDict_SetItemString(dict, "__name__", name) < 0)
+        return -1;
+    if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
+        return -1;
+    return 0;
+}
+
+static void
+module_dealloc(PyModuleObject *m)
+{
+    PyObject_GC_UnTrack(m);
+    if (m->md_dict != NULL) {
+        _PyModule_Clear((PyObject *)m);
+        Py_DECREF(m->md_dict);
+    }
+    Py_TYPE(m)->tp_free((PyObject *)m);
+}
+
+static PyObject *
+module_repr(PyModuleObject *m)
+{
+    char *name;
+    char *filename;
+
+    name = PyModule_GetName((PyObject *)m);
+    if (name == NULL) {
+        PyErr_Clear();
+        name = "?";
+    }
+    filename = PyModule_GetFilename((PyObject *)m);
+    if (filename == NULL) {
+        PyErr_Clear();
+        return PyString_FromFormat("<module '%s' (built-in)>", name);
+    }
+    return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
+}
+
+/* We only need a traverse function, no clear function: If the module
+   is in a cycle, md_dict will be cleared as well, which will break
+   the cycle. */
+static int
+module_traverse(PyModuleObject *m, visitproc visit, void *arg)
+{
+    Py_VISIT(m->md_dict);
+    return 0;
+}
+
+PyDoc_STRVAR(module_doc,
+"module(name[, doc])\n\
+\n\
+Create a module object.\n\
+The name must be a string; the optional doc argument can have any type.");
+
+PyTypeObject PyModule_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "module",                                   /* tp_name */
+    sizeof(PyModuleObject),                     /* tp_size */
+    0,                                          /* tp_itemsize */
+    (destructor)module_dealloc,                 /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)module_repr,                      /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    PyObject_GenericSetAttr,                    /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    module_doc,                                 /* tp_doc */
+    (traverseproc)module_traverse,              /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    module_members,                             /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
+    (initproc)module_init,                      /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    PyType_GenericNew,                          /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
diff --git a/Python-2.7.5/Objects/object.c b/Python-2.7.5/Objects/object.c
new file mode 100644
index 0000000..14f4e9f
--- /dev/null
+++ b/Python-2.7.5/Objects/object.c
@@ -0,0 +1,2513 @@
+
+/* Generic object operations; and implementation of None (NoObject) */
+
+#include "Python.h"
+#include "frameobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef Py_REF_DEBUG
+Py_ssize_t _Py_RefTotal;
+
+Py_ssize_t
+_Py_GetRefTotal(void)
+{
+    PyObject *o;
+    Py_ssize_t total = _Py_RefTotal;
+    /* ignore the references to the dummy object of the dicts and sets
+       because they are not reliable and not useful (now that the
+       hash table code is well-tested) */
+    o = _PyDict_Dummy();
+    if (o != NULL)
+        total -= o->ob_refcnt;
+    o = _PySet_Dummy();
+    if (o != NULL)
+        total -= o->ob_refcnt;
+    return total;
+}
+#endif /* Py_REF_DEBUG */
+
+int Py_DivisionWarningFlag;
+int Py_Py3kWarningFlag;
+
+/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
+   These are used by the individual routines for object creation.
+   Do not call them otherwise, they do not initialize the object! */
+
+#ifdef Py_TRACE_REFS
+/* Head of circular doubly-linked list of all objects.  These are linked
+ * together via the _ob_prev and _ob_next members of a PyObject, which
+ * exist only in a Py_TRACE_REFS build.
+ */
+static PyObject refchain = {&refchain, &refchain};
+
+/* Insert op at the front of the list of all objects.  If force is true,
+ * op is added even if _ob_prev and _ob_next are non-NULL already.  If
+ * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
+ * force should be true if and only if op points to freshly allocated,
+ * uninitialized memory, or you've unlinked op from the list and are
+ * relinking it into the front.
+ * Note that objects are normally added to the list via _Py_NewReference,
+ * which is called by PyObject_Init.  Not all objects are initialized that
+ * way, though; exceptions include statically allocated type objects, and
+ * statically allocated singletons (like Py_True and Py_None).
+ */
+void
+_Py_AddToAllObjects(PyObject *op, int force)
+{
+#ifdef  Py_DEBUG
+    if (!force) {
+        /* If it's initialized memory, op must be in or out of
+         * the list unambiguously.
+         */
+        assert((op->_ob_prev == NULL) == (op->_ob_next == NULL));
+    }
+#endif
+    if (force || op->_ob_prev == NULL) {
+        op->_ob_next = refchain._ob_next;
+        op->_ob_prev = &refchain;
+        refchain._ob_next->_ob_prev = op;
+        refchain._ob_next = op;
+    }
+}
+#endif  /* Py_TRACE_REFS */
+
+#ifdef COUNT_ALLOCS
+static PyTypeObject *type_list;
+/* All types are added to type_list, at least when
+   they get one object created. That makes them
+   immortal, which unfortunately contributes to
+   garbage itself. If unlist_types_without_objects
+   is set, they will be removed from the type_list
+   once the last object is deallocated. */
+static int unlist_types_without_objects;
+extern Py_ssize_t tuple_zero_allocs, fast_tuple_allocs;
+extern Py_ssize_t quick_int_allocs, quick_neg_int_allocs;
+extern Py_ssize_t null_strings, one_strings;
+void
+dump_counts(FILE* f)
+{
+    PyTypeObject *tp;
+
+    for (tp = type_list; tp; tp = tp->tp_next)
+        fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, "
+            "freed: %" PY_FORMAT_SIZE_T "d, "
+            "max in use: %" PY_FORMAT_SIZE_T "d\n",
+            tp->tp_name, tp->tp_allocs, tp->tp_frees,
+            tp->tp_maxalloc);
+    fprintf(f, "fast tuple allocs: %" PY_FORMAT_SIZE_T "d, "
+        "empty: %" PY_FORMAT_SIZE_T "d\n",
+        fast_tuple_allocs, tuple_zero_allocs);
+    fprintf(f, "fast int allocs: pos: %" PY_FORMAT_SIZE_T "d, "
+        "neg: %" PY_FORMAT_SIZE_T "d\n",
+        quick_int_allocs, quick_neg_int_allocs);
+    fprintf(f, "null strings: %" PY_FORMAT_SIZE_T "d, "
+        "1-strings: %" PY_FORMAT_SIZE_T "d\n",
+        null_strings, one_strings);
+}
+
+PyObject *
+get_counts(void)
+{
+    PyTypeObject *tp;
+    PyObject *result;
+    PyObject *v;
+
+    result = PyList_New(0);
+    if (result == NULL)
+        return NULL;
+    for (tp = type_list; tp; tp = tp->tp_next) {
+        v = Py_BuildValue("(snnn)", tp->tp_name, tp->tp_allocs,
+                          tp->tp_frees, tp->tp_maxalloc);
+        if (v == NULL) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        if (PyList_Append(result, v) < 0) {
+            Py_DECREF(v);
+            Py_DECREF(result);
+            return NULL;
+        }
+        Py_DECREF(v);
+    }
+    return result;
+}
+
+void
+inc_count(PyTypeObject *tp)
+{
+    if (tp->tp_next == NULL && tp->tp_prev == NULL) {
+        /* first time; insert in linked list */
+        if (tp->tp_next != NULL) /* sanity check */
+            Py_FatalError("XXX inc_count sanity check");
+        if (type_list)
+            type_list->tp_prev = tp;
+        tp->tp_next = type_list;
+        /* Note that as of Python 2.2, heap-allocated type objects
+         * can go away, but this code requires that they stay alive
+         * until program exit.  That's why we're careful with
+         * refcounts here.  type_list gets a new reference to tp,
+         * while ownership of the reference type_list used to hold
+         * (if any) was transferred to tp->tp_next in the line above.
+         * tp is thus effectively immortal after this.
+         */
+        Py_INCREF(tp);
+        type_list = tp;
+#ifdef Py_TRACE_REFS
+        /* Also insert in the doubly-linked list of all objects,
+         * if not already there.
+         */
+        _Py_AddToAllObjects((PyObject *)tp, 0);
+#endif
+    }
+    tp->tp_allocs++;
+    if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
+        tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees;
+}
+
+void dec_count(PyTypeObject *tp)
+{
+    tp->tp_frees++;
+    if (unlist_types_without_objects &&
+        tp->tp_allocs == tp->tp_frees) {
+        /* unlink the type from type_list */
+        if (tp->tp_prev)
+            tp->tp_prev->tp_next = tp->tp_next;
+        else
+            type_list = tp->tp_next;
+        if (tp->tp_next)
+            tp->tp_next->tp_prev = tp->tp_prev;
+        tp->tp_next = tp->tp_prev = NULL;
+        Py_DECREF(tp);
+    }
+}
+
+#endif
+
+#ifdef Py_REF_DEBUG
+/* Log a fatal error; doesn't return. */
+void
+_Py_NegativeRefcount(const char *fname, int lineno, PyObject *op)
+{
+    char buf[300];
+
+    PyOS_snprintf(buf, sizeof(buf),
+                  "%s:%i object at %p has negative ref count "
+                  "%" PY_FORMAT_SIZE_T "d",
+                  fname, lineno, op, op->ob_refcnt);
+    Py_FatalError(buf);
+}
+
+#endif /* Py_REF_DEBUG */
+
+void
+Py_IncRef(PyObject *o)
+{
+    Py_XINCREF(o);
+}
+
+void
+Py_DecRef(PyObject *o)
+{
+    Py_XDECREF(o);
+}
+
+PyObject *
+PyObject_Init(PyObject *op, PyTypeObject *tp)
+{
+    if (op == NULL)
+        return PyErr_NoMemory();
+    /* Any changes should be reflected in PyObject_INIT (objimpl.h) */
+    Py_TYPE(op) = tp;
+    _Py_NewReference(op);
+    return op;
+}
+
+PyVarObject *
+PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
+{
+    if (op == NULL)
+        return (PyVarObject *) PyErr_NoMemory();
+    /* Any changes should be reflected in PyObject_INIT_VAR */
+    op->ob_size = size;
+    Py_TYPE(op) = tp;
+    _Py_NewReference((PyObject *)op);
+    return op;
+}
+
+PyObject *
+_PyObject_New(PyTypeObject *tp)
+{
+    PyObject *op;
+    op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
+    if (op == NULL)
+        return PyErr_NoMemory();
+    return PyObject_INIT(op, tp);
+}
+
+PyVarObject *
+_PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
+{
+    PyVarObject *op;
+    const size_t size = _PyObject_VAR_SIZE(tp, nitems);
+    op = (PyVarObject *) PyObject_MALLOC(size);
+    if (op == NULL)
+        return (PyVarObject *)PyErr_NoMemory();
+    return PyObject_INIT_VAR(op, tp, nitems);
+}
+
+/* for binary compatibility with 2.2 */
+#undef _PyObject_Del
+void
+_PyObject_Del(PyObject *op)
+{
+    PyObject_FREE(op);
+}
+
+/* Implementation of PyObject_Print with recursion checking */
+static int
+internal_print(PyObject *op, FILE *fp, int flags, int nesting)
+{
+    int ret = 0;
+    if (nesting > 10) {
+        PyErr_SetString(PyExc_RuntimeError, "print recursion");
+        return -1;
+    }
+    if (PyErr_CheckSignals())
+        return -1;
+#ifdef USE_STACKCHECK
+    if (PyOS_CheckStack()) {
+        PyErr_SetString(PyExc_MemoryError, "stack overflow");
+        return -1;
+    }
+#endif
+    clearerr(fp); /* Clear any previous error condition */
+    if (op == NULL) {
+        Py_BEGIN_ALLOW_THREADS
+        fprintf(fp, "<nil>");
+        Py_END_ALLOW_THREADS
+    }
+    else {
+        if (op->ob_refcnt <= 0)
+            /* XXX(twouters) cast refcount to long until %zd is
+               universally available */
+            Py_BEGIN_ALLOW_THREADS
+            fprintf(fp, "<refcnt %ld at %p>",
+                (long)op->ob_refcnt, op);
+            Py_END_ALLOW_THREADS
+        else if (Py_TYPE(op)->tp_print == NULL) {
+            PyObject *s;
+            if (flags & Py_PRINT_RAW)
+                s = PyObject_Str(op);
+            else
+                s = PyObject_Repr(op);
+            if (s == NULL)
+                ret = -1;
+            else {
+                ret = internal_print(s, fp, Py_PRINT_RAW,
+                                     nesting+1);
+            }
+            Py_XDECREF(s);
+        }
+        else
+            ret = (*Py_TYPE(op)->tp_print)(op, fp, flags);
+    }
+    if (ret == 0) {
+        if (ferror(fp)) {
+            PyErr_SetFromErrno(PyExc_IOError);
+            clearerr(fp);
+            ret = -1;
+        }
+    }
+    return ret;
+}
+
+int
+PyObject_Print(PyObject *op, FILE *fp, int flags)
+{
+    return internal_print(op, fp, flags, 0);
+}
+
+
+/* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
+void _PyObject_Dump(PyObject* op)
+{
+    if (op == NULL)
+        fprintf(stderr, "NULL\n");
+    else {
+#ifdef WITH_THREAD
+        PyGILState_STATE gil;
+#endif
+        fprintf(stderr, "object  : ");
+#ifdef WITH_THREAD
+        gil = PyGILState_Ensure();
+#endif
+        (void)PyObject_Print(op, stderr, 0);
+#ifdef WITH_THREAD
+        PyGILState_Release(gil);
+#endif
+        /* XXX(twouters) cast refcount to long until %zd is
+           universally available */
+        fprintf(stderr, "\n"
+            "type    : %s\n"
+            "refcount: %ld\n"
+            "address : %p\n",
+            Py_TYPE(op)==NULL ? "NULL" : Py_TYPE(op)->tp_name,
+            (long)op->ob_refcnt,
+            op);
+    }
+}
+
+PyObject *
+PyObject_Repr(PyObject *v)
+{
+    if (PyErr_CheckSignals())
+        return NULL;
+#ifdef USE_STACKCHECK
+    if (PyOS_CheckStack()) {
+        PyErr_SetString(PyExc_MemoryError, "stack overflow");
+        return NULL;
+    }
+#endif
+    if (v == NULL)
+        return PyString_FromString("<NULL>");
+    else if (Py_TYPE(v)->tp_repr == NULL)
+        return PyString_FromFormat("<%s object at %p>",
+                                   Py_TYPE(v)->tp_name, v);
+    else {
+        PyObject *res;
+        res = (*Py_TYPE(v)->tp_repr)(v);
+        if (res == NULL)
+            return NULL;
+#ifdef Py_USING_UNICODE
+        if (PyUnicode_Check(res)) {
+            PyObject* str;
+            str = PyUnicode_AsEncodedString(res, NULL, NULL);
+            Py_DECREF(res);
+            if (str)
+                res = str;
+            else
+                return NULL;
+        }
+#endif
+        if (!PyString_Check(res)) {
+            PyErr_Format(PyExc_TypeError,
+                         "__repr__ returned non-string (type %.200s)",
+                         Py_TYPE(res)->tp_name);
+            Py_DECREF(res);
+            return NULL;
+        }
+        return res;
+    }
+}
+
+PyObject *
+_PyObject_Str(PyObject *v)
+{
+    PyObject *res;
+    int type_ok;
+    if (v == NULL)
+        return PyString_FromString("<NULL>");
+    if (PyString_CheckExact(v)) {
+        Py_INCREF(v);
+        return v;
+    }
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_CheckExact(v)) {
+        Py_INCREF(v);
+        return v;
+    }
+#endif
+    if (Py_TYPE(v)->tp_str == NULL)
+        return PyObject_Repr(v);
+
+    /* It is possible for a type to have a tp_str representation that loops
+       infinitely. */
+    if (Py_EnterRecursiveCall(" while getting the str of an object"))
+        return NULL;
+    res = (*Py_TYPE(v)->tp_str)(v);
+    Py_LeaveRecursiveCall();
+    if (res == NULL)
+        return NULL;
+    type_ok = PyString_Check(res);
+#ifdef Py_USING_UNICODE
+    type_ok = type_ok || PyUnicode_Check(res);
+#endif
+    if (!type_ok) {
+        PyErr_Format(PyExc_TypeError,
+                     "__str__ returned non-string (type %.200s)",
+                     Py_TYPE(res)->tp_name);
+        Py_DECREF(res);
+        return NULL;
+    }
+    return res;
+}
+
+PyObject *
+PyObject_Str(PyObject *v)
+{
+    PyObject *res = _PyObject_Str(v);
+    if (res == NULL)
+        return NULL;
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(res)) {
+        PyObject* str;
+        str = PyUnicode_AsEncodedString(res, NULL, NULL);
+        Py_DECREF(res);
+        if (str)
+            res = str;
+        else
+            return NULL;
+    }
+#endif
+    assert(PyString_Check(res));
+    return res;
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyObject_Unicode(PyObject *v)
+{
+    PyObject *res;
+    PyObject *func;
+    PyObject *str;
+    int unicode_method_found = 0;
+    static PyObject *unicodestr = NULL;
+
+    if (v == NULL) {
+        res = PyString_FromString("<NULL>");
+        if (res == NULL)
+            return NULL;
+        str = PyUnicode_FromEncodedObject(res, NULL, "strict");
+        Py_DECREF(res);
+        return str;
+    } else if (PyUnicode_CheckExact(v)) {
+        Py_INCREF(v);
+        return v;
+    }
+
+    if (PyInstance_Check(v)) {
+        /* We're an instance of a classic class */
+        /* Try __unicode__ from the instance -- alas we have no type */
+        if (!unicodestr) {
+            unicodestr = PyString_InternFromString("__unicode__");
+            if (!unicodestr)
+                return NULL;
+        }
+        func = PyObject_GetAttr(v, unicodestr);
+        if (func != NULL) {
+            unicode_method_found = 1;
+            res = PyObject_CallFunctionObjArgs(func, NULL);
+            Py_DECREF(func);
+        }
+        else {
+            PyErr_Clear();
+        }
+    }
+    else {
+        /* Not a classic class instance, try __unicode__. */
+        func = _PyObject_LookupSpecial(v, "__unicode__", &unicodestr);
+        if (func != NULL) {
+            unicode_method_found = 1;
+            res = PyObject_CallFunctionObjArgs(func, NULL);
+            Py_DECREF(func);
+        }
+        else if (PyErr_Occurred())
+            return NULL;
+    }
+
+    /* Didn't find __unicode__ */
+    if (!unicode_method_found) {
+        if (PyUnicode_Check(v)) {
+            /* For a Unicode subtype that's didn't overwrite __unicode__,
+               return a true Unicode object with the same data. */
+            return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v),
+                                         PyUnicode_GET_SIZE(v));
+        }
+        if (PyString_CheckExact(v)) {
+            Py_INCREF(v);
+            res = v;
+        }
+        else {
+            if (Py_TYPE(v)->tp_str != NULL)
+                res = (*Py_TYPE(v)->tp_str)(v);
+            else
+                res = PyObject_Repr(v);
+        }
+    }
+
+    if (res == NULL)
+        return NULL;
+    if (!PyUnicode_Check(res)) {
+        str = PyUnicode_FromEncodedObject(res, NULL, "strict");
+        Py_DECREF(res);
+        res = str;
+    }
+    return res;
+}
+#endif
+
+
+/* Helper to warn about deprecated tp_compare return values.  Return:
+   -2 for an exception;
+   -1 if v <  w;
+    0 if v == w;
+    1 if v  > w.
+   (This function cannot return 2.)
+*/
+static int
+adjust_tp_compare(int c)
+{
+    if (PyErr_Occurred()) {
+        if (c != -1 && c != -2) {
+            PyObject *t, *v, *tb;
+            PyErr_Fetch(&t, &v, &tb);
+            if (PyErr_Warn(PyExc_RuntimeWarning,
+                           "tp_compare didn't return -1 or -2 "
+                           "for exception") < 0) {
+                Py_XDECREF(t);
+                Py_XDECREF(v);
+                Py_XDECREF(tb);
+            }
+            else
+                PyErr_Restore(t, v, tb);
+        }
+        return -2;
+    }
+    else if (c < -1 || c > 1) {
+        if (PyErr_Warn(PyExc_RuntimeWarning,
+                       "tp_compare didn't return -1, 0 or 1") < 0)
+            return -2;
+        else
+            return c < -1 ? -1 : 1;
+    }
+    else {
+        assert(c >= -1 && c <= 1);
+        return c;
+    }
+}
+
+
+/* Macro to get the tp_richcompare field of a type if defined */
+#define RICHCOMPARE(t) (PyType_HasFeature((t), Py_TPFLAGS_HAVE_RICHCOMPARE) \
+             ? (t)->tp_richcompare : NULL)
+
+/* Map rich comparison operators to their swapped version, e.g. LT --> GT */
+int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
+
+/* Try a genuine rich comparison, returning an object.  Return:
+   NULL for exception;
+   NotImplemented if this particular rich comparison is not implemented or
+     undefined;
+   some object not equal to NotImplemented if it is implemented
+     (this latter object may not be a Boolean).
+*/
+static PyObject *
+try_rich_compare(PyObject *v, PyObject *w, int op)
+{
+    richcmpfunc f;
+    PyObject *res;
+
+    if (v->ob_type != w->ob_type &&
+        PyType_IsSubtype(w->ob_type, v->ob_type) &&
+        (f = RICHCOMPARE(w->ob_type)) != NULL) {
+        res = (*f)(w, v, _Py_SwappedOp[op]);
+        if (res != Py_NotImplemented)
+            return res;
+        Py_DECREF(res);
+    }
+    if ((f = RICHCOMPARE(v->ob_type)) != NULL) {
+        res = (*f)(v, w, op);
+        if (res != Py_NotImplemented)
+            return res;
+        Py_DECREF(res);
+    }
+    if ((f = RICHCOMPARE(w->ob_type)) != NULL) {
+        return (*f)(w, v, _Py_SwappedOp[op]);
+    }
+    res = Py_NotImplemented;
+    Py_INCREF(res);
+    return res;
+}
+
+/* Try a genuine rich comparison, returning an int.  Return:
+   -1 for exception (including the case where try_rich_compare() returns an
+      object that's not a Boolean);
+    0 if the outcome is false;
+    1 if the outcome is true;
+    2 if this particular rich comparison is not implemented or undefined.
+*/
+static int
+try_rich_compare_bool(PyObject *v, PyObject *w, int op)
+{
+    PyObject *res;
+    int ok;
+
+    if (RICHCOMPARE(v->ob_type) == NULL && RICHCOMPARE(w->ob_type) == NULL)
+        return 2; /* Shortcut, avoid INCREF+DECREF */
+    res = try_rich_compare(v, w, op);
+    if (res == NULL)
+        return -1;
+    if (res == Py_NotImplemented) {
+        Py_DECREF(res);
+        return 2;
+    }
+    ok = PyObject_IsTrue(res);
+    Py_DECREF(res);
+    return ok;
+}
+
+/* Try rich comparisons to determine a 3-way comparison.  Return:
+   -2 for an exception;
+   -1 if v  < w;
+    0 if v == w;
+    1 if v  > w;
+    2 if this particular rich comparison is not implemented or undefined.
+*/
+static int
+try_rich_to_3way_compare(PyObject *v, PyObject *w)
+{
+    static struct { int op; int outcome; } tries[3] = {
+        /* Try this operator, and if it is true, use this outcome: */
+        {Py_EQ, 0},
+        {Py_LT, -1},
+        {Py_GT, 1},
+    };
+    int i;
+
+    if (RICHCOMPARE(v->ob_type) == NULL && RICHCOMPARE(w->ob_type) == NULL)
+        return 2; /* Shortcut */
+
+    for (i = 0; i < 3; i++) {
+        switch (try_rich_compare_bool(v, w, tries[i].op)) {
+        case -1:
+            return -2;
+        case 1:
+            return tries[i].outcome;
+        }
+    }
+
+    return 2;
+}
+
+/* Try a 3-way comparison, returning an int.  Return:
+   -2 for an exception;
+   -1 if v <  w;
+    0 if v == w;
+    1 if v  > w;
+    2 if this particular 3-way comparison is not implemented or undefined.
+*/
+static int
+try_3way_compare(PyObject *v, PyObject *w)
+{
+    int c;
+    cmpfunc f;
+
+    /* Comparisons involving instances are given to instance_compare,
+       which has the same return conventions as this function. */
+
+    f = v->ob_type->tp_compare;
+    if (PyInstance_Check(v))
+        return (*f)(v, w);
+    if (PyInstance_Check(w))
+        return (*w->ob_type->tp_compare)(v, w);
+
+    /* If both have the same (non-NULL) tp_compare, use it. */
+    if (f != NULL && f == w->ob_type->tp_compare) {
+        c = (*f)(v, w);
+        return adjust_tp_compare(c);
+    }
+
+    /* If either tp_compare is _PyObject_SlotCompare, that's safe. */
+    if (f == _PyObject_SlotCompare ||
+        w->ob_type->tp_compare == _PyObject_SlotCompare)
+        return _PyObject_SlotCompare(v, w);
+
+    /* If we're here, v and w,
+        a) are not instances;
+        b) have different types or a type without tp_compare; and
+        c) don't have a user-defined tp_compare.
+       tp_compare implementations in C assume that both arguments
+       have their type, so we give up if the coercion fails or if
+       it yields types which are still incompatible (which can
+       happen with a user-defined nb_coerce).
+    */
+    c = PyNumber_CoerceEx(&v, &w);
+    if (c < 0)
+        return -2;
+    if (c > 0)
+        return 2;
+    f = v->ob_type->tp_compare;
+    if (f != NULL && f == w->ob_type->tp_compare) {
+        c = (*f)(v, w);
+        Py_DECREF(v);
+        Py_DECREF(w);
+        return adjust_tp_compare(c);
+    }
+
+    /* No comparison defined */
+    Py_DECREF(v);
+    Py_DECREF(w);
+    return 2;
+}
+
+/* Final fallback 3-way comparison, returning an int.  Return:
+   -2 if an error occurred;
+   -1 if v <  w;
+    0 if v == w;
+    1 if v >  w.
+*/
+static int
+default_3way_compare(PyObject *v, PyObject *w)
+{
+    int c;
+    const char *vname, *wname;
+
+    if (v->ob_type == w->ob_type) {
+        /* When comparing these pointers, they must be cast to
+         * integer types (i.e. Py_uintptr_t, our spelling of C9X's
+         * uintptr_t).  ANSI specifies that pointer compares other
+         * than == and != to non-related structures are undefined.
+         */
+        Py_uintptr_t vv = (Py_uintptr_t)v;
+        Py_uintptr_t ww = (Py_uintptr_t)w;
+        return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
+    }
+
+    /* None is smaller than anything */
+    if (v == Py_None)
+        return -1;
+    if (w == Py_None)
+        return 1;
+
+    /* different type: compare type names; numbers are smaller */
+    if (PyNumber_Check(v))
+        vname = "";
+    else
+        vname = v->ob_type->tp_name;
+    if (PyNumber_Check(w))
+        wname = "";
+    else
+        wname = w->ob_type->tp_name;
+    c = strcmp(vname, wname);
+    if (c < 0)
+        return -1;
+    if (c > 0)
+        return 1;
+    /* Same type name, or (more likely) incomparable numeric types */
+    return ((Py_uintptr_t)(v->ob_type) < (
+        Py_uintptr_t)(w->ob_type)) ? -1 : 1;
+}
+
+/* Do a 3-way comparison, by hook or by crook.  Return:
+   -2 for an exception (but see below);
+   -1 if v <  w;
+    0 if v == w;
+    1 if v >  w;
+   BUT: if the object implements a tp_compare function, it returns
+   whatever this function returns (whether with an exception or not).
+*/
+static int
+do_cmp(PyObject *v, PyObject *w)
+{
+    int c;
+    cmpfunc f;
+
+    if (v->ob_type == w->ob_type
+        && (f = v->ob_type->tp_compare) != NULL) {
+        c = (*f)(v, w);
+        if (PyInstance_Check(v)) {
+            /* Instance tp_compare has a different signature.
+               But if it returns undefined we fall through. */
+            if (c != 2)
+                return c;
+            /* Else fall through to try_rich_to_3way_compare() */
+        }
+        else
+            return adjust_tp_compare(c);
+    }
+    /* We only get here if one of the following is true:
+       a) v and w have different types
+       b) v and w have the same type, which doesn't have tp_compare
+       c) v and w are instances, and either __cmp__ is not defined or
+          __cmp__ returns NotImplemented
+    */
+    c = try_rich_to_3way_compare(v, w);
+    if (c < 2)
+        return c;
+    c = try_3way_compare(v, w);
+    if (c < 2)
+        return c;
+    return default_3way_compare(v, w);
+}
+
+/* Compare v to w.  Return
+   -1 if v <  w or exception (PyErr_Occurred() true in latter case).
+    0 if v == w.
+    1 if v > w.
+   XXX The docs (C API manual) say the return value is undefined in case
+   XXX of error.
+*/
+int
+PyObject_Compare(PyObject *v, PyObject *w)
+{
+    int result;
+
+    if (v == NULL || w == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (v == w)
+        return 0;
+    if (Py_EnterRecursiveCall(" in cmp"))
+        return -1;
+    result = do_cmp(v, w);
+    Py_LeaveRecursiveCall();
+    return result < 0 ? -1 : result;
+}
+
+/* Return (new reference to) Py_True or Py_False. */
+static PyObject *
+convert_3way_to_object(int op, int c)
+{
+    PyObject *result;
+    switch (op) {
+    case Py_LT: c = c <  0; break;
+    case Py_LE: c = c <= 0; break;
+    case Py_EQ: c = c == 0; break;
+    case Py_NE: c = c != 0; break;
+    case Py_GT: c = c >  0; break;
+    case Py_GE: c = c >= 0; break;
+    }
+    result = c ? Py_True : Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
+/* We want a rich comparison but don't have one.  Try a 3-way cmp instead.
+   Return
+   NULL      if error
+   Py_True   if v op w
+   Py_False  if not (v op w)
+*/
+static PyObject *
+try_3way_to_rich_compare(PyObject *v, PyObject *w, int op)
+{
+    int c;
+
+    c = try_3way_compare(v, w);
+    if (c >= 2) {
+
+        /* Py3K warning if types are not equal and comparison isn't == or !=  */
+        if (Py_Py3kWarningFlag &&
+            v->ob_type != w->ob_type && op != Py_EQ && op != Py_NE &&
+            PyErr_WarnEx(PyExc_DeprecationWarning,
+                       "comparing unequal types not supported "
+                       "in 3.x", 1) < 0) {
+            return NULL;
+        }
+
+        c = default_3way_compare(v, w);
+    }
+    if (c <= -2)
+        return NULL;
+    return convert_3way_to_object(op, c);
+}
+
+/* Do rich comparison on v and w.  Return
+   NULL      if error
+   Else a new reference to an object other than Py_NotImplemented, usually(?):
+   Py_True   if v op w
+   Py_False  if not (v op w)
+*/
+static PyObject *
+do_richcmp(PyObject *v, PyObject *w, int op)
+{
+    PyObject *res;
+
+    res = try_rich_compare(v, w, op);
+    if (res != Py_NotImplemented)
+        return res;
+    Py_DECREF(res);
+
+    return try_3way_to_rich_compare(v, w, op);
+}
+
+/* Return:
+   NULL for exception;
+   some object not equal to NotImplemented if it is implemented
+     (this latter object may not be a Boolean).
+*/
+PyObject *
+PyObject_RichCompare(PyObject *v, PyObject *w, int op)
+{
+    PyObject *res;
+
+    assert(Py_LT <= op && op <= Py_GE);
+    if (Py_EnterRecursiveCall(" in cmp"))
+        return NULL;
+
+    /* If the types are equal, and not old-style instances, try to
+       get out cheap (don't bother with coercions etc.). */
+    if (v->ob_type == w->ob_type && !PyInstance_Check(v)) {
+        cmpfunc fcmp;
+        richcmpfunc frich = RICHCOMPARE(v->ob_type);
+        /* If the type has richcmp, try it first.  try_rich_compare
+           tries it two-sided, which is not needed since we've a
+           single type only. */
+        if (frich != NULL) {
+            res = (*frich)(v, w, op);
+            if (res != Py_NotImplemented)
+                goto Done;
+            Py_DECREF(res);
+        }
+        /* No richcmp, or this particular richmp not implemented.
+           Try 3-way cmp. */
+        fcmp = v->ob_type->tp_compare;
+        if (fcmp != NULL) {
+            int c = (*fcmp)(v, w);
+            c = adjust_tp_compare(c);
+            if (c == -2) {
+                res = NULL;
+                goto Done;
+            }
+            res = convert_3way_to_object(op, c);
+            goto Done;
+        }
+    }
+
+    /* Fast path not taken, or couldn't deliver a useful result. */
+    res = do_richcmp(v, w, op);
+Done:
+    Py_LeaveRecursiveCall();
+    return res;
+}
+
+/* Return -1 if error; 1 if v op w; 0 if not (v op w). */
+int
+PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
+{
+    PyObject *res;
+    int ok;
+
+    /* Quick result when objects are the same.
+       Guarantees that identity implies equality. */
+    if (v == w) {
+        if (op == Py_EQ)
+            return 1;
+        else if (op == Py_NE)
+            return 0;
+    }
+
+    res = PyObject_RichCompare(v, w, op);
+    if (res == NULL)
+        return -1;
+    if (PyBool_Check(res))
+        ok = (res == Py_True);
+    else
+        ok = PyObject_IsTrue(res);
+    Py_DECREF(res);
+    return ok;
+}
+
+/* Set of hash utility functions to help maintaining the invariant that
+    if a==b then hash(a)==hash(b)
+
+   All the utility functions (_Py_Hash*()) return "-1" to signify an error.
+*/
+
+long
+_Py_HashDouble(double v)
+{
+    double intpart, fractpart;
+    int expo;
+    long hipart;
+    long x;             /* the final hash value */
+    /* This is designed so that Python numbers of different types
+     * that compare equal hash to the same value; otherwise comparisons
+     * of mapping keys will turn out weird.
+     */
+
+    if (!Py_IS_FINITE(v)) {
+        if (Py_IS_INFINITY(v))
+            return v < 0 ? -271828 : 314159;
+        else
+            return 0;
+    }
+    fractpart = modf(v, &intpart);
+    if (fractpart == 0.0) {
+        /* This must return the same hash as an equal int or long. */
+        if (intpart > LONG_MAX/2 || -intpart > LONG_MAX/2) {
+            /* Convert to long and use its hash. */
+            PyObject *plong;                    /* converted to Python long */
+            plong = PyLong_FromDouble(v);
+            if (plong == NULL)
+                return -1;
+            x = PyObject_Hash(plong);
+            Py_DECREF(plong);
+            return x;
+        }
+        /* Fits in a C long == a Python int, so is its own hash. */
+        x = (long)intpart;
+        if (x == -1)
+            x = -2;
+        return x;
+    }
+    /* The fractional part is non-zero, so we don't have to worry about
+     * making this match the hash of some other type.
+     * Use frexp to get at the bits in the double.
+     * Since the VAX D double format has 56 mantissa bits, which is the
+     * most of any double format in use, each of these parts may have as
+     * many as (but no more than) 56 significant bits.
+     * So, assuming sizeof(long) >= 4, each part can be broken into two
+     * longs; frexp and multiplication are used to do that.
+     * Also, since the Cray double format has 15 exponent bits, which is
+     * the most of any double format in use, shifting the exponent field
+     * left by 15 won't overflow a long (again assuming sizeof(long) >= 4).
+     */
+    v = frexp(v, &expo);
+    v *= 2147483648.0;          /* 2**31 */
+    hipart = (long)v;           /* take the top 32 bits */
+    v = (v - (double)hipart) * 2147483648.0; /* get the next 32 bits */
+    x = hipart + (long)v + (expo << 15);
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+long
+_Py_HashPointer(void *p)
+{
+    long x;
+    size_t y = (size_t)p;
+    /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
+       excessive hash collisions for dicts and sets */
+    y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
+    x = (long)y;
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+long
+PyObject_HashNotImplemented(PyObject *self)
+{
+    PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
+                 self->ob_type->tp_name);
+    return -1;
+}
+
+_Py_HashSecret_t _Py_HashSecret;
+
+long
+PyObject_Hash(PyObject *v)
+{
+    PyTypeObject *tp = v->ob_type;
+    if (tp->tp_hash != NULL)
+        return (*tp->tp_hash)(v);
+    /* To keep to the general practice that inheriting
+     * solely from object in C code should work without
+     * an explicit call to PyType_Ready, we implicitly call
+     * PyType_Ready here and then check the tp_hash slot again
+     */
+    if (tp->tp_dict == NULL) {
+        if (PyType_Ready(tp) < 0)
+            return -1;
+        if (tp->tp_hash != NULL)
+            return (*tp->tp_hash)(v);
+    }
+    if (tp->tp_compare == NULL && RICHCOMPARE(tp) == NULL) {
+        return _Py_HashPointer(v); /* Use address as hash value */
+    }
+    /* If there's a cmp but no hash defined, the object can't be hashed */
+    return PyObject_HashNotImplemented(v);
+}
+
+PyObject *
+PyObject_GetAttrString(PyObject *v, const char *name)
+{
+    PyObject *w, *res;
+
+    if (Py_TYPE(v)->tp_getattr != NULL)
+        return (*Py_TYPE(v)->tp_getattr)(v, (char*)name);
+    w = PyString_InternFromString(name);
+    if (w == NULL)
+        return NULL;
+    res = PyObject_GetAttr(v, w);
+    Py_XDECREF(w);
+    return res;
+}
+
+int
+PyObject_HasAttrString(PyObject *v, const char *name)
+{
+    PyObject *res = PyObject_GetAttrString(v, name);
+    if (res != NULL) {
+        Py_DECREF(res);
+        return 1;
+    }
+    PyErr_Clear();
+    return 0;
+}
+
+int
+PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
+{
+    PyObject *s;
+    int res;
+
+    if (Py_TYPE(v)->tp_setattr != NULL)
+        return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w);
+    s = PyString_InternFromString(name);
+    if (s == NULL)
+        return -1;
+    res = PyObject_SetAttr(v, s, w);
+    Py_XDECREF(s);
+    return res;
+}
+
+PyObject *
+PyObject_GetAttr(PyObject *v, PyObject *name)
+{
+    PyTypeObject *tp = Py_TYPE(v);
+
+    if (!PyString_Check(name)) {
+#ifdef Py_USING_UNICODE
+        /* The Unicode to string conversion is done here because the
+           existing tp_getattro slots expect a string object as name
+           and we wouldn't want to break those. */
+        if (PyUnicode_Check(name)) {
+            name = _PyUnicode_AsDefaultEncodedString(name, NULL);
+            if (name == NULL)
+                return NULL;
+        }
+        else
+#endif
+        {
+            PyErr_Format(PyExc_TypeError,
+                         "attribute name must be string, not '%.200s'",
+                         Py_TYPE(name)->tp_name);
+            return NULL;
+        }
+    }
+    if (tp->tp_getattro != NULL)
+        return (*tp->tp_getattro)(v, name);
+    if (tp->tp_getattr != NULL)
+        return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
+    PyErr_Format(PyExc_AttributeError,
+                 "'%.50s' object has no attribute '%.400s'",
+                 tp->tp_name, PyString_AS_STRING(name));
+    return NULL;
+}
+
+int
+PyObject_HasAttr(PyObject *v, PyObject *name)
+{
+    PyObject *res = PyObject_GetAttr(v, name);
+    if (res != NULL) {
+        Py_DECREF(res);
+        return 1;
+    }
+    PyErr_Clear();
+    return 0;
+}
+
+int
+PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
+{
+    PyTypeObject *tp = Py_TYPE(v);
+    int err;
+
+    if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+        /* The Unicode to string conversion is done here because the
+           existing tp_setattro slots expect a string object as name
+           and we wouldn't want to break those. */
+        if (PyUnicode_Check(name)) {
+            name = PyUnicode_AsEncodedString(name, NULL, NULL);
+            if (name == NULL)
+                return -1;
+        }
+        else
+#endif
+        {
+            PyErr_Format(PyExc_TypeError,
+                         "attribute name must be string, not '%.200s'",
+                         Py_TYPE(name)->tp_name);
+            return -1;
+        }
+    }
+    else
+        Py_INCREF(name);
+
+    PyString_InternInPlace(&name);
+    if (tp->tp_setattro != NULL) {
+        err = (*tp->tp_setattro)(v, name, value);
+        Py_DECREF(name);
+        return err;
+    }
+    if (tp->tp_setattr != NULL) {
+        err = (*tp->tp_setattr)(v, PyString_AS_STRING(name), value);
+        Py_DECREF(name);
+        return err;
+    }
+    Py_DECREF(name);
+    if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
+        PyErr_Format(PyExc_TypeError,
+                     "'%.100s' object has no attributes "
+                     "(%s .%.100s)",
+                     tp->tp_name,
+                     value==NULL ? "del" : "assign to",
+                     PyString_AS_STRING(name));
+    else
+        PyErr_Format(PyExc_TypeError,
+                     "'%.100s' object has only read-only attributes "
+                     "(%s .%.100s)",
+                     tp->tp_name,
+                     value==NULL ? "del" : "assign to",
+                     PyString_AS_STRING(name));
+    return -1;
+}
+
+/* Helper to get a pointer to an object's __dict__ slot, if any */
+
+PyObject **
+_PyObject_GetDictPtr(PyObject *obj)
+{
+    Py_ssize_t dictoffset;
+    PyTypeObject *tp = Py_TYPE(obj);
+
+    if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+        return NULL;
+    dictoffset = tp->tp_dictoffset;
+    if (dictoffset == 0)
+        return NULL;
+    if (dictoffset < 0) {
+        Py_ssize_t tsize;
+        size_t size;
+
+        tsize = ((PyVarObject *)obj)->ob_size;
+        if (tsize < 0)
+            tsize = -tsize;
+        size = _PyObject_VAR_SIZE(tp, tsize);
+
+        dictoffset += (long)size;
+        assert(dictoffset > 0);
+        assert(dictoffset % SIZEOF_VOID_P == 0);
+    }
+    return (PyObject **) ((char *)obj + dictoffset);
+}
+
+PyObject *
+PyObject_SelfIter(PyObject *obj)
+{
+    Py_INCREF(obj);
+    return obj;
+}
+
+/* Helper used when the __next__ method is removed from a type:
+   tp_iternext is never NULL and can be safely called without checking
+   on every iteration.
+ */
+
+PyObject *
+_PyObject_NextNotImplemented(PyObject *self)
+{
+    PyErr_Format(PyExc_TypeError,
+                 "'%.200s' object is not iterable",
+                 Py_TYPE(self)->tp_name);
+    return NULL;
+}
+
+/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
+
+PyObject *
+_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
+{
+    PyTypeObject *tp = Py_TYPE(obj);
+    PyObject *descr = NULL;
+    PyObject *res = NULL;
+    descrgetfunc f;
+    Py_ssize_t dictoffset;
+    PyObject **dictptr;
+
+    if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+        /* The Unicode to string conversion is done here because the
+           existing tp_setattro slots expect a string object as name
+           and we wouldn't want to break those. */
+        if (PyUnicode_Check(name)) {
+            name = PyUnicode_AsEncodedString(name, NULL, NULL);
+            if (name == NULL)
+                return NULL;
+        }
+        else
+#endif
+        {
+            PyErr_Format(PyExc_TypeError,
+                         "attribute name must be string, not '%.200s'",
+                         Py_TYPE(name)->tp_name);
+            return NULL;
+        }
+    }
+    else
+        Py_INCREF(name);
+
+    if (tp->tp_dict == NULL) {
+        if (PyType_Ready(tp) < 0)
+            goto done;
+    }
+
+#if 0 /* XXX this is not quite _PyType_Lookup anymore */
+    /* Inline _PyType_Lookup */
+    {
+        Py_ssize_t i, n;
+        PyObject *mro, *base, *dict;
+
+        /* Look in tp_dict of types in MRO */
+        mro = tp->tp_mro;
+        assert(mro != NULL);
+        assert(PyTuple_Check(mro));
+        n = PyTuple_GET_SIZE(mro);
+        for (i = 0; i < n; i++) {
+            base = PyTuple_GET_ITEM(mro, i);
+            if (PyClass_Check(base))
+                dict = ((PyClassObject *)base)->cl_dict;
+            else {
+                assert(PyType_Check(base));
+                dict = ((PyTypeObject *)base)->tp_dict;
+            }
+            assert(dict && PyDict_Check(dict));
+            descr = PyDict_GetItem(dict, name);
+            if (descr != NULL)
+                break;
+        }
+    }
+#else
+    descr = _PyType_Lookup(tp, name);
+#endif
+
+    Py_XINCREF(descr);
+
+    f = NULL;
+    if (descr != NULL &&
+        PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
+        f = descr->ob_type->tp_descr_get;
+        if (f != NULL && PyDescr_IsData(descr)) {
+            res = f(descr, obj, (PyObject *)obj->ob_type);
+            Py_DECREF(descr);
+            goto done;
+        }
+    }
+
+    if (dict == NULL) {
+        /* Inline _PyObject_GetDictPtr */
+        dictoffset = tp->tp_dictoffset;
+        if (dictoffset != 0) {
+            if (dictoffset < 0) {
+                Py_ssize_t tsize;
+                size_t size;
+
+                tsize = ((PyVarObject *)obj)->ob_size;
+                if (tsize < 0)
+                    tsize = -tsize;
+                size = _PyObject_VAR_SIZE(tp, tsize);
+
+                dictoffset += (long)size;
+                assert(dictoffset > 0);
+                assert(dictoffset % SIZEOF_VOID_P == 0);
+            }
+            dictptr = (PyObject **) ((char *)obj + dictoffset);
+            dict = *dictptr;
+        }
+    }
+    if (dict != NULL) {
+        Py_INCREF(dict);
+        res = PyDict_GetItem(dict, name);
+        if (res != NULL) {
+            Py_INCREF(res);
+            Py_XDECREF(descr);
+            Py_DECREF(dict);
+            goto done;
+        }
+        Py_DECREF(dict);
+    }
+
+    if (f != NULL) {
+        res = f(descr, obj, (PyObject *)Py_TYPE(obj));
+        Py_DECREF(descr);
+        goto done;
+    }
+
+    if (descr != NULL) {
+        res = descr;
+        /* descr was already increfed above */
+        goto done;
+    }
+
+    PyErr_Format(PyExc_AttributeError,
+                 "'%.50s' object has no attribute '%.400s'",
+                 tp->tp_name, PyString_AS_STRING(name));
+  done:
+    Py_DECREF(name);
+    return res;
+}
+
+PyObject *
+PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
+{
+    return _PyObject_GenericGetAttrWithDict(obj, name, NULL);
+}
+
+int
+_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
+                                 PyObject *value, PyObject *dict)
+{
+    PyTypeObject *tp = Py_TYPE(obj);
+    PyObject *descr;
+    descrsetfunc f;
+    PyObject **dictptr;
+    int res = -1;
+
+    if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+        /* The Unicode to string conversion is done here because the
+           existing tp_setattro slots expect a string object as name
+           and we wouldn't want to break those. */
+        if (PyUnicode_Check(name)) {
+            name = PyUnicode_AsEncodedString(name, NULL, NULL);
+            if (name == NULL)
+                return -1;
+        }
+        else
+#endif
+        {
+            PyErr_Format(PyExc_TypeError,
+                         "attribute name must be string, not '%.200s'",
+                         Py_TYPE(name)->tp_name);
+            return -1;
+        }
+    }
+    else
+        Py_INCREF(name);
+
+    if (tp->tp_dict == NULL) {
+        if (PyType_Ready(tp) < 0)
+            goto done;
+    }
+
+    descr = _PyType_Lookup(tp, name);
+    f = NULL;
+    if (descr != NULL &&
+        PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
+        f = descr->ob_type->tp_descr_set;
+        if (f != NULL && PyDescr_IsData(descr)) {
+            res = f(descr, obj, value);
+            goto done;
+        }
+    }
+
+    if (dict == NULL) {
+        dictptr = _PyObject_GetDictPtr(obj);
+        if (dictptr != NULL) {
+            dict = *dictptr;
+            if (dict == NULL && value != NULL) {
+                dict = PyDict_New();
+                if (dict == NULL)
+                    goto done;
+                *dictptr = dict;
+            }
+        }
+    }
+    if (dict != NULL) {
+        Py_INCREF(dict);
+        if (value == NULL)
+            res = PyDict_DelItem(dict, name);
+        else
+            res = PyDict_SetItem(dict, name, value);
+        if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+            PyErr_SetObject(PyExc_AttributeError, name);
+        Py_DECREF(dict);
+        goto done;
+    }
+
+    if (f != NULL) {
+        res = f(descr, obj, value);
+        goto done;
+    }
+
+    if (descr == NULL) {
+        PyErr_Format(PyExc_AttributeError,
+                     "'%.100s' object has no attribute '%.200s'",
+                     tp->tp_name, PyString_AS_STRING(name));
+        goto done;
+    }
+
+    PyErr_Format(PyExc_AttributeError,
+                 "'%.50s' object attribute '%.400s' is read-only",
+                 tp->tp_name, PyString_AS_STRING(name));
+  done:
+    Py_DECREF(name);
+    return res;
+}
+
+int
+PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
+{
+    return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL);
+}
+
+
+/* Test a value used as condition, e.g., in a for or if statement.
+   Return -1 if an error occurred */
+
+int
+PyObject_IsTrue(PyObject *v)
+{
+    Py_ssize_t res;
+    if (v == Py_True)
+        return 1;
+    if (v == Py_False)
+        return 0;
+    if (v == Py_None)
+        return 0;
+    else if (v->ob_type->tp_as_number != NULL &&
+             v->ob_type->tp_as_number->nb_nonzero != NULL)
+        res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
+    else if (v->ob_type->tp_as_mapping != NULL &&
+             v->ob_type->tp_as_mapping->mp_length != NULL)
+        res = (*v->ob_type->tp_as_mapping->mp_length)(v);
+    else if (v->ob_type->tp_as_sequence != NULL &&
+             v->ob_type->tp_as_sequence->sq_length != NULL)
+        res = (*v->ob_type->tp_as_sequence->sq_length)(v);
+    else
+        return 1;
+    /* if it is negative, it should be either -1 or -2 */
+    return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int);
+}
+
+/* equivalent of 'not v'
+   Return -1 if an error occurred */
+
+int
+PyObject_Not(PyObject *v)
+{
+    int res;
+    res = PyObject_IsTrue(v);
+    if (res < 0)
+        return res;
+    return res == 0;
+}
+
+/* Coerce two numeric types to the "larger" one.
+   Increment the reference count on each argument.
+   Return value:
+   -1 if an error occurred;
+   0 if the coercion succeeded (and then the reference counts are increased);
+   1 if no coercion is possible (and no error is raised).
+*/
+int
+PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
+{
+    register PyObject *v = *pv;
+    register PyObject *w = *pw;
+    int res;
+
+    /* Shortcut only for old-style types */
+    if (v->ob_type == w->ob_type &&
+        !PyType_HasFeature(v->ob_type, Py_TPFLAGS_CHECKTYPES))
+    {
+        Py_INCREF(v);
+        Py_INCREF(w);
+        return 0;
+    }
+    if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) {
+        res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
+        if (res <= 0)
+            return res;
+    }
+    if (w->ob_type->tp_as_number && w->ob_type->tp_as_number->nb_coerce) {
+        res = (*w->ob_type->tp_as_number->nb_coerce)(pw, pv);
+        if (res <= 0)
+            return res;
+    }
+    return 1;
+}
+
+/* Coerce two numeric types to the "larger" one.
+   Increment the reference count on each argument.
+   Return -1 and raise an exception if no coercion is possible
+   (and then no reference count is incremented).
+*/
+int
+PyNumber_Coerce(PyObject **pv, PyObject **pw)
+{
+    int err = PyNumber_CoerceEx(pv, pw);
+    if (err <= 0)
+        return err;
+    PyErr_SetString(PyExc_TypeError, "number coercion failed");
+    return -1;
+}
+
+
+/* Test whether an object can be called */
+
+int
+PyCallable_Check(PyObject *x)
+{
+    if (x == NULL)
+        return 0;
+    if (PyInstance_Check(x)) {
+        PyObject *call = PyObject_GetAttrString(x, "__call__");
+        if (call == NULL) {
+            PyErr_Clear();
+            return 0;
+        }
+        /* Could test recursively but don't, for fear of endless
+           recursion if some joker sets self.__call__ = self */
+        Py_DECREF(call);
+        return 1;
+    }
+    else {
+        return x->ob_type->tp_call != NULL;
+    }
+}
+
+/* ------------------------- PyObject_Dir() helpers ------------------------- */
+
+/* Helper for PyObject_Dir.
+   Merge the __dict__ of aclass into dict, and recursively also all
+   the __dict__s of aclass's base classes.  The order of merging isn't
+   defined, as it's expected that only the final set of dict keys is
+   interesting.
+   Return 0 on success, -1 on error.
+*/
+
+static int
+merge_class_dict(PyObject* dict, PyObject* aclass)
+{
+    PyObject *classdict;
+    PyObject *bases;
+
+    assert(PyDict_Check(dict));
+    assert(aclass);
+
+    /* Merge in the type's dict (if any). */
+    classdict = PyObject_GetAttrString(aclass, "__dict__");
+    if (classdict == NULL)
+        PyErr_Clear();
+    else {
+        int status = PyDict_Update(dict, classdict);
+        Py_DECREF(classdict);
+        if (status < 0)
+            return -1;
+    }
+
+    /* Recursively merge in the base types' (if any) dicts. */
+    bases = PyObject_GetAttrString(aclass, "__bases__");
+    if (bases == NULL)
+        PyErr_Clear();
+    else {
+        /* We have no guarantee that bases is a real tuple */
+        Py_ssize_t i, n;
+        n = PySequence_Size(bases); /* This better be right */
+        if (n < 0)
+            PyErr_Clear();
+        else {
+            for (i = 0; i < n; i++) {
+                int status;
+                PyObject *base = PySequence_GetItem(bases, i);
+                if (base == NULL) {
+                    Py_DECREF(bases);
+                    return -1;
+                }
+                status = merge_class_dict(dict, base);
+                Py_DECREF(base);
+                if (status < 0) {
+                    Py_DECREF(bases);
+                    return -1;
+                }
+            }
+        }
+        Py_DECREF(bases);
+    }
+    return 0;
+}
+
+/* Helper for PyObject_Dir.
+   If obj has an attr named attrname that's a list, merge its string
+   elements into keys of dict.
+   Return 0 on success, -1 on error.  Errors due to not finding the attr,
+   or the attr not being a list, are suppressed.
+*/
+
+static int
+merge_list_attr(PyObject* dict, PyObject* obj, const char *attrname)
+{
+    PyObject *list;
+    int result = 0;
+
+    assert(PyDict_Check(dict));
+    assert(obj);
+    assert(attrname);
+
+    list = PyObject_GetAttrString(obj, attrname);
+    if (list == NULL)
+        PyErr_Clear();
+
+    else if (PyList_Check(list)) {
+        int i;
+        for (i = 0; i < PyList_GET_SIZE(list); ++i) {
+            PyObject *item = PyList_GET_ITEM(list, i);
+            if (PyString_Check(item)) {
+                result = PyDict_SetItem(dict, item, Py_None);
+                if (result < 0)
+                    break;
+            }
+        }
+        if (Py_Py3kWarningFlag &&
+            (strcmp(attrname, "__members__") == 0 ||
+             strcmp(attrname, "__methods__") == 0)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                           "__members__ and __methods__ not "
+                           "supported in 3.x", 1) < 0) {
+                Py_XDECREF(list);
+                return -1;
+            }
+        }
+    }
+
+    Py_XDECREF(list);
+    return result;
+}
+
+/* Helper for PyObject_Dir without arguments: returns the local scope. */
+static PyObject *
+_dir_locals(void)
+{
+    PyObject *names;
+    PyObject *locals = PyEval_GetLocals();
+
+    if (locals == NULL) {
+        PyErr_SetString(PyExc_SystemError, "frame does not exist");
+        return NULL;
+    }
+
+    names = PyMapping_Keys(locals);
+    if (!names)
+        return NULL;
+    if (!PyList_Check(names)) {
+        PyErr_Format(PyExc_TypeError,
+            "dir(): expected keys() of locals to be a list, "
+            "not '%.200s'", Py_TYPE(names)->tp_name);
+        Py_DECREF(names);
+        return NULL;
+    }
+    /* the locals don't need to be DECREF'd */
+    return names;
+}
+
+/* Helper for PyObject_Dir of type objects: returns __dict__ and __bases__.
+   We deliberately don't suck up its __class__, as methods belonging to the
+   metaclass would probably be more confusing than helpful.
+*/
+static PyObject *
+_specialized_dir_type(PyObject *obj)
+{
+    PyObject *result = NULL;
+    PyObject *dict = PyDict_New();
+
+    if (dict != NULL && merge_class_dict(dict, obj) == 0)
+        result = PyDict_Keys(dict);
+
+    Py_XDECREF(dict);
+    return result;
+}
+
+/* Helper for PyObject_Dir of module objects: returns the module's __dict__. */
+static PyObject *
+_specialized_dir_module(PyObject *obj)
+{
+    PyObject *result = NULL;
+    PyObject *dict = PyObject_GetAttrString(obj, "__dict__");
+
+    if (dict != NULL) {
+        if (PyDict_Check(dict))
+            result = PyDict_Keys(dict);
+        else {
+            char *name = PyModule_GetName(obj);
+            if (name)
+                PyErr_Format(PyExc_TypeError,
+                             "%.200s.__dict__ is not a dictionary",
+                             name);
+        }
+    }
+
+    Py_XDECREF(dict);
+    return result;
+}
+
+/* Helper for PyObject_Dir of generic objects: returns __dict__, __class__,
+   and recursively up the __class__.__bases__ chain.
+*/
+static PyObject *
+_generic_dir(PyObject *obj)
+{
+    PyObject *result = NULL;
+    PyObject *dict = NULL;
+    PyObject *itsclass = NULL;
+
+    /* Get __dict__ (which may or may not be a real dict...) */
+    dict = PyObject_GetAttrString(obj, "__dict__");
+    if (dict == NULL) {
+        PyErr_Clear();
+        dict = PyDict_New();
+    }
+    else if (!PyDict_Check(dict)) {
+        Py_DECREF(dict);
+        dict = PyDict_New();
+    }
+    else {
+        /* Copy __dict__ to avoid mutating it. */
+        PyObject *temp = PyDict_Copy(dict);
+        Py_DECREF(dict);
+        dict = temp;
+    }
+
+    if (dict == NULL)
+        goto error;
+
+    /* Merge in __members__ and __methods__ (if any).
+     * This is removed in Python 3000. */
+    if (merge_list_attr(dict, obj, "__members__") < 0)
+        goto error;
+    if (merge_list_attr(dict, obj, "__methods__") < 0)
+        goto error;
+
+    /* Merge in attrs reachable from its class. */
+    itsclass = PyObject_GetAttrString(obj, "__class__");
+    if (itsclass == NULL)
+        /* XXX(tomer): Perhaps fall back to obj->ob_type if no
+                       __class__ exists? */
+        PyErr_Clear();
+    else {
+        if (merge_class_dict(dict, itsclass) != 0)
+            goto error;
+    }
+
+    result = PyDict_Keys(dict);
+    /* fall through */
+error:
+    Py_XDECREF(itsclass);
+    Py_XDECREF(dict);
+    return result;
+}
+
+/* Helper for PyObject_Dir: object introspection.
+   This calls one of the above specialized versions if no __dir__ method
+   exists. */
+static PyObject *
+_dir_object(PyObject *obj)
+{
+    PyObject *result = NULL;
+    static PyObject *dir_str = NULL;
+    PyObject *dirfunc;
+
+    assert(obj);
+    if (PyInstance_Check(obj)) {
+        dirfunc = PyObject_GetAttrString(obj, "__dir__");
+        if (dirfunc == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                PyErr_Clear();
+            else
+                return NULL;
+        }
+    }
+    else {
+        dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str);
+        if (PyErr_Occurred())
+            return NULL;
+    }
+    if (dirfunc == NULL) {
+        /* use default implementation */
+        if (PyModule_Check(obj))
+            result = _specialized_dir_module(obj);
+        else if (PyType_Check(obj) || PyClass_Check(obj))
+            result = _specialized_dir_type(obj);
+        else
+            result = _generic_dir(obj);
+    }
+    else {
+        /* use __dir__ */
+        result = PyObject_CallFunctionObjArgs(dirfunc, NULL);
+        Py_DECREF(dirfunc);
+        if (result == NULL)
+            return NULL;
+
+        /* result must be a list */
+        /* XXX(gbrandl): could also check if all items are strings */
+        if (!PyList_Check(result)) {
+            PyErr_Format(PyExc_TypeError,
+                         "__dir__() must return a list, not %.200s",
+                         Py_TYPE(result)->tp_name);
+            Py_DECREF(result);
+            result = NULL;
+        }
+    }
+
+    return result;
+}
+
+/* Implementation of dir() -- if obj is NULL, returns the names in the current
+   (local) scope.  Otherwise, performs introspection of the object: returns a
+   sorted list of attribute names (supposedly) accessible from the object
+*/
+PyObject *
+PyObject_Dir(PyObject *obj)
+{
+    PyObject * result;
+
+    if (obj == NULL)
+        /* no object -- introspect the locals */
+        result = _dir_locals();
+    else
+        /* object -- introspect the object */
+        result = _dir_object(obj);
+
+    assert(result == NULL || PyList_Check(result));
+
+    if (result != NULL && PyList_Sort(result) != 0) {
+        /* sorting the list failed */
+        Py_DECREF(result);
+        result = NULL;
+    }
+
+    return result;
+}
+
+/*
+NoObject is usable as a non-NULL undefined value, used by the macro None.
+There is (and should be!) no way to create other objects of this type,
+so there is exactly one (which is indestructible, by the way).
+(XXX This type and the type of NotImplemented below should be unified.)
+*/
+
+/* ARGSUSED */
+static PyObject *
+none_repr(PyObject *op)
+{
+    return PyString_FromString("None");
+}
+
+/* ARGUSED */
+static void
+none_dealloc(PyObject* ignore)
+{
+    /* This should never get called, but we also don't want to SEGV if
+     * we accidentally decref None out of existence.
+     */
+    Py_FatalError("deallocating None");
+}
+
+
+static PyTypeObject PyNone_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "NoneType",
+    0,
+    0,
+    none_dealloc,       /*tp_dealloc*/ /*never called*/
+    0,                  /*tp_print*/
+    0,                  /*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    none_repr,          /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    (hashfunc)_Py_HashPointer, /*tp_hash */
+};
+
+PyObject _Py_NoneStruct = {
+  _PyObject_EXTRA_INIT
+  1, &PyNone_Type
+};
+
+/* NotImplemented is an object that can be used to signal that an
+   operation is not implemented for the given type combination. */
+
+static PyObject *
+NotImplemented_repr(PyObject *op)
+{
+    return PyString_FromString("NotImplemented");
+}
+
+static PyTypeObject PyNotImplemented_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "NotImplementedType",
+    0,
+    0,
+    none_dealloc,       /*tp_dealloc*/ /*never called*/
+    0,                  /*tp_print*/
+    0,                  /*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_compare*/
+    NotImplemented_repr, /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash */
+};
+
+PyObject _Py_NotImplementedStruct = {
+    _PyObject_EXTRA_INIT
+    1, &PyNotImplemented_Type
+};
+
+void
+_Py_ReadyTypes(void)
+{
+    if (PyType_Ready(&PyType_Type) < 0)
+        Py_FatalError("Can't initialize type type");
+
+    if (PyType_Ready(&_PyWeakref_RefType) < 0)
+        Py_FatalError("Can't initialize weakref type");
+
+    if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0)
+        Py_FatalError("Can't initialize callable weakref proxy type");
+
+    if (PyType_Ready(&_PyWeakref_ProxyType) < 0)
+        Py_FatalError("Can't initialize weakref proxy type");
+
+    if (PyType_Ready(&PyBool_Type) < 0)
+        Py_FatalError("Can't initialize bool type");
+
+    if (PyType_Ready(&PyString_Type) < 0)
+        Py_FatalError("Can't initialize str type");
+
+    if (PyType_Ready(&PyByteArray_Type) < 0)
+        Py_FatalError("Can't initialize bytearray type");
+
+    if (PyType_Ready(&PyList_Type) < 0)
+        Py_FatalError("Can't initialize list type");
+
+    if (PyType_Ready(&PyNone_Type) < 0)
+        Py_FatalError("Can't initialize None type");
+
+    if (PyType_Ready(&PyNotImplemented_Type) < 0)
+        Py_FatalError("Can't initialize NotImplemented type");
+
+    if (PyType_Ready(&PyTraceBack_Type) < 0)
+        Py_FatalError("Can't initialize traceback type");
+
+    if (PyType_Ready(&PySuper_Type) < 0)
+        Py_FatalError("Can't initialize super type");
+
+    if (PyType_Ready(&PyBaseObject_Type) < 0)
+        Py_FatalError("Can't initialize object type");
+
+    if (PyType_Ready(&PyRange_Type) < 0)
+        Py_FatalError("Can't initialize xrange type");
+
+    if (PyType_Ready(&PyDict_Type) < 0)
+        Py_FatalError("Can't initialize dict type");
+
+    if (PyType_Ready(&PySet_Type) < 0)
+        Py_FatalError("Can't initialize set type");
+
+#ifdef Py_USING_UNICODE
+    if (PyType_Ready(&PyUnicode_Type) < 0)
+        Py_FatalError("Can't initialize unicode type");
+#endif
+
+    if (PyType_Ready(&PySlice_Type) < 0)
+        Py_FatalError("Can't initialize slice type");
+
+    if (PyType_Ready(&PyStaticMethod_Type) < 0)
+        Py_FatalError("Can't initialize static method type");
+
+#ifndef WITHOUT_COMPLEX
+    if (PyType_Ready(&PyComplex_Type) < 0)
+        Py_FatalError("Can't initialize complex type");
+#endif
+
+    if (PyType_Ready(&PyFloat_Type) < 0)
+        Py_FatalError("Can't initialize float type");
+
+    if (PyType_Ready(&PyBuffer_Type) < 0)
+        Py_FatalError("Can't initialize buffer type");
+
+    if (PyType_Ready(&PyLong_Type) < 0)
+        Py_FatalError("Can't initialize long type");
+
+    if (PyType_Ready(&PyInt_Type) < 0)
+        Py_FatalError("Can't initialize int type");
+
+    if (PyType_Ready(&PyFrozenSet_Type) < 0)
+        Py_FatalError("Can't initialize frozenset type");
+
+    if (PyType_Ready(&PyProperty_Type) < 0)
+        Py_FatalError("Can't initialize property type");
+
+    if (PyType_Ready(&PyMemoryView_Type) < 0)
+        Py_FatalError("Can't initialize memoryview type");
+
+    if (PyType_Ready(&PyTuple_Type) < 0)
+        Py_FatalError("Can't initialize tuple type");
+
+    if (PyType_Ready(&PyEnum_Type) < 0)
+        Py_FatalError("Can't initialize enumerate type");
+
+    if (PyType_Ready(&PyReversed_Type) < 0)
+        Py_FatalError("Can't initialize reversed type");
+
+    if (PyType_Ready(&PyCode_Type) < 0)
+        Py_FatalError("Can't initialize code type");
+
+    if (PyType_Ready(&PyFrame_Type) < 0)
+        Py_FatalError("Can't initialize frame type");
+
+    if (PyType_Ready(&PyCFunction_Type) < 0)
+        Py_FatalError("Can't initialize builtin function type");
+
+    if (PyType_Ready(&PyMethod_Type) < 0)
+        Py_FatalError("Can't initialize method type");
+
+    if (PyType_Ready(&PyFunction_Type) < 0)
+        Py_FatalError("Can't initialize function type");
+
+    if (PyType_Ready(&PyClass_Type) < 0)
+        Py_FatalError("Can't initialize class type");
+
+    if (PyType_Ready(&PyDictProxy_Type) < 0)
+        Py_FatalError("Can't initialize dict proxy type");
+
+    if (PyType_Ready(&PyGen_Type) < 0)
+        Py_FatalError("Can't initialize generator type");
+
+    if (PyType_Ready(&PyGetSetDescr_Type) < 0)
+        Py_FatalError("Can't initialize get-set descriptor type");
+
+    if (PyType_Ready(&PyWrapperDescr_Type) < 0)
+        Py_FatalError("Can't initialize wrapper type");
+
+    if (PyType_Ready(&PyInstance_Type) < 0)
+        Py_FatalError("Can't initialize instance type");
+
+    if (PyType_Ready(&PyEllipsis_Type) < 0)
+        Py_FatalError("Can't initialize ellipsis type");
+
+    if (PyType_Ready(&PyMemberDescr_Type) < 0)
+        Py_FatalError("Can't initialize member descriptor type");
+
+    if (PyType_Ready(&PyFile_Type) < 0)
+        Py_FatalError("Can't initialize file type");
+
+    if (PyType_Ready(&PyCapsule_Type) < 0)
+        Py_FatalError("Can't initialize capsule type");
+
+    if (PyType_Ready(&PyCell_Type) < 0)
+        Py_FatalError("Can't initialize cell type");
+
+    if (PyType_Ready(&PyCallIter_Type) < 0)
+        Py_FatalError("Can't initialize call iter type");
+
+    if (PyType_Ready(&PySeqIter_Type) < 0)
+        Py_FatalError("Can't initialize sequence iterator type");
+}
+
+
+#ifdef Py_TRACE_REFS
+
+void
+_Py_NewReference(PyObject *op)
+{
+    _Py_INC_REFTOTAL;
+    op->ob_refcnt = 1;
+    _Py_AddToAllObjects(op, 1);
+    _Py_INC_TPALLOCS(op);
+}
+
+void
+_Py_ForgetReference(register PyObject *op)
+{
+#ifdef SLOW_UNREF_CHECK
+    register PyObject *p;
+#endif
+    if (op->ob_refcnt < 0)
+        Py_FatalError("UNREF negative refcnt");
+    if (op == &refchain ||
+        op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
+        Py_FatalError("UNREF invalid object");
+#ifdef SLOW_UNREF_CHECK
+    for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
+        if (p == op)
+            break;
+    }
+    if (p == &refchain) /* Not found */
+        Py_FatalError("UNREF unknown object");
+#endif
+    op->_ob_next->_ob_prev = op->_ob_prev;
+    op->_ob_prev->_ob_next = op->_ob_next;
+    op->_ob_next = op->_ob_prev = NULL;
+    _Py_INC_TPFREES(op);
+}
+
+void
+_Py_Dealloc(PyObject *op)
+{
+    destructor dealloc = Py_TYPE(op)->tp_dealloc;
+    _Py_ForgetReference(op);
+    (*dealloc)(op);
+}
+
+/* Print all live objects.  Because PyObject_Print is called, the
+ * interpreter must be in a healthy state.
+ */
+void
+_Py_PrintReferences(FILE *fp)
+{
+    PyObject *op;
+    fprintf(fp, "Remaining objects:\n");
+    for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
+        fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", op, op->ob_refcnt);
+        if (PyObject_Print(op, fp, 0) != 0)
+            PyErr_Clear();
+        putc('\n', fp);
+    }
+}
+
+/* Print the addresses of all live objects.  Unlike _Py_PrintReferences, this
+ * doesn't make any calls to the Python C API, so is always safe to call.
+ */
+void
+_Py_PrintReferenceAddresses(FILE *fp)
+{
+    PyObject *op;
+    fprintf(fp, "Remaining object addresses:\n");
+    for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
+        fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", op,
+            op->ob_refcnt, Py_TYPE(op)->tp_name);
+}
+
+PyObject *
+_Py_GetObjects(PyObject *self, PyObject *args)
+{
+    int i, n;
+    PyObject *t = NULL;
+    PyObject *res, *op;
+
+    if (!PyArg_ParseTuple(args, "i|O", &n, &t))
+        return NULL;
+    op = refchain._ob_next;
+    res = PyList_New(0);
+    if (res == NULL)
+        return NULL;
+    for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
+        while (op == self || op == args || op == res || op == t ||
+               (t != NULL && Py_TYPE(op) != (PyTypeObject *) t)) {
+            op = op->_ob_next;
+            if (op == &refchain)
+                return res;
+        }
+        if (PyList_Append(res, op) < 0) {
+            Py_DECREF(res);
+            return NULL;
+        }
+        op = op->_ob_next;
+    }
+    return res;
+}
+
+#endif
+
+
+/* Hack to force loading of capsule.o */
+PyTypeObject *_Py_capsule_hack = &PyCapsule_Type;
+
+
+/* Hack to force loading of cobject.o */
+PyTypeObject *_Py_cobject_hack = &PyCObject_Type;
+
+
+/* Hack to force loading of abstract.o */
+Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
+
+
+/* Python's malloc wrappers (see pymem.h) */
+
+void *
+PyMem_Malloc(size_t nbytes)
+{
+    return PyMem_MALLOC(nbytes);
+}
+
+void *
+PyMem_Realloc(void *p, size_t nbytes)
+{
+    return PyMem_REALLOC(p, nbytes);
+}
+
+void
+PyMem_Free(void *p)
+{
+    PyMem_FREE(p);
+}
+
+
+/* These methods are used to control infinite recursion in repr, str, print,
+   etc.  Container objects that may recursively contain themselves,
+   e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
+   Py_ReprLeave() to avoid infinite recursion.
+
+   Py_ReprEnter() returns 0 the first time it is called for a particular
+   object and 1 every time thereafter.  It returns -1 if an exception
+   occurred.  Py_ReprLeave() has no return value.
+
+   See dictobject.c and listobject.c for examples of use.
+*/
+
+#define KEY "Py_Repr"
+
+int
+Py_ReprEnter(PyObject *obj)
+{
+    PyObject *dict;
+    PyObject *list;
+    Py_ssize_t i;
+
+    dict = PyThreadState_GetDict();
+    if (dict == NULL)
+        return 0;
+    list = PyDict_GetItemString(dict, KEY);
+    if (list == NULL) {
+        list = PyList_New(0);
+        if (list == NULL)
+            return -1;
+        if (PyDict_SetItemString(dict, KEY, list) < 0)
+            return -1;
+        Py_DECREF(list);
+    }
+    i = PyList_GET_SIZE(list);
+    while (--i >= 0) {
+        if (PyList_GET_ITEM(list, i) == obj)
+            return 1;
+    }
+    PyList_Append(list, obj);
+    return 0;
+}
+
+void
+Py_ReprLeave(PyObject *obj)
+{
+    PyObject *dict;
+    PyObject *list;
+    Py_ssize_t i;
+
+    dict = PyThreadState_GetDict();
+    if (dict == NULL)
+        return;
+    list = PyDict_GetItemString(dict, KEY);
+    if (list == NULL || !PyList_Check(list))
+        return;
+    i = PyList_GET_SIZE(list);
+    /* Count backwards because we always expect obj to be list[-1] */
+    while (--i >= 0) {
+        if (PyList_GET_ITEM(list, i) == obj) {
+            PyList_SetSlice(list, i, i + 1, NULL);
+            break;
+        }
+    }
+}
+
+/* Trashcan support. */
+
+/* Current call-stack depth of tp_dealloc calls. */
+int _PyTrash_delete_nesting = 0;
+
+/* List of objects that still need to be cleaned up, singly linked via their
+ * gc headers' gc_prev pointers.
+ */
+PyObject *_PyTrash_delete_later = NULL;
+
+/* Add op to the _PyTrash_delete_later list.  Called when the current
+ * call-stack depth gets large.  op must be a currently untracked gc'ed
+ * object, with refcount 0.  Py_DECREF must already have been called on it.
+ */
+void
+_PyTrash_deposit_object(PyObject *op)
+{
+    assert(PyObject_IS_GC(op));
+    assert(_Py_AS_GC(op)->gc.gc_refs == _PyGC_REFS_UNTRACKED);
+    assert(op->ob_refcnt == 0);
+    _Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *)_PyTrash_delete_later;
+    _PyTrash_delete_later = op;
+}
+
+/* The equivalent API, using per-thread state recursion info */
+void
+_PyTrash_thread_deposit_object(PyObject *op)
+{
+    PyThreadState *tstate = PyThreadState_GET();
+    assert(PyObject_IS_GC(op));
+    assert(_Py_AS_GC(op)->gc.gc_refs == _PyGC_REFS_UNTRACKED);
+    assert(op->ob_refcnt == 0);
+    _Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *) tstate->trash_delete_later;
+    tstate->trash_delete_later = op;
+}
+
+/* Dealloccate all the objects in the _PyTrash_delete_later list.  Called when
+ * the call-stack unwinds again.
+ */
+void
+_PyTrash_destroy_chain(void)
+{
+    while (_PyTrash_delete_later) {
+        PyObject *op = _PyTrash_delete_later;
+        destructor dealloc = Py_TYPE(op)->tp_dealloc;
+
+        _PyTrash_delete_later =
+            (PyObject*) _Py_AS_GC(op)->gc.gc_prev;
+
+        /* Call the deallocator directly.  This used to try to
+         * fool Py_DECREF into calling it indirectly, but
+         * Py_DECREF was already called on this object, and in
+         * assorted non-release builds calling Py_DECREF again ends
+         * up distorting allocation statistics.
+         */
+        assert(op->ob_refcnt == 0);
+        ++_PyTrash_delete_nesting;
+        (*dealloc)(op);
+        --_PyTrash_delete_nesting;
+    }
+}
+
+/* The equivalent API, using per-thread state recursion info */
+void
+_PyTrash_thread_destroy_chain(void)
+{
+    PyThreadState *tstate = PyThreadState_GET();
+    while (tstate->trash_delete_later) {
+        PyObject *op = tstate->trash_delete_later;
+        destructor dealloc = Py_TYPE(op)->tp_dealloc;
+
+        tstate->trash_delete_later =
+            (PyObject*) _Py_AS_GC(op)->gc.gc_prev;
+
+        /* Call the deallocator directly.  This used to try to
+         * fool Py_DECREF into calling it indirectly, but
+         * Py_DECREF was already called on this object, and in
+         * assorted non-release builds calling Py_DECREF again ends
+         * up distorting allocation statistics.
+         */
+        assert(op->ob_refcnt == 0);
+        ++tstate->trash_delete_nesting;
+        (*dealloc)(op);
+        --tstate->trash_delete_nesting;
+    }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Python-2.7.5/Objects/obmalloc.c b/Python-2.7.5/Objects/obmalloc.c
new file mode 100644
index 0000000..38ebc37
--- /dev/null
+++ b/Python-2.7.5/Objects/obmalloc.c
@@ -0,0 +1,1888 @@
+#include "Python.h"
+
+#ifdef WITH_PYMALLOC
+
+#ifdef WITH_VALGRIND
+#include <valgrind/valgrind.h>
+
+/* If we're using GCC, use __builtin_expect() to reduce overhead of
+   the valgrind checks */
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#  define UNLIKELY(value) __builtin_expect((value), 0)
+#else
+#  define UNLIKELY(value) (value)
+#endif
+
+/* -1 indicates that we haven't checked that we're running on valgrind yet. */
+static int running_on_valgrind = -1;
+#endif
+
+/* An object allocator for Python.
+
+   Here is an introduction to the layers of the Python memory architecture,
+   showing where the object allocator is actually used (layer +2), It is
+   called for every object allocation and deallocation (PyObject_New/Del),
+   unless the object-specific allocators implement a proprietary allocation
+   scheme (ex.: ints use a simple free list). This is also the place where
+   the cyclic garbage collector operates selectively on container objects.
+
+
+    Object-specific allocators
+    _____   ______   ______       ________
+   [ int ] [ dict ] [ list ] ... [ string ]       Python core         |
++3 | <----- Object-specific memory -----> | <-- Non-object memory --> |
+    _______________________________       |                           |
+   [   Python's object allocator   ]      |                           |
++2 | ####### Object memory ####### | <------ Internal buffers ------> |
+    ______________________________________________________________    |
+   [          Python's raw memory allocator (PyMem_ API)          ]   |
++1 | <----- Python memory (under PyMem manager's control) ------> |   |
+    __________________________________________________________________
+   [    Underlying general-purpose allocator (ex: C library malloc)   ]
+ 0 | <------ Virtual memory allocated for the python process -------> |
+
+   =========================================================================
+    _______________________________________________________________________
+   [                OS-specific Virtual Memory Manager (VMM)               ]
+-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> |
+    __________________________________   __________________________________
+   [                                  ] [                                  ]
+-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> |
+
+*/
+/*==========================================================================*/
+
+/* A fast, special-purpose memory allocator for small blocks, to be used
+   on top of a general-purpose malloc -- heavily based on previous art. */
+
+/* Vladimir Marangozov -- August 2000 */
+
+/*
+ * "Memory management is where the rubber meets the road -- if we do the wrong
+ * thing at any level, the results will not be good. And if we don't make the
+ * levels work well together, we are in serious trouble." (1)
+ *
+ * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles,
+ *    "Dynamic Storage Allocation: A Survey and Critical Review",
+ *    in Proc. 1995 Int'l. Workshop on Memory Management, September 1995.
+ */
+
+/* #undef WITH_MEMORY_LIMITS */         /* disable mem limit checks  */
+
+/*==========================================================================*/
+
+/*
+ * Allocation strategy abstract:
+ *
+ * For small requests, the allocator sub-allocates <Big> blocks of memory.
+ * Requests greater than 256 bytes are routed to the system's allocator.
+ *
+ * Small requests are grouped in size classes spaced 8 bytes apart, due
+ * to the required valid alignment of the returned address. Requests of
+ * a particular size are serviced from memory pools of 4K (one VMM page).
+ * Pools are fragmented on demand and contain free lists of blocks of one
+ * particular size class. In other words, there is a fixed-size allocator
+ * for each size class. Free pools are shared by the different allocators
+ * thus minimizing the space reserved for a particular size class.
+ *
+ * This allocation strategy is a variant of what is known as "simple
+ * segregated storage based on array of free lists". The main drawback of
+ * simple segregated storage is that we might end up with lot of reserved
+ * memory for the different free lists, which degenerate in time. To avoid
+ * this, we partition each free list in pools and we share dynamically the
+ * reserved space between all free lists. This technique is quite efficient
+ * for memory intensive programs which allocate mainly small-sized blocks.
+ *
+ * For small requests we have the following table:
+ *
+ * Request in bytes     Size of allocated block      Size class idx
+ * ----------------------------------------------------------------
+ *        1-8                     8                       0
+ *        9-16                   16                       1
+ *       17-24                   24                       2
+ *       25-32                   32                       3
+ *       33-40                   40                       4
+ *       41-48                   48                       5
+ *       49-56                   56                       6
+ *       57-64                   64                       7
+ *       65-72                   72                       8
+ *        ...                   ...                     ...
+ *      241-248                 248                      30
+ *      249-256                 256                      31
+ *
+ *      0, 257 and up: routed to the underlying allocator.
+ */
+
+/*==========================================================================*/
+
+/*
+ * -- Main tunable settings section --
+ */
+
+/*
+ * Alignment of addresses returned to the user. 8-bytes alignment works
+ * on most current architectures (with 32-bit or 64-bit address busses).
+ * The alignment value is also used for grouping small requests in size
+ * classes spaced ALIGNMENT bytes apart.
+ *
+ * You shouldn't change this unless you know what you are doing.
+ */
+#define ALIGNMENT               8               /* must be 2^N */
+#define ALIGNMENT_SHIFT         3
+#define ALIGNMENT_MASK          (ALIGNMENT - 1)
+
+/* Return the number of bytes in size class I, as a uint. */
+#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT)
+
+/*
+ * Max size threshold below which malloc requests are considered to be
+ * small enough in order to use preallocated memory pools. You can tune
+ * this value according to your application behaviour and memory needs.
+ *
+ * The following invariants must hold:
+ *      1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 256
+ *      2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT
+ *
+ * Although not required, for better performance and space efficiency,
+ * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2.
+ */
+#define SMALL_REQUEST_THRESHOLD 256
+#define NB_SMALL_SIZE_CLASSES   (SMALL_REQUEST_THRESHOLD / ALIGNMENT)
+
+/*
+ * The system's VMM page size can be obtained on most unices with a
+ * getpagesize() call or deduced from various header files. To make
+ * things simpler, we assume that it is 4K, which is OK for most systems.
+ * It is probably better if this is the native page size, but it doesn't
+ * have to be.  In theory, if SYSTEM_PAGE_SIZE is larger than the native page
+ * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation
+ * violation fault.  4K is apparently OK for all the platforms that python
+ * currently targets.
+ */
+#define SYSTEM_PAGE_SIZE        (4 * 1024)
+#define SYSTEM_PAGE_SIZE_MASK   (SYSTEM_PAGE_SIZE - 1)
+
+/*
+ * Maximum amount of memory managed by the allocator for small requests.
+ */
+#ifdef WITH_MEMORY_LIMITS
+#ifndef SMALL_MEMORY_LIMIT
+#define SMALL_MEMORY_LIMIT      (64 * 1024 * 1024)      /* 64 MB -- more? */
+#endif
+#endif
+
+/*
+ * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned
+ * on a page boundary. This is a reserved virtual address space for the
+ * current process (obtained through a malloc call). In no way this means
+ * that the memory arenas will be used entirely. A malloc(<Big>) is usually
+ * an address range reservation for <Big> bytes, unless all pages within this
+ * space are referenced subsequently. So malloc'ing big blocks and not using
+ * them does not mean "wasting memory". It's an addressable range wastage...
+ *
+ * Therefore, allocating arenas with malloc is not optimal, because there is
+ * some address space wastage, but this is the most portable way to request
+ * memory from the system across various platforms.
+ */
+#define ARENA_SIZE              (256 << 10)     /* 256KB */
+
+#ifdef WITH_MEMORY_LIMITS
+#define MAX_ARENAS              (SMALL_MEMORY_LIMIT / ARENA_SIZE)
+#endif
+
+/*
+ * Size of the pools used for small blocks. Should be a power of 2,
+ * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k.
+ */
+#define POOL_SIZE               SYSTEM_PAGE_SIZE        /* must be 2^N */
+#define POOL_SIZE_MASK          SYSTEM_PAGE_SIZE_MASK
+
+/*
+ * -- End of tunable settings section --
+ */
+
+/*==========================================================================*/
+
+/*
+ * Locking
+ *
+ * To reduce lock contention, it would probably be better to refine the
+ * crude function locking with per size class locking. I'm not positive
+ * however, whether it's worth switching to such locking policy because
+ * of the performance penalty it might introduce.
+ *
+ * The following macros describe the simplest (should also be the fastest)
+ * lock object on a particular platform and the init/fini/lock/unlock
+ * operations on it. The locks defined here are not expected to be recursive
+ * because it is assumed that they will always be called in the order:
+ * INIT, [LOCK, UNLOCK]*, FINI.
+ */
+
+/*
+ * Python's threads are serialized, so object malloc locking is disabled.
+ */
+#define SIMPLELOCK_DECL(lock)   /* simple lock declaration              */
+#define SIMPLELOCK_INIT(lock)   /* allocate (if needed) and initialize  */
+#define SIMPLELOCK_FINI(lock)   /* free/destroy an existing lock        */
+#define SIMPLELOCK_LOCK(lock)   /* acquire released lock */
+#define SIMPLELOCK_UNLOCK(lock) /* release acquired lock */
+
+/*
+ * Basic types
+ * I don't care if these are defined in <sys/types.h> or elsewhere. Axiom.
+ */
+#undef  uchar
+#define uchar   unsigned char   /* assuming == 8 bits  */
+
+#undef  uint
+#define uint    unsigned int    /* assuming >= 16 bits */
+
+#undef  ulong
+#define ulong   unsigned long   /* assuming >= 32 bits */
+
+#undef uptr
+#define uptr    Py_uintptr_t
+
+/* When you say memory, my mind reasons in terms of (pointers to) blocks */
+typedef uchar block;
+
+/* Pool for small blocks. */
+struct pool_header {
+    union { block *_padding;
+            uint count; } ref;          /* number of allocated blocks    */
+    block *freeblock;                   /* pool's free list head         */
+    struct pool_header *nextpool;       /* next pool of this size class  */
+    struct pool_header *prevpool;       /* previous pool       ""        */
+    uint arenaindex;                    /* index into arenas of base adr */
+    uint szidx;                         /* block size class index        */
+    uint nextoffset;                    /* bytes to virgin block         */
+    uint maxnextoffset;                 /* largest valid nextoffset      */
+};
+
+typedef struct pool_header *poolp;
+
+/* Record keeping for arenas. */
+struct arena_object {
+    /* The address of the arena, as returned by malloc.  Note that 0
+     * will never be returned by a successful malloc, and is used
+     * here to mark an arena_object that doesn't correspond to an
+     * allocated arena.
+     */
+    uptr address;
+
+    /* Pool-aligned pointer to the next pool to be carved off. */
+    block* pool_address;
+
+    /* The number of available pools in the arena:  free pools + never-
+     * allocated pools.
+     */
+    uint nfreepools;
+
+    /* The total number of pools in the arena, whether or not available. */
+    uint ntotalpools;
+
+    /* Singly-linked list of available pools. */
+    struct pool_header* freepools;
+
+    /* Whenever this arena_object is not associated with an allocated
+     * arena, the nextarena member is used to link all unassociated
+     * arena_objects in the singly-linked `unused_arena_objects` list.
+     * The prevarena member is unused in this case.
+     *
+     * When this arena_object is associated with an allocated arena
+     * with at least one available pool, both members are used in the
+     * doubly-linked `usable_arenas` list, which is maintained in
+     * increasing order of `nfreepools` values.
+     *
+     * Else this arena_object is associated with an allocated arena
+     * all of whose pools are in use.  `nextarena` and `prevarena`
+     * are both meaningless in this case.
+     */
+    struct arena_object* nextarena;
+    struct arena_object* prevarena;
+};
+
+#undef  ROUNDUP
+#define ROUNDUP(x)              (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
+#define POOL_OVERHEAD           ROUNDUP(sizeof(struct pool_header))
+
+#define DUMMY_SIZE_IDX          0xffff  /* size class of newly cached pools */
+
+/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */
+#define POOL_ADDR(P) ((poolp)((uptr)(P) & ~(uptr)POOL_SIZE_MASK))
+
+/* Return total number of blocks in pool of size index I, as a uint. */
+#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I))
+
+/*==========================================================================*/
+
+/*
+ * This malloc lock
+ */
+SIMPLELOCK_DECL(_malloc_lock)
+#define LOCK()          SIMPLELOCK_LOCK(_malloc_lock)
+#define UNLOCK()        SIMPLELOCK_UNLOCK(_malloc_lock)
+#define LOCK_INIT()     SIMPLELOCK_INIT(_malloc_lock)
+#define LOCK_FINI()     SIMPLELOCK_FINI(_malloc_lock)
+
+/*
+ * Pool table -- headed, circular, doubly-linked lists of partially used pools.
+
+This is involved.  For an index i, usedpools[i+i] is the header for a list of
+all partially used pools holding small blocks with "size class idx" i. So
+usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size
+16, and so on:  index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT.
+
+Pools are carved off an arena's highwater mark (an arena_object's pool_address
+member) as needed.  Once carved off, a pool is in one of three states forever
+after:
+
+used == partially used, neither empty nor full
+    At least one block in the pool is currently allocated, and at least one
+    block in the pool is not currently allocated (note this implies a pool
+    has room for at least two blocks).
+    This is a pool's initial state, as a pool is created only when malloc
+    needs space.
+    The pool holds blocks of a fixed size, and is in the circular list headed
+    at usedpools[i] (see above).  It's linked to the other used pools of the
+    same size class via the pool_header's nextpool and prevpool members.
+    If all but one block is currently allocated, a malloc can cause a
+    transition to the full state.  If all but one block is not currently
+    allocated, a free can cause a transition to the empty state.
+
+full == all the pool's blocks are currently allocated
+    On transition to full, a pool is unlinked from its usedpools[] list.
+    It's not linked to from anything then anymore, and its nextpool and
+    prevpool members are meaningless until it transitions back to used.
+    A free of a block in a full pool puts the pool back in the used state.
+    Then it's linked in at the front of the appropriate usedpools[] list, so
+    that the next allocation for its size class will reuse the freed block.
+
+empty == all the pool's blocks are currently available for allocation
+    On transition to empty, a pool is unlinked from its usedpools[] list,
+    and linked to the front of its arena_object's singly-linked freepools list,
+    via its nextpool member.  The prevpool member has no meaning in this case.
+    Empty pools have no inherent size class:  the next time a malloc finds
+    an empty list in usedpools[], it takes the first pool off of freepools.
+    If the size class needed happens to be the same as the size class the pool
+    last had, some pool initialization can be skipped.
+
+
+Block Management
+
+Blocks within pools are again carved out as needed.  pool->freeblock points to
+the start of a singly-linked list of free blocks within the pool.  When a
+block is freed, it's inserted at the front of its pool's freeblock list.  Note
+that the available blocks in a pool are *not* linked all together when a pool
+is initialized.  Instead only "the first two" (lowest addresses) blocks are
+set up, returning the first such block, and setting pool->freeblock to a
+one-block list holding the second such block.  This is consistent with that
+pymalloc strives at all levels (arena, pool, and block) never to touch a piece
+of memory until it's actually needed.
+
+So long as a pool is in the used state, we're certain there *is* a block
+available for allocating, and pool->freeblock is not NULL.  If pool->freeblock
+points to the end of the free list before we've carved the entire pool into
+blocks, that means we simply haven't yet gotten to one of the higher-address
+blocks.  The offset from the pool_header to the start of "the next" virgin
+block is stored in the pool_header nextoffset member, and the largest value
+of nextoffset that makes sense is stored in the maxnextoffset member when a
+pool is initialized.  All the blocks in a pool have been passed out at least
+once when and only when nextoffset > maxnextoffset.
+
+
+Major obscurity:  While the usedpools vector is declared to have poolp
+entries, it doesn't really.  It really contains two pointers per (conceptual)
+poolp entry, the nextpool and prevpool members of a pool_header.  The
+excruciating initialization code below fools C so that
+
+    usedpool[i+i]
+
+"acts like" a genuine poolp, but only so long as you only reference its
+nextpool and prevpool members.  The "- 2*sizeof(block *)" gibberish is
+compensating for that a pool_header's nextpool and prevpool members
+immediately follow a pool_header's first two members:
+
+    union { block *_padding;
+            uint count; } ref;
+    block *freeblock;
+
+each of which consume sizeof(block *) bytes.  So what usedpools[i+i] really
+contains is a fudged-up pointer p such that *if* C believes it's a poolp
+pointer, then p->nextpool and p->prevpool are both p (meaning that the headed
+circular list is empty).
+
+It's unclear why the usedpools setup is so convoluted.  It could be to
+minimize the amount of cache required to hold this heavily-referenced table
+(which only *needs* the two interpool pointer members of a pool_header). OTOH,
+referencing code has to remember to "double the index" and doing so isn't
+free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying
+on that C doesn't insert any padding anywhere in a pool_header at or before
+the prevpool member.
+**************************************************************************** */
+
+#define PTA(x)  ((poolp )((uchar *)&(usedpools[2*(x)]) - 2*sizeof(block *)))
+#define PT(x)   PTA(x), PTA(x)
+
+static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = {
+    PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7)
+#if NB_SMALL_SIZE_CLASSES > 8
+    , PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15)
+#if NB_SMALL_SIZE_CLASSES > 16
+    , PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23)
+#if NB_SMALL_SIZE_CLASSES > 24
+    , PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31)
+#if NB_SMALL_SIZE_CLASSES > 32
+    , PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39)
+#if NB_SMALL_SIZE_CLASSES > 40
+    , PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47)
+#if NB_SMALL_SIZE_CLASSES > 48
+    , PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55)
+#if NB_SMALL_SIZE_CLASSES > 56
+    , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63)
+#endif /* NB_SMALL_SIZE_CLASSES > 56 */
+#endif /* NB_SMALL_SIZE_CLASSES > 48 */
+#endif /* NB_SMALL_SIZE_CLASSES > 40 */
+#endif /* NB_SMALL_SIZE_CLASSES > 32 */
+#endif /* NB_SMALL_SIZE_CLASSES > 24 */
+#endif /* NB_SMALL_SIZE_CLASSES > 16 */
+#endif /* NB_SMALL_SIZE_CLASSES >  8 */
+};
+
+/*==========================================================================
+Arena management.
+
+`arenas` is a vector of arena_objects.  It contains maxarenas entries, some of
+which may not be currently used (== they're arena_objects that aren't
+currently associated with an allocated arena).  Note that arenas proper are
+separately malloc'ed.
+
+Prior to Python 2.5, arenas were never free()'ed.  Starting with Python 2.5,
+we do try to free() arenas, and use some mild heuristic strategies to increase
+the likelihood that arenas eventually can be freed.
+
+unused_arena_objects
+
+    This is a singly-linked list of the arena_objects that are currently not
+    being used (no arena is associated with them).  Objects are taken off the
+    head of the list in new_arena(), and are pushed on the head of the list in
+    PyObject_Free() when the arena is empty.  Key invariant:  an arena_object
+    is on this list if and only if its .address member is 0.
+
+usable_arenas
+
+    This is a doubly-linked list of the arena_objects associated with arenas
+    that have pools available.  These pools are either waiting to be reused,
+    or have not been used before.  The list is sorted to have the most-
+    allocated arenas first (ascending order based on the nfreepools member).
+    This means that the next allocation will come from a heavily used arena,
+    which gives the nearly empty arenas a chance to be returned to the system.
+    In my unscientific tests this dramatically improved the number of arenas
+    that could be freed.
+
+Note that an arena_object associated with an arena all of whose pools are
+currently in use isn't on either list.
+*/
+
+/* Array of objects used to track chunks of memory (arenas). */
+static struct arena_object* arenas = NULL;
+/* Number of slots currently allocated in the `arenas` vector. */
+static uint maxarenas = 0;
+
+/* The head of the singly-linked, NULL-terminated list of available
+ * arena_objects.
+ */
+static struct arena_object* unused_arena_objects = NULL;
+
+/* The head of the doubly-linked, NULL-terminated at each end, list of
+ * arena_objects associated with arenas that have pools available.
+ */
+static struct arena_object* usable_arenas = NULL;
+
+/* How many arena_objects do we initially allocate?
+ * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
+ * `arenas` vector.
+ */
+#define INITIAL_ARENA_OBJECTS 16
+
+/* Number of arenas allocated that haven't been free()'d. */
+static size_t narenas_currently_allocated = 0;
+
+#ifdef PYMALLOC_DEBUG
+/* Total number of times malloc() called to allocate an arena. */
+static size_t ntimes_arena_allocated = 0;
+/* High water mark (max value ever seen) for narenas_currently_allocated. */
+static size_t narenas_highwater = 0;
+#endif
+
+/* Allocate a new arena.  If we run out of memory, return NULL.  Else
+ * allocate a new arena, and return the address of an arena_object
+ * describing the new arena.  It's expected that the caller will set
+ * `usable_arenas` to the return value.
+ */
+static struct arena_object*
+new_arena(void)
+{
+    struct arena_object* arenaobj;
+    uint excess;        /* number of bytes above pool alignment */
+
+#ifdef PYMALLOC_DEBUG
+    if (Py_GETENV("PYTHONMALLOCSTATS"))
+        _PyObject_DebugMallocStats();
+#endif
+    if (unused_arena_objects == NULL) {
+        uint i;
+        uint numarenas;
+        size_t nbytes;
+
+        /* Double the number of arena objects on each allocation.
+         * Note that it's possible for `numarenas` to overflow.
+         */
+        numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
+        if (numarenas <= maxarenas)
+            return NULL;                /* overflow */
+#if SIZEOF_SIZE_T <= SIZEOF_INT
+        if (numarenas > PY_SIZE_MAX / sizeof(*arenas))
+            return NULL;                /* overflow */
+#endif
+        nbytes = numarenas * sizeof(*arenas);
+        arenaobj = (struct arena_object *)realloc(arenas, nbytes);
+        if (arenaobj == NULL)
+            return NULL;
+        arenas = arenaobj;
+
+        /* We might need to fix pointers that were copied.  However,
+         * new_arena only gets called when all the pages in the
+         * previous arenas are full.  Thus, there are *no* pointers
+         * into the old array. Thus, we don't have to worry about
+         * invalid pointers.  Just to be sure, some asserts:
+         */
+        assert(usable_arenas == NULL);
+        assert(unused_arena_objects == NULL);
+
+        /* Put the new arenas on the unused_arena_objects list. */
+        for (i = maxarenas; i < numarenas; ++i) {
+            arenas[i].address = 0;              /* mark as unassociated */
+            arenas[i].nextarena = i < numarenas - 1 ?
+                                   &arenas[i+1] : NULL;
+        }
+
+        /* Update globals. */
+        unused_arena_objects = &arenas[maxarenas];
+        maxarenas = numarenas;
+    }
+
+    /* Take the next available arena object off the head of the list. */
+    assert(unused_arena_objects != NULL);
+    arenaobj = unused_arena_objects;
+    unused_arena_objects = arenaobj->nextarena;
+    assert(arenaobj->address == 0);
+    arenaobj->address = (uptr)malloc(ARENA_SIZE);
+    if (arenaobj->address == 0) {
+        /* The allocation failed: return NULL after putting the
+         * arenaobj back.
+         */
+        arenaobj->nextarena = unused_arena_objects;
+        unused_arena_objects = arenaobj;
+        return NULL;
+    }
+
+    ++narenas_currently_allocated;
+#ifdef PYMALLOC_DEBUG
+    ++ntimes_arena_allocated;
+    if (narenas_currently_allocated > narenas_highwater)
+        narenas_highwater = narenas_currently_allocated;
+#endif
+    arenaobj->freepools = NULL;
+    /* pool_address <- first pool-aligned address in the arena
+       nfreepools <- number of whole pools that fit after alignment */
+    arenaobj->pool_address = (block*)arenaobj->address;
+    arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE;
+    assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE);
+    excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
+    if (excess != 0) {
+        --arenaobj->nfreepools;
+        arenaobj->pool_address += POOL_SIZE - excess;
+    }
+    arenaobj->ntotalpools = arenaobj->nfreepools;
+
+    return arenaobj;
+}
+
+/*
+Py_ADDRESS_IN_RANGE(P, POOL)
+
+Return true if and only if P is an address that was allocated by pymalloc.
+POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
+(the caller is asked to compute this because the macro expands POOL more than
+once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
+variable and pass the latter to the macro; because Py_ADDRESS_IN_RANGE is
+called on every alloc/realloc/free, micro-efficiency is important here).
+
+Tricky:  Let B be the arena base address associated with the pool, B =
+arenas[(POOL)->arenaindex].address.  Then P belongs to the arena if and only if
+
+    B <= P < B + ARENA_SIZE
+
+Subtracting B throughout, this is true iff
+
+    0 <= P-B < ARENA_SIZE
+
+By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
+
+Obscure:  A PyMem "free memory" function can call the pymalloc free or realloc
+before the first arena has been allocated.  `arenas` is still NULL in that
+case.  We're relying on that maxarenas is also 0 in that case, so that
+(POOL)->arenaindex < maxarenas  must be false, saving us from trying to index
+into a NULL arenas.
+
+Details:  given P and POOL, the arena_object corresponding to P is AO =
+arenas[(POOL)->arenaindex].  Suppose obmalloc controls P.  Then (barring wild
+stores, etc), POOL is the correct address of P's pool, AO.address is the
+correct base address of the pool's arena, and P must be within ARENA_SIZE of
+AO.address.  In addition, AO.address is not 0 (no arena can start at address 0
+(NULL)).  Therefore Py_ADDRESS_IN_RANGE correctly reports that obmalloc
+controls P.
+
+Now suppose obmalloc does not control P (e.g., P was obtained via a direct
+call to the system malloc() or realloc()).  (POOL)->arenaindex may be anything
+in this case -- it may even be uninitialized trash.  If the trash arenaindex
+is >= maxarenas, the macro correctly concludes at once that obmalloc doesn't
+control P.
+
+Else arenaindex is < maxarena, and AO is read up.  If AO corresponds to an
+allocated arena, obmalloc controls all the memory in slice AO.address :
+AO.address+ARENA_SIZE.  By case assumption, P is not controlled by obmalloc,
+so P doesn't lie in that slice, so the macro correctly reports that P is not
+controlled by obmalloc.
+
+Finally, if P is not controlled by obmalloc and AO corresponds to an unused
+arena_object (one not currently associated with an allocated arena),
+AO.address is 0, and the second test in the macro reduces to:
+
+    P < ARENA_SIZE
+
+If P >= ARENA_SIZE (extremely likely), the macro again correctly concludes
+that P is not controlled by obmalloc.  However, if P < ARENA_SIZE, this part
+of the test still passes, and the third clause (AO.address != 0) is necessary
+to get the correct result:  AO.address is 0 in this case, so the macro
+correctly reports that P is not controlled by obmalloc (despite that P lies in
+slice AO.address : AO.address + ARENA_SIZE).
+
+Note:  The third (AO.address != 0) clause was added in Python 2.5.  Before
+2.5, arenas were never free()'ed, and an arenaindex < maxarena always
+corresponded to a currently-allocated arena, so the "P is not controlled by
+obmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case
+was impossible.
+
+Note that the logic is excruciating, and reading up possibly uninitialized
+memory when P is not controlled by obmalloc (to get at (POOL)->arenaindex)
+creates problems for some memory debuggers.  The overwhelming advantage is
+that this test determines whether an arbitrary address is controlled by
+obmalloc in a small constant time, independent of the number of arenas
+obmalloc controls.  Since this test is needed at every entry point, it's
+extremely desirable that it be this fast.
+
+Since Py_ADDRESS_IN_RANGE may be reading from memory which was not allocated
+by Python, it is important that (POOL)->arenaindex is read only once, as
+another thread may be concurrently modifying the value without holding the
+GIL.  To accomplish this, the arenaindex_temp variable is used to store
+(POOL)->arenaindex for the duration of the Py_ADDRESS_IN_RANGE macro's
+execution.  The caller of the macro is responsible for declaring this
+variable.
+*/
+#define Py_ADDRESS_IN_RANGE(P, POOL)                    \
+    ((arenaindex_temp = (POOL)->arenaindex) < maxarenas &&              \
+     (uptr)(P) - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE && \
+     arenas[arenaindex_temp].address != 0)
+
+
+/* This is only useful when running memory debuggers such as
+ * Purify or Valgrind.  Uncomment to use.
+ *
+#define Py_USING_MEMORY_DEBUGGER
+ */
+
+#ifdef Py_USING_MEMORY_DEBUGGER
+
+/* Py_ADDRESS_IN_RANGE may access uninitialized memory by design
+ * This leads to thousands of spurious warnings when using
+ * Purify or Valgrind.  By making a function, we can easily
+ * suppress the uninitialized memory reads in this one function.
+ * So we won't ignore real errors elsewhere.
+ *
+ * Disable the macro and use a function.
+ */
+
+#undef Py_ADDRESS_IN_RANGE
+
+#if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \
+                          (__GNUC__ >= 4))
+#define Py_NO_INLINE __attribute__((__noinline__))
+#else
+#define Py_NO_INLINE
+#endif
+
+/* Don't make static, to try to ensure this isn't inlined. */
+int Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE;
+#undef Py_NO_INLINE
+#endif
+
+/*==========================================================================*/
+
+/* malloc.  Note that nbytes==0 tries to return a non-NULL pointer, distinct
+ * from all other currently live pointers.  This may not be possible.
+ */
+
+/*
+ * The basic blocks are ordered by decreasing execution frequency,
+ * which minimizes the number of jumps in the most common cases,
+ * improves branching prediction and instruction scheduling (small
+ * block allocations typically result in a couple of instructions).
+ * Unless the optimizer reorders everything, being too smart...
+ */
+
+#undef PyObject_Malloc
+void *
+PyObject_Malloc(size_t nbytes)
+{
+    block *bp;
+    poolp pool;
+    poolp next;
+    uint size;
+
+#ifdef WITH_VALGRIND
+    if (UNLIKELY(running_on_valgrind == -1))
+        running_on_valgrind = RUNNING_ON_VALGRIND;
+    if (UNLIKELY(running_on_valgrind))
+        goto redirect;
+#endif
+
+    /*
+     * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
+     * Most python internals blindly use a signed Py_ssize_t to track
+     * things without checking for overflows or negatives.
+     * As size_t is unsigned, checking for nbytes < 0 is not required.
+     */
+    if (nbytes > PY_SSIZE_T_MAX)
+        return NULL;
+
+    /*
+     * This implicitly redirects malloc(0).
+     */
+    if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
+        LOCK();
+        /*
+         * Most frequent paths first
+         */
+        size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT;
+        pool = usedpools[size + size];
+        if (pool != pool->nextpool) {
+            /*
+             * There is a used pool for this size class.
+             * Pick up the head block of its free list.
+             */
+            ++pool->ref.count;
+            bp = pool->freeblock;
+            assert(bp != NULL);
+            if ((pool->freeblock = *(block **)bp) != NULL) {
+                UNLOCK();
+                return (void *)bp;
+            }
+            /*
+             * Reached the end of the free list, try to extend it.
+             */
+            if (pool->nextoffset <= pool->maxnextoffset) {
+                /* There is room for another block. */
+                pool->freeblock = (block*)pool +
+                                  pool->nextoffset;
+                pool->nextoffset += INDEX2SIZE(size);
+                *(block **)(pool->freeblock) = NULL;
+                UNLOCK();
+                return (void *)bp;
+            }
+            /* Pool is full, unlink from used pools. */
+            next = pool->nextpool;
+            pool = pool->prevpool;
+            next->prevpool = pool;
+            pool->nextpool = next;
+            UNLOCK();
+            return (void *)bp;
+        }
+
+        /* There isn't a pool of the right size class immediately
+         * available:  use a free pool.
+         */
+        if (usable_arenas == NULL) {
+            /* No arena has a free pool:  allocate a new arena. */
+#ifdef WITH_MEMORY_LIMITS
+            if (narenas_currently_allocated >= MAX_ARENAS) {
+                UNLOCK();
+                goto redirect;
+            }
+#endif
+            usable_arenas = new_arena();
+            if (usable_arenas == NULL) {
+                UNLOCK();
+                goto redirect;
+            }
+            usable_arenas->nextarena =
+                usable_arenas->prevarena = NULL;
+        }
+        assert(usable_arenas->address != 0);
+
+        /* Try to get a cached free pool. */
+        pool = usable_arenas->freepools;
+        if (pool != NULL) {
+            /* Unlink from cached pools. */
+            usable_arenas->freepools = pool->nextpool;
+
+            /* This arena already had the smallest nfreepools
+             * value, so decreasing nfreepools doesn't change
+             * that, and we don't need to rearrange the
+             * usable_arenas list.  However, if the arena has
+             * become wholly allocated, we need to remove its
+             * arena_object from usable_arenas.
+             */
+            --usable_arenas->nfreepools;
+            if (usable_arenas->nfreepools == 0) {
+                /* Wholly allocated:  remove. */
+                assert(usable_arenas->freepools == NULL);
+                assert(usable_arenas->nextarena == NULL ||
+                       usable_arenas->nextarena->prevarena ==
+                       usable_arenas);
+
+                usable_arenas = usable_arenas->nextarena;
+                if (usable_arenas != NULL) {
+                    usable_arenas->prevarena = NULL;
+                    assert(usable_arenas->address != 0);
+                }
+            }
+            else {
+                /* nfreepools > 0:  it must be that freepools
+                 * isn't NULL, or that we haven't yet carved
+                 * off all the arena's pools for the first
+                 * time.
+                 */
+                assert(usable_arenas->freepools != NULL ||
+                       usable_arenas->pool_address <=
+                       (block*)usable_arenas->address +
+                           ARENA_SIZE - POOL_SIZE);
+            }
+        init_pool:
+            /* Frontlink to used pools. */
+            next = usedpools[size + size]; /* == prev */
+            pool->nextpool = next;
+            pool->prevpool = next;
+            next->nextpool = pool;
+            next->prevpool = pool;
+            pool->ref.count = 1;
+            if (pool->szidx == size) {
+                /* Luckily, this pool last contained blocks
+                 * of the same size class, so its header
+                 * and free list are already initialized.
+                 */
+                bp = pool->freeblock;
+                pool->freeblock = *(block **)bp;
+                UNLOCK();
+                return (void *)bp;
+            }
+            /*
+             * Initialize the pool header, set up the free list to
+             * contain just the second block, and return the first
+             * block.
+             */
+            pool->szidx = size;
+            size = INDEX2SIZE(size);
+            bp = (block *)pool + POOL_OVERHEAD;
+            pool->nextoffset = POOL_OVERHEAD + (size << 1);
+            pool->maxnextoffset = POOL_SIZE - size;
+            pool->freeblock = bp + size;
+            *(block **)(pool->freeblock) = NULL;
+            UNLOCK();
+            return (void *)bp;
+        }
+
+        /* Carve off a new pool. */
+        assert(usable_arenas->nfreepools > 0);
+        assert(usable_arenas->freepools == NULL);
+        pool = (poolp)usable_arenas->pool_address;
+        assert((block*)pool <= (block*)usable_arenas->address +
+                               ARENA_SIZE - POOL_SIZE);
+        pool->arenaindex = usable_arenas - arenas;
+        assert(&arenas[pool->arenaindex] == usable_arenas);
+        pool->szidx = DUMMY_SIZE_IDX;
+        usable_arenas->pool_address += POOL_SIZE;
+        --usable_arenas->nfreepools;
+
+        if (usable_arenas->nfreepools == 0) {
+            assert(usable_arenas->nextarena == NULL ||
+                   usable_arenas->nextarena->prevarena ==
+                   usable_arenas);
+            /* Unlink the arena:  it is completely allocated. */
+            usable_arenas = usable_arenas->nextarena;
+            if (usable_arenas != NULL) {
+                usable_arenas->prevarena = NULL;
+                assert(usable_arenas->address != 0);
+            }
+        }
+
+        goto init_pool;
+    }
+
+    /* The small block allocator ends here. */
+
+redirect:
+    /* Redirect the original request to the underlying (libc) allocator.
+     * We jump here on bigger requests, on error in the code above (as a
+     * last chance to serve the request) or when the max memory limit
+     * has been reached.
+     */
+    if (nbytes == 0)
+        nbytes = 1;
+    return (void *)malloc(nbytes);
+}
+
+/* free */
+
+#undef PyObject_Free
+void
+PyObject_Free(void *p)
+{
+    poolp pool;
+    block *lastfree;
+    poolp next, prev;
+    uint size;
+#ifndef Py_USING_MEMORY_DEBUGGER
+    uint arenaindex_temp;
+#endif
+
+    if (p == NULL)      /* free(NULL) has no effect */
+        return;
+
+#ifdef WITH_VALGRIND
+    if (UNLIKELY(running_on_valgrind > 0))
+        goto redirect;
+#endif
+
+    pool = POOL_ADDR(p);
+    if (Py_ADDRESS_IN_RANGE(p, pool)) {
+        /* We allocated this address. */
+        LOCK();
+        /* Link p to the start of the pool's freeblock list.  Since
+         * the pool had at least the p block outstanding, the pool
+         * wasn't empty (so it's already in a usedpools[] list, or
+         * was full and is in no list -- it's not in the freeblocks
+         * list in any case).
+         */
+        assert(pool->ref.count > 0);            /* else it was empty */
+        *(block **)p = lastfree = pool->freeblock;
+        pool->freeblock = (block *)p;
+        if (lastfree) {
+            struct arena_object* ao;
+            uint nf;  /* ao->nfreepools */
+
+            /* freeblock wasn't NULL, so the pool wasn't full,
+             * and the pool is in a usedpools[] list.
+             */
+            if (--pool->ref.count != 0) {
+                /* pool isn't empty:  leave it in usedpools */
+                UNLOCK();
+                return;
+            }
+            /* Pool is now empty:  unlink from usedpools, and
+             * link to the front of freepools.  This ensures that
+             * previously freed pools will be allocated later
+             * (being not referenced, they are perhaps paged out).
+             */
+            next = pool->nextpool;
+            prev = pool->prevpool;
+            next->prevpool = prev;
+            prev->nextpool = next;
+
+            /* Link the pool to freepools.  This is a singly-linked
+             * list, and pool->prevpool isn't used there.
+             */
+            ao = &arenas[pool->arenaindex];
+            pool->nextpool = ao->freepools;
+            ao->freepools = pool;
+            nf = ++ao->nfreepools;
+
+            /* All the rest is arena management.  We just freed
+             * a pool, and there are 4 cases for arena mgmt:
+             * 1. If all the pools are free, return the arena to
+             *    the system free().
+             * 2. If this is the only free pool in the arena,
+             *    add the arena back to the `usable_arenas` list.
+             * 3. If the "next" arena has a smaller count of free
+             *    pools, we have to "slide this arena right" to
+             *    restore that usable_arenas is sorted in order of
+             *    nfreepools.
+             * 4. Else there's nothing more to do.
+             */
+            if (nf == ao->ntotalpools) {
+                /* Case 1.  First unlink ao from usable_arenas.
+                 */
+                assert(ao->prevarena == NULL ||
+                       ao->prevarena->address != 0);
+                assert(ao ->nextarena == NULL ||
+                       ao->nextarena->address != 0);
+
+                /* Fix the pointer in the prevarena, or the
+                 * usable_arenas pointer.
+                 */
+                if (ao->prevarena == NULL) {
+                    usable_arenas = ao->nextarena;
+                    assert(usable_arenas == NULL ||
+                           usable_arenas->address != 0);
+                }
+                else {
+                    assert(ao->prevarena->nextarena == ao);
+                    ao->prevarena->nextarena =
+                        ao->nextarena;
+                }
+                /* Fix the pointer in the nextarena. */
+                if (ao->nextarena != NULL) {
+                    assert(ao->nextarena->prevarena == ao);
+                    ao->nextarena->prevarena =
+                        ao->prevarena;
+                }
+                /* Record that this arena_object slot is
+                 * available to be reused.
+                 */
+                ao->nextarena = unused_arena_objects;
+                unused_arena_objects = ao;
+
+                /* Free the entire arena. */
+                free((void *)ao->address);
+                ao->address = 0;                        /* mark unassociated */
+                --narenas_currently_allocated;
+
+                UNLOCK();
+                return;
+            }
+            if (nf == 1) {
+                /* Case 2.  Put ao at the head of
+                 * usable_arenas.  Note that because
+                 * ao->nfreepools was 0 before, ao isn't
+                 * currently on the usable_arenas list.
+                 */
+                ao->nextarena = usable_arenas;
+                ao->prevarena = NULL;
+                if (usable_arenas)
+                    usable_arenas->prevarena = ao;
+                usable_arenas = ao;
+                assert(usable_arenas->address != 0);
+
+                UNLOCK();
+                return;
+            }
+            /* If this arena is now out of order, we need to keep
+             * the list sorted.  The list is kept sorted so that
+             * the "most full" arenas are used first, which allows
+             * the nearly empty arenas to be completely freed.  In
+             * a few un-scientific tests, it seems like this
+             * approach allowed a lot more memory to be freed.
+             */
+            if (ao->nextarena == NULL ||
+                         nf <= ao->nextarena->nfreepools) {
+                /* Case 4.  Nothing to do. */
+                UNLOCK();
+                return;
+            }
+            /* Case 3:  We have to move the arena towards the end
+             * of the list, because it has more free pools than
+             * the arena to its right.
+             * First unlink ao from usable_arenas.
+             */
+            if (ao->prevarena != NULL) {
+                /* ao isn't at the head of the list */
+                assert(ao->prevarena->nextarena == ao);
+                ao->prevarena->nextarena = ao->nextarena;
+            }
+            else {
+                /* ao is at the head of the list */
+                assert(usable_arenas == ao);
+                usable_arenas = ao->nextarena;
+            }
+            ao->nextarena->prevarena = ao->prevarena;
+
+            /* Locate the new insertion point by iterating over
+             * the list, using our nextarena pointer.
+             */
+            while (ao->nextarena != NULL &&
+                            nf > ao->nextarena->nfreepools) {
+                ao->prevarena = ao->nextarena;
+                ao->nextarena = ao->nextarena->nextarena;
+            }
+
+            /* Insert ao at this point. */
+            assert(ao->nextarena == NULL ||
+                ao->prevarena == ao->nextarena->prevarena);
+            assert(ao->prevarena->nextarena == ao->nextarena);
+
+            ao->prevarena->nextarena = ao;
+            if (ao->nextarena != NULL)
+                ao->nextarena->prevarena = ao;
+
+            /* Verify that the swaps worked. */
+            assert(ao->nextarena == NULL ||
+                      nf <= ao->nextarena->nfreepools);
+            assert(ao->prevarena == NULL ||
+                      nf > ao->prevarena->nfreepools);
+            assert(ao->nextarena == NULL ||
+                ao->nextarena->prevarena == ao);
+            assert((usable_arenas == ao &&
+                ao->prevarena == NULL) ||
+                ao->prevarena->nextarena == ao);
+
+            UNLOCK();
+            return;
+        }
+        /* Pool was full, so doesn't currently live in any list:
+         * link it to the front of the appropriate usedpools[] list.
+         * This mimics LRU pool usage for new allocations and
+         * targets optimal filling when several pools contain
+         * blocks of the same size class.
+         */
+        --pool->ref.count;
+        assert(pool->ref.count > 0);            /* else the pool is empty */
+        size = pool->szidx;
+        next = usedpools[size + size];
+        prev = next->prevpool;
+        /* insert pool before next:   prev <-> pool <-> next */
+        pool->nextpool = next;
+        pool->prevpool = prev;
+        next->prevpool = pool;
+        prev->nextpool = pool;
+        UNLOCK();
+        return;
+    }
+
+#ifdef WITH_VALGRIND
+redirect:
+#endif
+    /* We didn't allocate this address. */
+    free(p);
+}
+
+/* realloc.  If p is NULL, this acts like malloc(nbytes).  Else if nbytes==0,
+ * then as the Python docs promise, we do not treat this like free(p), and
+ * return a non-NULL result.
+ */
+
+#undef PyObject_Realloc
+void *
+PyObject_Realloc(void *p, size_t nbytes)
+{
+    void *bp;
+    poolp pool;
+    size_t size;
+#ifndef Py_USING_MEMORY_DEBUGGER
+    uint arenaindex_temp;
+#endif
+
+    if (p == NULL)
+        return PyObject_Malloc(nbytes);
+
+    /*
+     * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
+     * Most python internals blindly use a signed Py_ssize_t to track
+     * things without checking for overflows or negatives.
+     * As size_t is unsigned, checking for nbytes < 0 is not required.
+     */
+    if (nbytes > PY_SSIZE_T_MAX)
+        return NULL;
+
+#ifdef WITH_VALGRIND
+    /* Treat running_on_valgrind == -1 the same as 0 */
+    if (UNLIKELY(running_on_valgrind > 0))
+        goto redirect;
+#endif
+
+    pool = POOL_ADDR(p);
+    if (Py_ADDRESS_IN_RANGE(p, pool)) {
+        /* We're in charge of this block */
+        size = INDEX2SIZE(pool->szidx);
+        if (nbytes <= size) {
+            /* The block is staying the same or shrinking.  If
+             * it's shrinking, there's a tradeoff:  it costs
+             * cycles to copy the block to a smaller size class,
+             * but it wastes memory not to copy it.  The
+             * compromise here is to copy on shrink only if at
+             * least 25% of size can be shaved off.
+             */
+            if (4 * nbytes > 3 * size) {
+                /* It's the same,
+                 * or shrinking and new/old > 3/4.
+                 */
+                return p;
+            }
+            size = nbytes;
+        }
+        bp = PyObject_Malloc(nbytes);
+        if (bp != NULL) {
+            memcpy(bp, p, size);
+            PyObject_Free(p);
+        }
+        return bp;
+    }
+#ifdef WITH_VALGRIND
+ redirect:
+#endif
+    /* We're not managing this block.  If nbytes <=
+     * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this
+     * block.  However, if we do, we need to copy the valid data from
+     * the C-managed block to one of our blocks, and there's no portable
+     * way to know how much of the memory space starting at p is valid.
+     * As bug 1185883 pointed out the hard way, it's possible that the
+     * C-managed block is "at the end" of allocated VM space, so that
+     * a memory fault can occur if we try to copy nbytes bytes starting
+     * at p.  Instead we punt:  let C continue to manage this block.
+     */
+    if (nbytes)
+        return realloc(p, nbytes);
+    /* C doesn't define the result of realloc(p, 0) (it may or may not
+     * return NULL then), but Python's docs promise that nbytes==0 never
+     * returns NULL.  We don't pass 0 to realloc(), to avoid that endcase
+     * to begin with.  Even then, we can't be sure that realloc() won't
+     * return NULL.
+     */
+    bp = realloc(p, 1);
+    return bp ? bp : p;
+}
+
+#else   /* ! WITH_PYMALLOC */
+
+/*==========================================================================*/
+/* pymalloc not enabled:  Redirect the entry points to malloc.  These will
+ * only be used by extensions that are compiled with pymalloc enabled. */
+
+void *
+PyObject_Malloc(size_t n)
+{
+    return PyMem_MALLOC(n);
+}
+
+void *
+PyObject_Realloc(void *p, size_t n)
+{
+    return PyMem_REALLOC(p, n);
+}
+
+void
+PyObject_Free(void *p)
+{
+    PyMem_FREE(p);
+}
+#endif /* WITH_PYMALLOC */
+
+#ifdef PYMALLOC_DEBUG
+/*==========================================================================*/
+/* A x-platform debugging allocator.  This doesn't manage memory directly,
+ * it wraps a real allocator, adding extra debugging info to the memory blocks.
+ */
+
+/* Special bytes broadcast into debug memory blocks at appropriate times.
+ * Strings of these are unlikely to be valid addresses, floats, ints or
+ * 7-bit ASCII.
+ */
+#undef CLEANBYTE
+#undef DEADBYTE
+#undef FORBIDDENBYTE
+#define CLEANBYTE      0xCB    /* clean (newly allocated) memory */
+#define DEADBYTE       0xDB    /* dead (newly freed) memory */
+#define FORBIDDENBYTE  0xFB    /* untouchable bytes at each end of a block */
+
+/* We tag each block with an API ID in order to tag API violations */
+#define _PYMALLOC_MEM_ID 'm'   /* the PyMem_Malloc() API */
+#define _PYMALLOC_OBJ_ID 'o'   /* The PyObject_Malloc() API */
+
+static size_t serialno = 0;     /* incremented on each debug {m,re}alloc */
+
+/* serialno is always incremented via calling this routine.  The point is
+ * to supply a single place to set a breakpoint.
+ */
+static void
+bumpserialno(void)
+{
+    ++serialno;
+}
+
+#define SST SIZEOF_SIZE_T
+
+/* Read sizeof(size_t) bytes at p as a big-endian size_t. */
+static size_t
+read_size_t(const void *p)
+{
+    const uchar *q = (const uchar *)p;
+    size_t result = *q++;
+    int i;
+
+    for (i = SST; --i > 0; ++q)
+        result = (result << 8) | *q;
+    return result;
+}
+
+/* Write n as a big-endian size_t, MSB at address p, LSB at
+ * p + sizeof(size_t) - 1.
+ */
+static void
+write_size_t(void *p, size_t n)
+{
+    uchar *q = (uchar *)p + SST - 1;
+    int i;
+
+    for (i = SST; --i >= 0; --q) {
+        *q = (uchar)(n & 0xff);
+        n >>= 8;
+    }
+}
+
+#ifdef Py_DEBUG
+/* Is target in the list?  The list is traversed via the nextpool pointers.
+ * The list may be NULL-terminated, or circular.  Return 1 if target is in
+ * list, else 0.
+ */
+static int
+pool_is_in_list(const poolp target, poolp list)
+{
+    poolp origlist = list;
+    assert(target != NULL);
+    if (list == NULL)
+        return 0;
+    do {
+        if (target == list)
+            return 1;
+        list = list->nextpool;
+    } while (list != NULL && list != origlist);
+    return 0;
+}
+
+#else
+#define pool_is_in_list(X, Y) 1
+
+#endif  /* Py_DEBUG */
+
+/* Let S = sizeof(size_t).  The debug malloc asks for 4*S extra bytes and
+   fills them with useful stuff, here calling the underlying malloc's result p:
+
+p[0: S]
+    Number of bytes originally asked for.  This is a size_t, big-endian (easier
+    to read in a memory dump).
+p[S: 2*S]
+    Copies of FORBIDDENBYTE.  Used to catch under- writes and reads.
+p[2*S: 2*S+n]
+    The requested memory, filled with copies of CLEANBYTE.
+    Used to catch reference to uninitialized memory.
+    &p[2*S] is returned.  Note that this is 8-byte aligned if pymalloc
+    handled the request itself.
+p[2*S+n: 2*S+n+S]
+    Copies of FORBIDDENBYTE.  Used to catch over- writes and reads.
+p[2*S+n+S: 2*S+n+2*S]
+    A serial number, incremented by 1 on each call to _PyObject_DebugMalloc
+    and _PyObject_DebugRealloc.
+    This is a big-endian size_t.
+    If "bad memory" is detected later, the serial number gives an
+    excellent way to set a breakpoint on the next run, to capture the
+    instant at which this block was passed out.
+*/
+
+/* debug replacements for the PyMem_* memory API */
+void *
+_PyMem_DebugMalloc(size_t nbytes)
+{
+    return _PyObject_DebugMallocApi(_PYMALLOC_MEM_ID, nbytes);
+}
+void *
+_PyMem_DebugRealloc(void *p, size_t nbytes)
+{
+    return _PyObject_DebugReallocApi(_PYMALLOC_MEM_ID, p, nbytes);
+}
+void
+_PyMem_DebugFree(void *p)
+{
+    _PyObject_DebugFreeApi(_PYMALLOC_MEM_ID, p);
+}
+
+/* debug replacements for the PyObject_* memory API */
+void *
+_PyObject_DebugMalloc(size_t nbytes)
+{
+    return _PyObject_DebugMallocApi(_PYMALLOC_OBJ_ID, nbytes);
+}
+void *
+_PyObject_DebugRealloc(void *p, size_t nbytes)
+{
+    return _PyObject_DebugReallocApi(_PYMALLOC_OBJ_ID, p, nbytes);
+}
+void
+_PyObject_DebugFree(void *p)
+{
+    _PyObject_DebugFreeApi(_PYMALLOC_OBJ_ID, p);
+}
+void
+_PyObject_DebugCheckAddress(const void *p)
+{
+    _PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p);
+}
+
+
+/* generic debug memory api, with an "id" to identify the API in use */
+void *
+_PyObject_DebugMallocApi(char id, size_t nbytes)
+{
+    uchar *p;           /* base address of malloc'ed block */
+    uchar *tail;        /* p + 2*SST + nbytes == pointer to tail pad bytes */
+    size_t total;       /* nbytes + 4*SST */
+
+    bumpserialno();
+    total = nbytes + 4*SST;
+    if (total < nbytes)
+        /* overflow:  can't represent total as a size_t */
+        return NULL;
+
+    p = (uchar *)PyObject_Malloc(total);
+    if (p == NULL)
+        return NULL;
+
+    /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */
+    write_size_t(p, nbytes);
+    p[SST] = (uchar)id;
+    memset(p + SST + 1 , FORBIDDENBYTE, SST-1);
+
+    if (nbytes > 0)
+        memset(p + 2*SST, CLEANBYTE, nbytes);
+
+    /* at tail, write pad (SST bytes) and serialno (SST bytes) */
+    tail = p + 2*SST + nbytes;
+    memset(tail, FORBIDDENBYTE, SST);
+    write_size_t(tail + SST, serialno);
+
+    return p + 2*SST;
+}
+
+/* The debug free first checks the 2*SST bytes on each end for sanity (in
+   particular, that the FORBIDDENBYTEs with the api ID are still intact).
+   Then fills the original bytes with DEADBYTE.
+   Then calls the underlying free.
+*/
+void
+_PyObject_DebugFreeApi(char api, void *p)
+{
+    uchar *q = (uchar *)p - 2*SST;  /* address returned from malloc */
+    size_t nbytes;
+
+    if (p == NULL)
+        return;
+    _PyObject_DebugCheckAddressApi(api, p);
+    nbytes = read_size_t(q);
+    nbytes += 4*SST;
+    if (nbytes > 0)
+        memset(q, DEADBYTE, nbytes);
+    PyObject_Free(q);
+}
+
+void *
+_PyObject_DebugReallocApi(char api, void *p, size_t nbytes)
+{
+    uchar *q = (uchar *)p;
+    uchar *tail;
+    size_t total;       /* nbytes + 4*SST */
+    size_t original_nbytes;
+    int i;
+
+    if (p == NULL)
+        return _PyObject_DebugMallocApi(api, nbytes);
+
+    _PyObject_DebugCheckAddressApi(api, p);
+    bumpserialno();
+    original_nbytes = read_size_t(q - 2*SST);
+    total = nbytes + 4*SST;
+    if (total < nbytes)
+        /* overflow:  can't represent total as a size_t */
+        return NULL;
+
+    if (nbytes < original_nbytes) {
+        /* shrinking:  mark old extra memory dead */
+        memset(q + nbytes, DEADBYTE, original_nbytes - nbytes + 2*SST);
+    }
+
+    /* Resize and add decorations. We may get a new pointer here, in which
+     * case we didn't get the chance to mark the old memory with DEADBYTE,
+     * but we live with that.
+     */
+    q = (uchar *)PyObject_Realloc(q - 2*SST, total);
+    if (q == NULL)
+        return NULL;
+
+    write_size_t(q, nbytes);
+    assert(q[SST] == (uchar)api);
+    for (i = 1; i < SST; ++i)
+        assert(q[SST + i] == FORBIDDENBYTE);
+    q += 2*SST;
+    tail = q + nbytes;
+    memset(tail, FORBIDDENBYTE, SST);
+    write_size_t(tail + SST, serialno);
+
+    if (nbytes > original_nbytes) {
+        /* growing:  mark new extra memory clean */
+        memset(q + original_nbytes, CLEANBYTE,
+               nbytes - original_nbytes);
+    }
+
+    return q;
+}
+
+/* Check the forbidden bytes on both ends of the memory allocated for p.
+ * If anything is wrong, print info to stderr via _PyObject_DebugDumpAddress,
+ * and call Py_FatalError to kill the program.
+ * The API id, is also checked.
+ */
+ void
+_PyObject_DebugCheckAddressApi(char api, const void *p)
+{
+    const uchar *q = (const uchar *)p;
+    char msgbuf[64];
+    char *msg;
+    size_t nbytes;
+    const uchar *tail;
+    int i;
+    char id;
+
+    if (p == NULL) {
+        msg = "didn't expect a NULL pointer";
+        goto error;
+    }
+
+    /* Check the API id */
+    id = (char)q[-SST];
+    if (id != api) {
+        msg = msgbuf;
+        snprintf(msg, sizeof(msgbuf), "bad ID: Allocated using API '%c', verified using API '%c'", id, api);
+        msgbuf[sizeof(msgbuf)-1] = 0;
+        goto error;
+    }
+
+    /* Check the stuff at the start of p first:  if there's underwrite
+     * corruption, the number-of-bytes field may be nuts, and checking
+     * the tail could lead to a segfault then.
+     */
+    for (i = SST-1; i >= 1; --i) {
+        if (*(q-i) != FORBIDDENBYTE) {
+            msg = "bad leading pad byte";
+            goto error;
+        }
+    }
+
+    nbytes = read_size_t(q - 2*SST);
+    tail = q + nbytes;
+    for (i = 0; i < SST; ++i) {
+        if (tail[i] != FORBIDDENBYTE) {
+            msg = "bad trailing pad byte";
+            goto error;
+        }
+    }
+
+    return;
+
+error:
+    _PyObject_DebugDumpAddress(p);
+    Py_FatalError(msg);
+}
+
+/* Display info to stderr about the memory block at p. */
+void
+_PyObject_DebugDumpAddress(const void *p)
+{
+    const uchar *q = (const uchar *)p;
+    const uchar *tail;
+    size_t nbytes, serial;
+    int i;
+    int ok;
+    char id;
+
+    fprintf(stderr, "Debug memory block at address p=%p:", p);
+    if (p == NULL) {
+        fprintf(stderr, "\n");
+        return;
+    }
+    id = (char)q[-SST];
+    fprintf(stderr, " API '%c'\n", id);
+
+    nbytes = read_size_t(q - 2*SST);
+    fprintf(stderr, "    %" PY_FORMAT_SIZE_T "u bytes originally "
+                    "requested\n", nbytes);
+
+    /* In case this is nuts, check the leading pad bytes first. */
+    fprintf(stderr, "    The %d pad bytes at p-%d are ", SST-1, SST-1);
+    ok = 1;
+    for (i = 1; i <= SST-1; ++i) {
+        if (*(q-i) != FORBIDDENBYTE) {
+            ok = 0;
+            break;
+        }
+    }
+    if (ok)
+        fputs("FORBIDDENBYTE, as expected.\n", stderr);
+    else {
+        fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
+            FORBIDDENBYTE);
+        for (i = SST-1; i >= 1; --i) {
+            const uchar byte = *(q-i);
+            fprintf(stderr, "        at p-%d: 0x%02x", i, byte);
+            if (byte != FORBIDDENBYTE)
+                fputs(" *** OUCH", stderr);
+            fputc('\n', stderr);
+        }
+
+        fputs("    Because memory is corrupted at the start, the "
+              "count of bytes requested\n"
+              "       may be bogus, and checking the trailing pad "
+              "bytes may segfault.\n", stderr);
+    }
+
+    tail = q + nbytes;
+    fprintf(stderr, "    The %d pad bytes at tail=%p are ", SST, tail);
+    ok = 1;
+    for (i = 0; i < SST; ++i) {
+        if (tail[i] != FORBIDDENBYTE) {
+            ok = 0;
+            break;
+        }
+    }
+    if (ok)
+        fputs("FORBIDDENBYTE, as expected.\n", stderr);
+    else {
+        fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
+                FORBIDDENBYTE);
+        for (i = 0; i < SST; ++i) {
+            const uchar byte = tail[i];
+            fprintf(stderr, "        at tail+%d: 0x%02x",
+                    i, byte);
+            if (byte != FORBIDDENBYTE)
+                fputs(" *** OUCH", stderr);
+            fputc('\n', stderr);
+        }
+    }
+
+    serial = read_size_t(tail + SST);
+    fprintf(stderr, "    The block was made by call #%" PY_FORMAT_SIZE_T
+                    "u to debug malloc/realloc.\n", serial);
+
+    if (nbytes > 0) {
+        i = 0;
+        fputs("    Data at p:", stderr);
+        /* print up to 8 bytes at the start */
+        while (q < tail && i < 8) {
+            fprintf(stderr, " %02x", *q);
+            ++i;
+            ++q;
+        }
+        /* and up to 8 at the end */
+        if (q < tail) {
+            if (tail - q > 8) {
+                fputs(" ...", stderr);
+                q = tail - 8;
+            }
+            while (q < tail) {
+                fprintf(stderr, " %02x", *q);
+                ++q;
+            }
+        }
+        fputc('\n', stderr);
+    }
+}
+
+static size_t
+printone(const char* msg, size_t value)
+{
+    int i, k;
+    char buf[100];
+    size_t origvalue = value;
+
+    fputs(msg, stderr);
+    for (i = (int)strlen(msg); i < 35; ++i)
+        fputc(' ', stderr);
+    fputc('=', stderr);
+
+    /* Write the value with commas. */
+    i = 22;
+    buf[i--] = '\0';
+    buf[i--] = '\n';
+    k = 3;
+    do {
+        size_t nextvalue = value / 10;
+        unsigned int digit = (unsigned int)(value - nextvalue * 10);
+        value = nextvalue;
+        buf[i--] = (char)(digit + '0');
+        --k;
+        if (k == 0 && value && i >= 0) {
+            k = 3;
+            buf[i--] = ',';
+        }
+    } while (value && i >= 0);
+
+    while (i >= 0)
+        buf[i--] = ' ';
+    fputs(buf, stderr);
+
+    return origvalue;
+}
+
+/* Print summary info to stderr about the state of pymalloc's structures.
+ * In Py_DEBUG mode, also perform some expensive internal consistency
+ * checks.
+ */
+void
+_PyObject_DebugMallocStats(void)
+{
+    uint i;
+    const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
+    /* # of pools, allocated blocks, and free blocks per class index */
+    size_t numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+    size_t numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+    size_t numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+    /* total # of allocated bytes in used and full pools */
+    size_t allocated_bytes = 0;
+    /* total # of available bytes in used pools */
+    size_t available_bytes = 0;
+    /* # of free pools + pools not yet carved out of current arena */
+    uint numfreepools = 0;
+    /* # of bytes for arena alignment padding */
+    size_t arena_alignment = 0;
+    /* # of bytes in used and full pools used for pool_headers */
+    size_t pool_header_bytes = 0;
+    /* # of bytes in used and full pools wasted due to quantization,
+     * i.e. the necessarily leftover space at the ends of used and
+     * full pools.
+     */
+    size_t quantization = 0;
+    /* # of arenas actually allocated. */
+    size_t narenas = 0;
+    /* running total -- should equal narenas * ARENA_SIZE */
+    size_t total;
+    char buf[128];
+
+    fprintf(stderr, "Small block threshold = %d, in %u size classes.\n",
+            SMALL_REQUEST_THRESHOLD, numclasses);
+
+    for (i = 0; i < numclasses; ++i)
+        numpools[i] = numblocks[i] = numfreeblocks[i] = 0;
+
+    /* Because full pools aren't linked to from anything, it's easiest
+     * to march over all the arenas.  If we're lucky, most of the memory
+     * will be living in full pools -- would be a shame to miss them.
+     */
+    for (i = 0; i < maxarenas; ++i) {
+        uint j;
+        uptr base = arenas[i].address;
+
+        /* Skip arenas which are not allocated. */
+        if (arenas[i].address == (uptr)NULL)
+            continue;
+        narenas += 1;
+
+        numfreepools += arenas[i].nfreepools;
+
+        /* round up to pool alignment */
+        if (base & (uptr)POOL_SIZE_MASK) {
+            arena_alignment += POOL_SIZE;
+            base &= ~(uptr)POOL_SIZE_MASK;
+            base += POOL_SIZE;
+        }
+
+        /* visit every pool in the arena */
+        assert(base <= (uptr) arenas[i].pool_address);
+        for (j = 0;
+                    base < (uptr) arenas[i].pool_address;
+                    ++j, base += POOL_SIZE) {
+            poolp p = (poolp)base;
+            const uint sz = p->szidx;
+            uint freeblocks;
+
+            if (p->ref.count == 0) {
+                /* currently unused */
+                assert(pool_is_in_list(p, arenas[i].freepools));
+                continue;
+            }
+            ++numpools[sz];
+            numblocks[sz] += p->ref.count;
+            freeblocks = NUMBLOCKS(sz) - p->ref.count;
+            numfreeblocks[sz] += freeblocks;
+#ifdef Py_DEBUG
+            if (freeblocks > 0)
+                assert(pool_is_in_list(p, usedpools[sz + sz]));
+#endif
+        }
+    }
+    assert(narenas == narenas_currently_allocated);
+
+    fputc('\n', stderr);
+    fputs("class   size   num pools   blocks in use  avail blocks\n"
+          "-----   ----   ---------   -------------  ------------\n",
+          stderr);
+
+    for (i = 0; i < numclasses; ++i) {
+        size_t p = numpools[i];
+        size_t b = numblocks[i];
+        size_t f = numfreeblocks[i];
+        uint size = INDEX2SIZE(i);
+        if (p == 0) {
+            assert(b == 0 && f == 0);
+            continue;
+        }
+        fprintf(stderr, "%5u %6u "
+                        "%11" PY_FORMAT_SIZE_T "u "
+                        "%15" PY_FORMAT_SIZE_T "u "
+                        "%13" PY_FORMAT_SIZE_T "u\n",
+                i, size, p, b, f);
+        allocated_bytes += b * size;
+        available_bytes += f * size;
+        pool_header_bytes += p * POOL_OVERHEAD;
+        quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
+    }
+    fputc('\n', stderr);
+    (void)printone("# times object malloc called", serialno);
+
+    (void)printone("# arenas allocated total", ntimes_arena_allocated);
+    (void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas);
+    (void)printone("# arenas highwater mark", narenas_highwater);
+    (void)printone("# arenas allocated current", narenas);
+
+    PyOS_snprintf(buf, sizeof(buf),
+        "%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena",
+        narenas, ARENA_SIZE);
+    (void)printone(buf, narenas * ARENA_SIZE);
+
+    fputc('\n', stderr);
+
+    total = printone("# bytes in allocated blocks", allocated_bytes);
+    total += printone("# bytes in available blocks", available_bytes);
+
+    PyOS_snprintf(buf, sizeof(buf),
+        "%u unused pools * %d bytes", numfreepools, POOL_SIZE);
+    total += printone(buf, (size_t)numfreepools * POOL_SIZE);
+
+    total += printone("# bytes lost to pool headers", pool_header_bytes);
+    total += printone("# bytes lost to quantization", quantization);
+    total += printone("# bytes lost to arena alignment", arena_alignment);
+    (void)printone("Total", total);
+}
+
+#endif  /* PYMALLOC_DEBUG */
+
+#ifdef Py_USING_MEMORY_DEBUGGER
+/* Make this function last so gcc won't inline it since the definition is
+ * after the reference.
+ */
+int
+Py_ADDRESS_IN_RANGE(void *P, poolp pool)
+{
+    uint arenaindex_temp = pool->arenaindex;
+
+    return arenaindex_temp < maxarenas &&
+           (uptr)P - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE &&
+           arenas[arenaindex_temp].address != 0;
+}
+#endif
diff --git a/Python-2.7.5/Objects/rangeobject.c b/Python-2.7.5/Objects/rangeobject.c
new file mode 100644
index 0000000..5203f40
--- /dev/null
+++ b/Python-2.7.5/Objects/rangeobject.c
@@ -0,0 +1,347 @@
+/* Range object implementation */
+
+#include "Python.h"
+
+typedef struct {
+    PyObject_HEAD
+    long        start;
+    long        step;
+    long        len;
+} rangeobject;
+
+/* Return number of items in range (lo, hi, step).  step != 0
+ * required.  The result always fits in an unsigned long.
+ */
+static unsigned long
+get_len_of_range(long lo, long hi, long step)
+{
+    /* -------------------------------------------------------------
+    If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
+    Else for step > 0, if n values are in the range, the last one is
+    lo + (n-1)*step, which must be <= hi-1.  Rearranging,
+    n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
+    the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
+    the RHS is non-negative and so truncation is the same as the
+    floor.  Letting M be the largest positive long, the worst case
+    for the RHS numerator is hi=M, lo=-M-1, and then
+    hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
+    precision to compute the RHS exactly.  The analysis for step < 0
+    is similar.
+    ---------------------------------------------------------------*/
+    assert(step != 0);
+    if (step > 0 && lo < hi)
+    return 1UL + (hi - 1UL - lo) / step;
+    else if (step < 0 && lo > hi)
+    return 1UL + (lo - 1UL - hi) / (0UL - step);
+    else
+    return 0UL;
+}
+
+/* Return a stop value suitable for reconstructing the xrange from
+ * a (start, stop, step) triple.  Used in range_repr and range_reduce.
+ * Computes start + len * step, clipped to the range [LONG_MIN, LONG_MAX].
+ */
+static long
+get_stop_for_range(rangeobject *r)
+{
+    long last;
+
+    if (r->len == 0)
+        return r->start;
+
+    /* The tricky bit is avoiding overflow.  We first compute the last entry in
+       the xrange, start + (len - 1) * step, which is guaranteed to lie within
+       the range of a long, and then add step to it.  See the range_reverse
+       comments for an explanation of the casts below.
+    */
+    last = (long)(r->start + (unsigned long)(r->len - 1) * r->step);
+    if (r->step > 0)
+        return last > LONG_MAX - r->step ? LONG_MAX : last + r->step;
+    else
+        return last < LONG_MIN - r->step ? LONG_MIN : last + r->step;
+}
+
+static PyObject *
+range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+    rangeobject *obj;
+    long ilow = 0, ihigh = 0, istep = 1;
+    unsigned long n;
+
+    if (!_PyArg_NoKeywords("xrange()", kw))
+        return NULL;
+
+    if (PyTuple_Size(args) <= 1) {
+        if (!PyArg_ParseTuple(args,
+                        "l;xrange() requires 1-3 int arguments",
+                        &ihigh))
+            return NULL;
+    }
+    else {
+        if (!PyArg_ParseTuple(args,
+                        "ll|l;xrange() requires 1-3 int arguments",
+                        &ilow, &ihigh, &istep))
+            return NULL;
+    }
+    if (istep == 0) {
+        PyErr_SetString(PyExc_ValueError, "xrange() arg 3 must not be zero");
+        return NULL;
+    }
+    n = get_len_of_range(ilow, ihigh, istep);
+    if (n > (unsigned long)LONG_MAX || (long)n > PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "xrange() result has too many items");
+        return NULL;
+    }
+
+    obj = PyObject_New(rangeobject, &PyRange_Type);
+    if (obj == NULL)
+        return NULL;
+    obj->start = ilow;
+    obj->len   = (long)n;
+    obj->step  = istep;
+    return (PyObject *) obj;
+}
+
+PyDoc_STRVAR(range_doc,
+"xrange(stop) -> xrange object\n\
+xrange(start, stop[, step]) -> xrange object\n\
+\n\
+Like range(), but instead of returning a list, returns an object that\n\
+generates the numbers in the range on demand.  For looping, this is \n\
+slightly faster than range() and more memory efficient.");
+
+static PyObject *
+range_item(rangeobject *r, Py_ssize_t i)
+{
+    if (i < 0 || i >= r->len) {
+        PyErr_SetString(PyExc_IndexError,
+                        "xrange object index out of range");
+        return NULL;
+    }
+    /* do calculation entirely using unsigned longs, to avoid
+       undefined behaviour due to signed overflow. */
+    return PyInt_FromLong((long)(r->start + (unsigned long)i * r->step));
+}
+
+static Py_ssize_t
+range_length(rangeobject *r)
+{
+    return (Py_ssize_t)(r->len);
+}
+
+static PyObject *
+range_repr(rangeobject *r)
+{
+    PyObject *rtn;
+
+    if (r->start == 0 && r->step == 1)
+        rtn = PyString_FromFormat("xrange(%ld)",
+                                  get_stop_for_range(r));
+
+    else if (r->step == 1)
+        rtn = PyString_FromFormat("xrange(%ld, %ld)",
+                                  r->start,
+                                  get_stop_for_range(r));
+
+    else
+        rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
+                                  r->start,
+                                  get_stop_for_range(r),
+                                  r->step);
+    return rtn;
+}
+
+/* Pickling support */
+static PyObject *
+range_reduce(rangeobject *r, PyObject *args)
+{
+    return Py_BuildValue("(O(lll))", Py_TYPE(r),
+                         r->start,
+                         get_stop_for_range(r),
+                         r->step);
+}
+
+static PySequenceMethods range_as_sequence = {
+    (lenfunc)range_length,      /* sq_length */
+    0,                          /* sq_concat */
+    0,                          /* sq_repeat */
+    (ssizeargfunc)range_item, /* sq_item */
+    0,                          /* sq_slice */
+};
+
+static PyObject * range_iter(PyObject *seq);
+static PyObject * range_reverse(PyObject *seq);
+
+PyDoc_STRVAR(reverse_doc,
+"Returns a reverse iterator.");
+
+static PyMethodDef range_methods[] = {
+    {"__reversed__",            (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
+    {"__reduce__",              (PyCFunction)range_reduce, METH_VARARGS},
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyRange_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                          /* Number of items for varobject */
+    "xrange",                   /* Name of this type */
+    sizeof(rangeobject),        /* Basic object size */
+    0,                          /* Item size for varobject */
+    (destructor)PyObject_Del, /* tp_dealloc */
+    0,                          /* tp_print */
+    0,                          /* tp_getattr */
+    0,                          /* tp_setattr */
+    0,                          /* tp_compare */
+    (reprfunc)range_repr,       /* tp_repr */
+    0,                          /* tp_as_number */
+    &range_as_sequence,         /* tp_as_sequence */
+    0,                          /* tp_as_mapping */
+    0,                          /* tp_hash */
+    0,                          /* tp_call */
+    0,                          /* tp_str */
+    PyObject_GenericGetAttr,  /* tp_getattro */
+    0,                          /* tp_setattro */
+    0,                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,         /* tp_flags */
+    range_doc,                  /* tp_doc */
+    0,                          /* tp_traverse */
+    0,                          /* tp_clear */
+    0,                          /* tp_richcompare */
+    0,                          /* tp_weaklistoffset */
+    range_iter,                 /* tp_iter */
+    0,                          /* tp_iternext */
+    range_methods,              /* tp_methods */
+    0,                          /* tp_members */
+    0,                          /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    0,                          /* tp_dictoffset */
+    0,                          /* tp_init */
+    0,                          /* tp_alloc */
+    range_new,                  /* tp_new */
+};
+
+/*********************** Xrange Iterator **************************/
+
+typedef struct {
+    PyObject_HEAD
+    long        index;
+    long        start;
+    long        step;
+    long        len;
+} rangeiterobject;
+
+static PyObject *
+rangeiter_next(rangeiterobject *r)
+{
+    if (r->index < r->len)
+        return PyInt_FromLong(r->start + (r->index++) * r->step);
+    return NULL;
+}
+
+static PyObject *
+rangeiter_len(rangeiterobject *r)
+{
+    return PyInt_FromLong(r->len - r->index);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef rangeiter_methods[] = {
+    {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyTypeObject Pyrangeiter_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                                      /* ob_size */
+    "rangeiterator",                        /* tp_name */
+    sizeof(rangeiterobject),                /* tp_basicsize */
+    0,                                      /* tp_itemsize */
+    /* methods */
+    (destructor)PyObject_Del,                   /* 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 */
+    0,                                      /* tp_str */
+    PyObject_GenericGetAttr,                /* tp_getattro */
+    0,                                      /* tp_setattro */
+    0,                                      /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    0,                                      /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                      /* tp_clear */
+    0,                                      /* tp_richcompare */
+    0,                                      /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)rangeiter_next,               /* tp_iternext */
+    rangeiter_methods,                          /* tp_methods */
+    0,
+};
+
+static PyObject *
+range_iter(PyObject *seq)
+{
+    rangeiterobject *it;
+
+    if (!PyRange_Check(seq)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+    if (it == NULL)
+        return NULL;
+    it->index = 0;
+    it->start = ((rangeobject *)seq)->start;
+    it->step = ((rangeobject *)seq)->step;
+    it->len = ((rangeobject *)seq)->len;
+    return (PyObject *)it;
+}
+
+static PyObject *
+range_reverse(PyObject *seq)
+{
+    rangeiterobject *it;
+    long start, step, len;
+
+    if (!PyRange_Check(seq)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+    if (it == NULL)
+        return NULL;
+
+    start = ((rangeobject *)seq)->start;
+    step = ((rangeobject *)seq)->step;
+    len = ((rangeobject *)seq)->len;
+
+    it->index = 0;
+    it->len = len;
+    /* the casts below guard against signed overflow by turning it
+       into unsigned overflow instead.  The correctness of this
+       code still depends on conversion from unsigned long to long
+       wrapping modulo ULONG_MAX+1, which isn't guaranteed (see
+       C99 6.3.1.3p3) but seems to hold in practice for all
+       platforms we're likely to meet.
+
+       If step == LONG_MIN then we still end up with LONG_MIN
+       after negation; but this works out, since we've still got
+       the correct value modulo ULONG_MAX+1, and the range_item
+       calculation is also done modulo ULONG_MAX+1.
+    */
+    it->start = (long)(start + (unsigned long)(len-1) * step);
+    it->step = (long)(0UL-step);
+
+    return (PyObject *)it;
+}
diff --git a/Python-2.7.5/Objects/setobject.c b/Python-2.7.5/Objects/setobject.c
new file mode 100644
index 0000000..af1ce16
--- /dev/null
+++ b/Python-2.7.5/Objects/setobject.c
@@ -0,0 +1,2519 @@
+
+/* set object implementation
+   Written and maintained by Raymond D. Hettinger <[email protected]>
+   Derived from Lib/sets.py and Objects/dictobject.c.
+
+   Copyright (c) 2003-2007 Python Software Foundation.
+   All rights reserved.
+*/
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+    PyObject *tup;
+    tup = PyTuple_Pack(1, arg);
+    if (!tup)
+        return; /* caller will expect error to be set anyway */
+    PyErr_SetObject(PyExc_KeyError, tup);
+    Py_DECREF(tup);
+}
+
+/* This must be >= 1. */
+#define PERTURB_SHIFT 5
+
+/* Object used as dummy key to fill deleted entries */
+static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */
+
+#ifdef Py_REF_DEBUG
+PyObject *
+_PySet_Dummy(void)
+{
+    return dummy;
+}
+#endif
+
+#define INIT_NONZERO_SET_SLOTS(so) do {                         \
+    (so)->table = (so)->smalltable;                             \
+    (so)->mask = PySet_MINSIZE - 1;                             \
+    (so)->hash = -1;                                            \
+    } while(0)
+
+#define EMPTY_TO_MINSIZE(so) do {                               \
+    memset((so)->smalltable, 0, sizeof((so)->smalltable));      \
+    (so)->used = (so)->fill = 0;                                \
+    INIT_NONZERO_SET_SLOTS(so);                                 \
+    } while(0)
+
+/* Reuse scheme to save calls to malloc, free, and memset */
+#ifndef PySet_MAXFREELIST
+#define PySet_MAXFREELIST 80
+#endif
+static PySetObject *free_list[PySet_MAXFREELIST];
+static int numfree = 0;
+
+/*
+The basic lookup function used by all operations.
+This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
+Open addressing is preferred over chaining since the link overhead for
+chaining would be substantial (100% with typical malloc overhead).
+
+The initial probe index is computed as hash mod the table size. Subsequent
+probe indices are computed as explained in Objects/dictobject.c.
+
+All arithmetic on hash should ignore overflow.
+
+Unlike the dictionary implementation, the lookkey functions can return
+NULL if the rich comparison returns an error.
+*/
+
+static setentry *
+set_lookkey(PySetObject *so, PyObject *key, register long hash)
+{
+    register Py_ssize_t i;
+    register size_t perturb;
+    register setentry *freeslot;
+    register size_t mask = so->mask;
+    setentry *table = so->table;
+    register setentry *entry;
+    register int cmp;
+    PyObject *startkey;
+
+    i = hash & mask;
+    entry = &table[i];
+    if (entry->key == NULL || entry->key == key)
+        return entry;
+
+    if (entry->key == dummy)
+        freeslot = entry;
+    else {
+        if (entry->hash == hash) {
+            startkey = entry->key;
+            Py_INCREF(startkey);
+            cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+            Py_DECREF(startkey);
+            if (cmp < 0)
+                return NULL;
+            if (table == so->table && entry->key == startkey) {
+                if (cmp > 0)
+                    return entry;
+            }
+            else {
+                /* The compare did major nasty stuff to the
+                 * set:  start over.
+                 */
+                return set_lookkey(so, key, hash);
+            }
+        }
+        freeslot = NULL;
+    }
+
+    /* In the loop, key == dummy is by far (factor of 100s) the
+       least likely outcome, so test for that last. */
+    for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+        i = (i << 2) + i + perturb + 1;
+        entry = &table[i & mask];
+        if (entry->key == NULL) {
+            if (freeslot != NULL)
+                entry = freeslot;
+            break;
+        }
+        if (entry->key == key)
+            break;
+        if (entry->hash == hash && entry->key != dummy) {
+            startkey = entry->key;
+            Py_INCREF(startkey);
+            cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+            Py_DECREF(startkey);
+            if (cmp < 0)
+                return NULL;
+            if (table == so->table && entry->key == startkey) {
+                if (cmp > 0)
+                    break;
+            }
+            else {
+                /* The compare did major nasty stuff to the
+                 * set:  start over.
+                 */
+                return set_lookkey(so, key, hash);
+            }
+        }
+        else if (entry->key == dummy && freeslot == NULL)
+            freeslot = entry;
+    }
+    return entry;
+}
+
+/*
+ * Hacked up version of set_lookkey which can assume keys are always strings;
+ * This means we can always use _PyString_Eq directly and not have to check to
+ * see if the comparison altered the table.
+ */
+static setentry *
+set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
+{
+    register Py_ssize_t i;
+    register size_t perturb;
+    register setentry *freeslot;
+    register size_t mask = so->mask;
+    setentry *table = so->table;
+    register setentry *entry;
+
+    /* Make sure this function doesn't have to handle non-string keys,
+       including subclasses of str; e.g., one reason to subclass
+       strings is to override __eq__, and for speed we don't cater to
+       that here. */
+    if (!PyString_CheckExact(key)) {
+        so->lookup = set_lookkey;
+        return set_lookkey(so, key, hash);
+    }
+    i = hash & mask;
+    entry = &table[i];
+    if (entry->key == NULL || entry->key == key)
+        return entry;
+    if (entry->key == dummy)
+        freeslot = entry;
+    else {
+        if (entry->hash == hash && _PyString_Eq(entry->key, key))
+            return entry;
+        freeslot = NULL;
+    }
+
+    /* In the loop, key == dummy is by far (factor of 100s) the
+       least likely outcome, so test for that last. */
+    for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+        i = (i << 2) + i + perturb + 1;
+        entry = &table[i & mask];
+        if (entry->key == NULL)
+            return freeslot == NULL ? entry : freeslot;
+        if (entry->key == key
+            || (entry->hash == hash
+            && entry->key != dummy
+            && _PyString_Eq(entry->key, key)))
+            return entry;
+        if (entry->key == dummy && freeslot == NULL)
+            freeslot = entry;
+    }
+    assert(0);          /* NOT REACHED */
+    return 0;
+}
+
+/*
+Internal routine to insert a new key into the table.
+Used by the public insert routine.
+Eats a reference to key.
+*/
+static int
+set_insert_key(register PySetObject *so, PyObject *key, long hash)
+{
+    register setentry *entry;
+    typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long);
+
+    assert(so->lookup != NULL);
+    entry = so->lookup(so, key, hash);
+    if (entry == NULL)
+        return -1;
+    if (entry->key == NULL) {
+        /* UNUSED */
+        so->fill++;
+        entry->key = key;
+        entry->hash = hash;
+        so->used++;
+    } else if (entry->key == dummy) {
+        /* DUMMY */
+        entry->key = key;
+        entry->hash = hash;
+        so->used++;
+        Py_DECREF(dummy);
+    } else {
+        /* ACTIVE */
+        Py_DECREF(key);
+    }
+    return 0;
+}
+
+/*
+Internal routine used by set_table_resize() to insert an item which is
+known to be absent from the set.  This routine also assumes that
+the set contains no deleted entries.  Besides the performance benefit,
+using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key`.
+*/
+static void
+set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+{
+    register size_t i;
+    register size_t perturb;
+    register size_t mask = (size_t)so->mask;
+    setentry *table = so->table;
+    register setentry *entry;
+
+    i = hash & mask;
+    entry = &table[i];
+    for (perturb = hash; entry->key != NULL; perturb >>= PERTURB_SHIFT) {
+        i = (i << 2) + i + perturb + 1;
+        entry = &table[i & mask];
+    }
+    so->fill++;
+    entry->key = key;
+    entry->hash = hash;
+    so->used++;
+}
+
+/*
+Restructure the table by allocating a new table and reinserting all
+keys again.  When entries have been deleted, the new table may
+actually be smaller than the old one.
+*/
+static int
+set_table_resize(PySetObject *so, Py_ssize_t minused)
+{
+    Py_ssize_t newsize;
+    setentry *oldtable, *newtable, *entry;
+    Py_ssize_t i;
+    int is_oldtable_malloced;
+    setentry small_copy[PySet_MINSIZE];
+
+    assert(minused >= 0);
+
+    /* Find the smallest table size > minused. */
+    for (newsize = PySet_MINSIZE;
+         newsize <= minused && newsize > 0;
+         newsize <<= 1)
+        ;
+    if (newsize <= 0) {
+        PyErr_NoMemory();
+        return -1;
+    }
+
+    /* Get space for a new table. */
+    oldtable = so->table;
+    assert(oldtable != NULL);
+    is_oldtable_malloced = oldtable != so->smalltable;
+
+    if (newsize == PySet_MINSIZE) {
+        /* A large table is shrinking, or we can't get any smaller. */
+        newtable = so->smalltable;
+        if (newtable == oldtable) {
+            if (so->fill == so->used) {
+                /* No dummies, so no point doing anything. */
+                return 0;
+            }
+            /* We're not going to resize it, but rebuild the
+               table anyway to purge old dummy entries.
+               Subtle:  This is *necessary* if fill==size,
+               as set_lookkey needs at least one virgin slot to
+               terminate failing searches.  If fill < size, it's
+               merely desirable, as dummies slow searches. */
+            assert(so->fill > so->used);
+            memcpy(small_copy, oldtable, sizeof(small_copy));
+            oldtable = small_copy;
+        }
+    }
+    else {
+        newtable = PyMem_NEW(setentry, newsize);
+        if (newtable == NULL) {
+            PyErr_NoMemory();
+            return -1;
+        }
+    }
+
+    /* Make the set empty, using the new table. */
+    assert(newtable != oldtable);
+    so->table = newtable;
+    so->mask = newsize - 1;
+    memset(newtable, 0, sizeof(setentry) * newsize);
+    so->used = 0;
+    i = so->fill;
+    so->fill = 0;
+
+    /* Copy the data over; this is refcount-neutral for active entries;
+       dummy entries aren't copied over, of course */
+    for (entry = oldtable; i > 0; entry++) {
+        if (entry->key == NULL) {
+            /* UNUSED */
+            ;
+        } else if (entry->key == dummy) {
+            /* DUMMY */
+            --i;
+            assert(entry->key == dummy);
+            Py_DECREF(entry->key);
+        } else {
+            /* ACTIVE */
+            --i;
+            set_insert_clean(so, entry->key, entry->hash);
+        }
+    }
+
+    if (is_oldtable_malloced)
+        PyMem_DEL(oldtable);
+    return 0;
+}
+
+/* CAUTION: set_add_key/entry() must guarantee it won't resize the table */
+
+static int
+set_add_entry(register PySetObject *so, setentry *entry)
+{
+    register Py_ssize_t n_used;
+    PyObject *key = entry->key;
+    long hash = entry->hash;
+
+    assert(so->fill <= so->mask);  /* at least one empty slot */
+    n_used = so->used;
+    Py_INCREF(key);
+    if (set_insert_key(so, key, hash) == -1) {
+        Py_DECREF(key);
+        return -1;
+    }
+    if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
+        return 0;
+    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+static int
+set_add_key(register PySetObject *so, PyObject *key)
+{
+    register long hash;
+    register Py_ssize_t n_used;
+
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return -1;
+    }
+    assert(so->fill <= so->mask);  /* at least one empty slot */
+    n_used = so->used;
+    Py_INCREF(key);
+    if (set_insert_key(so, key, hash) == -1) {
+        Py_DECREF(key);
+        return -1;
+    }
+    if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
+        return 0;
+    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+#define DISCARD_NOTFOUND 0
+#define DISCARD_FOUND 1
+
+static int
+set_discard_entry(PySetObject *so, setentry *oldentry)
+{       register setentry *entry;
+    PyObject *old_key;
+
+    entry = (so->lookup)(so, oldentry->key, oldentry->hash);
+    if (entry == NULL)
+        return -1;
+    if (entry->key == NULL  ||  entry->key == dummy)
+        return DISCARD_NOTFOUND;
+    old_key = entry->key;
+    Py_INCREF(dummy);
+    entry->key = dummy;
+    so->used--;
+    Py_DECREF(old_key);
+    return DISCARD_FOUND;
+}
+
+static int
+set_discard_key(PySetObject *so, PyObject *key)
+{
+    register long hash;
+    register setentry *entry;
+    PyObject *old_key;
+
+    assert (PyAnySet_Check(so));
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return -1;
+    }
+    entry = (so->lookup)(so, key, hash);
+    if (entry == NULL)
+        return -1;
+    if (entry->key == NULL  ||  entry->key == dummy)
+        return DISCARD_NOTFOUND;
+    old_key = entry->key;
+    Py_INCREF(dummy);
+    entry->key = dummy;
+    so->used--;
+    Py_DECREF(old_key);
+    return DISCARD_FOUND;
+}
+
+static int
+set_clear_internal(PySetObject *so)
+{
+    setentry *entry, *table;
+    int table_is_malloced;
+    Py_ssize_t fill;
+    setentry small_copy[PySet_MINSIZE];
+#ifdef Py_DEBUG
+    Py_ssize_t i, n;
+    assert (PyAnySet_Check(so));
+
+    n = so->mask + 1;
+    i = 0;
+#endif
+
+    table = so->table;
+    assert(table != NULL);
+    table_is_malloced = table != so->smalltable;
+
+    /* This is delicate.  During the process of clearing the set,
+     * decrefs can cause the set to mutate.  To avoid fatal confusion
+     * (voice of experience), we have to make the set empty before
+     * clearing the slots, and never refer to anything via so->ref while
+     * clearing.
+     */
+    fill = so->fill;
+    if (table_is_malloced)
+        EMPTY_TO_MINSIZE(so);
+
+    else if (fill > 0) {
+        /* It's a small table with something that needs to be cleared.
+         * Afraid the only safe way is to copy the set entries into
+         * another small table first.
+         */
+        memcpy(small_copy, table, sizeof(small_copy));
+        table = small_copy;
+        EMPTY_TO_MINSIZE(so);
+    }
+    /* else it's a small table that's already empty */
+
+    /* Now we can finally clear things.  If C had refcounts, we could
+     * assert that the refcount on table is 1 now, i.e. that this function
+     * has unique access to it, so decref side-effects can't alter it.
+     */
+    for (entry = table; fill > 0; ++entry) {
+#ifdef Py_DEBUG
+        assert(i < n);
+        ++i;
+#endif
+        if (entry->key) {
+            --fill;
+            Py_DECREF(entry->key);
+        }
+#ifdef Py_DEBUG
+        else
+            assert(entry->key == NULL);
+#endif
+    }
+
+    if (table_is_malloced)
+        PyMem_DEL(table);
+    return 0;
+}
+
+/*
+ * Iterate over a set table.  Use like so:
+ *
+ *     Py_ssize_t pos;
+ *     setentry *entry;
+ *     pos = 0;   # important!  pos should not otherwise be changed by you
+ *     while (set_next(yourset, &pos, &entry)) {
+ *              Refer to borrowed reference in entry->key.
+ *     }
+ *
+ * CAUTION:  In general, it isn't safe to use set_next in a loop that
+ * mutates the table.
+ */
+static int
+set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
+{
+    Py_ssize_t i;
+    Py_ssize_t mask;
+    register setentry *table;
+
+    assert (PyAnySet_Check(so));
+    i = *pos_ptr;
+    assert(i >= 0);
+    table = so->table;
+    mask = so->mask;
+    while (i <= mask && (table[i].key == NULL || table[i].key == dummy))
+        i++;
+    *pos_ptr = i+1;
+    if (i > mask)
+        return 0;
+    assert(table[i].key != NULL);
+    *entry_ptr = &table[i];
+    return 1;
+}
+
+static void
+set_dealloc(PySetObject *so)
+{
+    register setentry *entry;
+    Py_ssize_t fill = so->fill;
+    PyObject_GC_UnTrack(so);
+    Py_TRASHCAN_SAFE_BEGIN(so)
+    if (so->weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) so);
+
+    for (entry = so->table; fill > 0; entry++) {
+        if (entry->key) {
+            --fill;
+            Py_DECREF(entry->key);
+        }
+    }
+    if (so->table != so->smalltable)
+        PyMem_DEL(so->table);
+    if (numfree < PySet_MAXFREELIST && PyAnySet_CheckExact(so))
+        free_list[numfree++] = so;
+    else
+        Py_TYPE(so)->tp_free(so);
+    Py_TRASHCAN_SAFE_END(so)
+}
+
+static int
+set_tp_print(PySetObject *so, FILE *fp, int flags)
+{
+    setentry *entry;
+    Py_ssize_t pos=0;
+    char *emit = "";            /* No separator emitted on first pass */
+    char *separator = ", ";
+    int status = Py_ReprEnter((PyObject*)so);
+
+    if (status != 0) {
+        if (status < 0)
+            return status;
+        Py_BEGIN_ALLOW_THREADS
+        fprintf(fp, "%s(...)", so->ob_type->tp_name);
+        Py_END_ALLOW_THREADS
+        return 0;
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "%s([", so->ob_type->tp_name);
+    Py_END_ALLOW_THREADS
+    while (set_next(so, &pos, &entry)) {
+        Py_BEGIN_ALLOW_THREADS
+        fputs(emit, fp);
+        Py_END_ALLOW_THREADS
+        emit = separator;
+        if (PyObject_Print(entry->key, fp, 0) != 0) {
+            Py_ReprLeave((PyObject*)so);
+            return -1;
+        }
+    }
+    Py_BEGIN_ALLOW_THREADS
+    fputs("])", fp);
+    Py_END_ALLOW_THREADS
+    Py_ReprLeave((PyObject*)so);
+    return 0;
+}
+
+static PyObject *
+set_repr(PySetObject *so)
+{
+    PyObject *keys, *result=NULL, *listrepr;
+    int status = Py_ReprEnter((PyObject*)so);
+
+    if (status != 0) {
+        if (status < 0)
+            return NULL;
+        return PyString_FromFormat("%s(...)", so->ob_type->tp_name);
+    }
+
+    keys = PySequence_List((PyObject *)so);
+    if (keys == NULL)
+        goto done;
+    listrepr = PyObject_Repr(keys);
+    Py_DECREF(keys);
+    if (listrepr == NULL)
+        goto done;
+
+    result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
+        PyString_AS_STRING(listrepr));
+    Py_DECREF(listrepr);
+done:
+    Py_ReprLeave((PyObject*)so);
+    return result;
+}
+
+static Py_ssize_t
+set_len(PyObject *so)
+{
+    return ((PySetObject *)so)->used;
+}
+
+static int
+set_merge(PySetObject *so, PyObject *otherset)
+{
+    PySetObject *other;
+    PyObject *key;
+    long hash;
+    register Py_ssize_t i;
+    register setentry *entry;
+
+    assert (PyAnySet_Check(so));
+    assert (PyAnySet_Check(otherset));
+
+    other = (PySetObject*)otherset;
+    if (other == so || other->used == 0)
+        /* a.update(a) or a.update({}); nothing to do */
+        return 0;
+    /* Do one big resize at the start, rather than
+     * incrementally resizing as we insert new keys.  Expect
+     * that there will be no (or few) overlapping keys.
+     */
+    if ((so->fill + other->used)*3 >= (so->mask+1)*2) {
+       if (set_table_resize(so, (so->used + other->used)*2) != 0)
+           return -1;
+    }
+    for (i = 0; i <= other->mask; i++) {
+        entry = &other->table[i];
+        key = entry->key;
+        hash = entry->hash;
+        if (key != NULL &&
+            key != dummy) {
+            Py_INCREF(key);
+            if (set_insert_key(so, key, hash) == -1) {
+                Py_DECREF(key);
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+static int
+set_contains_key(PySetObject *so, PyObject *key)
+{
+    long hash;
+    setentry *entry;
+
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+        hash = PyObject_Hash(key);
+        if (hash == -1)
+            return -1;
+    }
+    entry = (so->lookup)(so, key, hash);
+    if (entry == NULL)
+        return -1;
+    key = entry->key;
+    return key != NULL && key != dummy;
+}
+
+static int
+set_contains_entry(PySetObject *so, setentry *entry)
+{
+    PyObject *key;
+    setentry *lu_entry;
+
+    lu_entry = (so->lookup)(so, entry->key, entry->hash);
+    if (lu_entry == NULL)
+        return -1;
+    key = lu_entry->key;
+    return key != NULL && key != dummy;
+}
+
+static PyObject *
+set_pop(PySetObject *so)
+{
+    register Py_ssize_t i = 0;
+    register setentry *entry;
+    PyObject *key;
+
+    assert (PyAnySet_Check(so));
+    if (so->used == 0) {
+        PyErr_SetString(PyExc_KeyError, "pop from an empty set");
+        return NULL;
+    }
+
+    /* Set entry to "the first" unused or dummy set entry.  We abuse
+     * the hash field of slot 0 to hold a search finger:
+     * If slot 0 has a value, use slot 0.
+     * Else slot 0 is being used to hold a search finger,
+     * and we use its hash value as the first index to look.
+     */
+    entry = &so->table[0];
+    if (entry->key == NULL || entry->key == dummy) {
+        i = entry->hash;
+        /* The hash field may be a real hash value, or it may be a
+         * legit search finger, or it may be a once-legit search
+         * finger that's out of bounds now because it wrapped around
+         * or the table shrunk -- simply make sure it's in bounds now.
+         */
+        if (i > so->mask || i < 1)
+            i = 1;              /* skip slot 0 */
+        while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
+            i++;
+            if (i > so->mask)
+                i = 1;
+        }
+    }
+    key = entry->key;
+    Py_INCREF(dummy);
+    entry->key = dummy;
+    so->used--;
+    so->table[0].hash = i + 1;  /* next place to start */
+    return key;
+}
+
+PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
+Raises KeyError if the set is empty.");
+
+static int
+set_traverse(PySetObject *so, visitproc visit, void *arg)
+{
+    Py_ssize_t pos = 0;
+    setentry *entry;
+
+    while (set_next(so, &pos, &entry))
+        Py_VISIT(entry->key);
+    return 0;
+}
+
+static long
+frozenset_hash(PyObject *self)
+{
+    PySetObject *so = (PySetObject *)self;
+    long h, hash = 1927868237L;
+    setentry *entry;
+    Py_ssize_t pos = 0;
+
+    if (so->hash != -1)
+        return so->hash;
+
+    hash *= PySet_GET_SIZE(self) + 1;
+    while (set_next(so, &pos, &entry)) {
+        /* Work to increase the bit dispersion for closely spaced hash
+           values.  The is important because some use cases have many
+           combinations of a small number of elements with nearby
+           hashes so that many distinct combinations collapse to only
+           a handful of distinct hash values. */
+        h = entry->hash;
+        hash ^= (h ^ (h << 16) ^ 89869747L)  * 3644798167u;
+    }
+    hash = hash * 69069L + 907133923L;
+    if (hash == -1)
+        hash = 590923713L;
+    so->hash = hash;
+    return hash;
+}
+
+/***** Set iterator type ***********************************************/
+
+typedef struct {
+    PyObject_HEAD
+    PySetObject *si_set; /* Set to NULL when iterator is exhausted */
+    Py_ssize_t si_used;
+    Py_ssize_t si_pos;
+    Py_ssize_t len;
+} setiterobject;
+
+static void
+setiter_dealloc(setiterobject *si)
+{
+    Py_XDECREF(si->si_set);
+    PyObject_GC_Del(si);
+}
+
+static int
+setiter_traverse(setiterobject *si, visitproc visit, void *arg)
+{
+    Py_VISIT(si->si_set);
+    return 0;
+}
+
+static PyObject *
+setiter_len(setiterobject *si)
+{
+    Py_ssize_t len = 0;
+    if (si->si_set != NULL && si->si_used == si->si_set->used)
+        len = si->len;
+    return PyInt_FromLong(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef setiter_methods[] = {
+    {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyObject *setiter_iternext(setiterobject *si)
+{
+    PyObject *key;
+    register Py_ssize_t i, mask;
+    register setentry *entry;
+    PySetObject *so = si->si_set;
+
+    if (so == NULL)
+        return NULL;
+    assert (PyAnySet_Check(so));
+
+    if (si->si_used != so->used) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "Set changed size during iteration");
+        si->si_used = -1; /* Make this state sticky */
+        return NULL;
+    }
+
+    i = si->si_pos;
+    assert(i>=0);
+    entry = so->table;
+    mask = so->mask;
+    while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
+        i++;
+    si->si_pos = i+1;
+    if (i > mask)
+        goto fail;
+    si->len--;
+    key = entry[i].key;
+    Py_INCREF(key);
+    return key;
+
+fail:
+    Py_DECREF(so);
+    si->si_set = NULL;
+    return NULL;
+}
+
+static PyTypeObject PySetIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "setiterator",                              /* tp_name */
+    sizeof(setiterobject),                      /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)setiter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)setiter_traverse,             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)setiter_iternext,             /* tp_iternext */
+    setiter_methods,                            /* tp_methods */
+    0,
+};
+
+static PyObject *
+set_iter(PySetObject *so)
+{
+    setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
+    if (si == NULL)
+        return NULL;
+    Py_INCREF(so);
+    si->si_set = so;
+    si->si_used = so->used;
+    si->si_pos = 0;
+    si->len = so->used;
+    _PyObject_GC_TRACK(si);
+    return (PyObject *)si;
+}
+
+static int
+set_update_internal(PySetObject *so, PyObject *other)
+{
+    PyObject *key, *it;
+
+    if (PyAnySet_Check(other))
+        return set_merge(so, other);
+
+    if (PyDict_CheckExact(other)) {
+        PyObject *value;
+        Py_ssize_t pos = 0;
+        long hash;
+        Py_ssize_t dictsize = PyDict_Size(other);
+
+        /* Do one big resize at the start, rather than
+        * incrementally resizing as we insert new keys.  Expect
+        * that there will be no (or few) overlapping keys.
+        */
+        if (dictsize == -1)
+            return -1;
+        if ((so->fill + dictsize)*3 >= (so->mask+1)*2) {
+            if (set_table_resize(so, (so->used + dictsize)*2) != 0)
+                return -1;
+        }
+        while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+            setentry an_entry;
+
+            an_entry.hash = hash;
+            an_entry.key = key;
+            if (set_add_entry(so, &an_entry) == -1)
+                return -1;
+        }
+        return 0;
+    }
+
+    it = PyObject_GetIter(other);
+    if (it == NULL)
+        return -1;
+
+    while ((key = PyIter_Next(it)) != NULL) {
+        if (set_add_key(so, key) == -1) {
+            Py_DECREF(it);
+            Py_DECREF(key);
+            return -1;
+        }
+        Py_DECREF(key);
+    }
+    Py_DECREF(it);
+    if (PyErr_Occurred())
+        return -1;
+    return 0;
+}
+
+static PyObject *
+set_update(PySetObject *so, PyObject *args)
+{
+    Py_ssize_t i;
+
+    for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+        PyObject *other = PyTuple_GET_ITEM(args, i);
+        if (set_update_internal(so, other) == -1)
+            return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(update_doc,
+"Update a set with the union of itself and others.");
+
+static PyObject *
+make_new_set(PyTypeObject *type, PyObject *iterable)
+{
+    register PySetObject *so = NULL;
+
+    if (dummy == NULL) { /* Auto-initialize dummy */
+        dummy = PyString_FromString("<dummy key>");
+        if (dummy == NULL)
+            return NULL;
+    }
+
+    /* create PySetObject structure */
+    if (numfree &&
+        (type == &PySet_Type  ||  type == &PyFrozenSet_Type)) {
+        so = free_list[--numfree];
+        assert (so != NULL && PyAnySet_CheckExact(so));
+        Py_TYPE(so) = type;
+        _Py_NewReference((PyObject *)so);
+        EMPTY_TO_MINSIZE(so);
+        PyObject_GC_Track(so);
+    } else {
+        so = (PySetObject *)type->tp_alloc(type, 0);
+        if (so == NULL)
+            return NULL;
+        /* tp_alloc has already zeroed the structure */
+        assert(so->table == NULL && so->fill == 0 && so->used == 0);
+        INIT_NONZERO_SET_SLOTS(so);
+    }
+
+    so->lookup = set_lookkey_string;
+    so->weakreflist = NULL;
+
+    if (iterable != NULL) {
+        if (set_update_internal(so, iterable) == -1) {
+            Py_DECREF(so);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)so;
+}
+
+/* The empty frozenset is a singleton */
+static PyObject *emptyfrozenset = NULL;
+
+static PyObject *
+frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *iterable = NULL, *result;
+
+    if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
+        return NULL;
+
+    if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
+        return NULL;
+
+    if (type != &PyFrozenSet_Type)
+        return make_new_set(type, iterable);
+
+    if (iterable != NULL) {
+        /* frozenset(f) is idempotent */
+        if (PyFrozenSet_CheckExact(iterable)) {
+            Py_INCREF(iterable);
+            return iterable;
+        }
+        result = make_new_set(type, iterable);
+        if (result == NULL || PySet_GET_SIZE(result))
+            return result;
+        Py_DECREF(result);
+    }
+    /* The empty frozenset is a singleton */
+    if (emptyfrozenset == NULL)
+        emptyfrozenset = make_new_set(type, NULL);
+    Py_XINCREF(emptyfrozenset);
+    return emptyfrozenset;
+}
+
+void
+PySet_Fini(void)
+{
+    PySetObject *so;
+
+    while (numfree) {
+        numfree--;
+        so = free_list[numfree];
+        PyObject_GC_Del(so);
+    }
+    Py_CLEAR(dummy);
+    Py_CLEAR(emptyfrozenset);
+}
+
+static PyObject *
+set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
+        return NULL;
+
+    return make_new_set(type, NULL);
+}
+
+/* set_swap_bodies() switches the contents of any two sets by moving their
+   internal data pointers and, if needed, copying the internal smalltables.
+   Semantically equivalent to:
+
+     t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
+
+   The function always succeeds and it leaves both objects in a stable state.
+   Useful for creating temporary frozensets from sets for membership testing
+   in __contains__(), discard(), and remove().  Also useful for operations
+   that update in-place (by allowing an intermediate result to be swapped
+   into one of the original inputs).
+*/
+
+static void
+set_swap_bodies(PySetObject *a, PySetObject *b)
+{
+    Py_ssize_t t;
+    setentry *u;
+    setentry *(*f)(PySetObject *so, PyObject *key, long hash);
+    setentry tab[PySet_MINSIZE];
+    long h;
+
+    t = a->fill;     a->fill   = b->fill;        b->fill  = t;
+    t = a->used;     a->used   = b->used;        b->used  = t;
+    t = a->mask;     a->mask   = b->mask;        b->mask  = t;
+
+    u = a->table;
+    if (a->table == a->smalltable)
+        u = b->smalltable;
+    a->table  = b->table;
+    if (b->table == b->smalltable)
+        a->table = a->smalltable;
+    b->table = u;
+
+    f = a->lookup;   a->lookup = b->lookup;      b->lookup = f;
+
+    if (a->table == a->smalltable || b->table == b->smalltable) {
+        memcpy(tab, a->smalltable, sizeof(tab));
+        memcpy(a->smalltable, b->smalltable, sizeof(tab));
+        memcpy(b->smalltable, tab, sizeof(tab));
+    }
+
+    if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type)  &&
+        PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
+        h = a->hash;     a->hash = b->hash;  b->hash = h;
+    } else {
+        a->hash = -1;
+        b->hash = -1;
+    }
+}
+
+static PyObject *
+set_copy(PySetObject *so)
+{
+    return make_new_set(Py_TYPE(so), (PyObject *)so);
+}
+
+static PyObject *
+frozenset_copy(PySetObject *so)
+{
+    if (PyFrozenSet_CheckExact(so)) {
+        Py_INCREF(so);
+        return (PyObject *)so;
+    }
+    return set_copy(so);
+}
+
+PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
+
+static PyObject *
+set_clear(PySetObject *so)
+{
+    set_clear_internal(so);
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
+
+static PyObject *
+set_union(PySetObject *so, PyObject *args)
+{
+    PySetObject *result;
+    PyObject *other;
+    Py_ssize_t i;
+
+    result = (PySetObject *)set_copy(so);
+    if (result == NULL)
+        return NULL;
+
+    for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+        other = PyTuple_GET_ITEM(args, i);
+        if ((PyObject *)so == other)
+            continue;
+        if (set_update_internal(result, other) == -1) {
+            Py_DECREF(result);
+            return NULL;
+        }
+    }
+    return (PyObject *)result;
+}
+
+PyDoc_STRVAR(union_doc,
+ "Return the union of sets as a new set.\n\
+\n\
+(i.e. all elements that are in either set.)");
+
+static PyObject *
+set_or(PySetObject *so, PyObject *other)
+{
+    PySetObject *result;
+
+    if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    result = (PySetObject *)set_copy(so);
+    if (result == NULL)
+        return NULL;
+    if ((PyObject *)so == other)
+        return (PyObject *)result;
+    if (set_update_internal(result, other) == -1) {
+        Py_DECREF(result);
+        return NULL;
+    }
+    return (PyObject *)result;
+}
+
+static PyObject *
+set_ior(PySetObject *so, PyObject *other)
+{
+    if (!PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    if (set_update_internal(so, other) == -1)
+        return NULL;
+    Py_INCREF(so);
+    return (PyObject *)so;
+}
+
+static PyObject *
+set_intersection(PySetObject *so, PyObject *other)
+{
+    PySetObject *result;
+    PyObject *key, *it, *tmp;
+
+    if ((PyObject *)so == other)
+        return set_copy(so);
+
+    result = (PySetObject *)make_new_set(Py_TYPE(so), NULL);
+    if (result == NULL)
+        return NULL;
+
+    if (PyAnySet_Check(other)) {
+        Py_ssize_t pos = 0;
+        setentry *entry;
+
+        if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
+            tmp = (PyObject *)so;
+            so = (PySetObject *)other;
+            other = tmp;
+        }
+
+        while (set_next((PySetObject *)other, &pos, &entry)) {
+            int rv = set_contains_entry(so, entry);
+            if (rv == -1) {
+                Py_DECREF(result);
+                return NULL;
+            }
+            if (rv) {
+                if (set_add_entry(result, entry) == -1) {
+                    Py_DECREF(result);
+                    return NULL;
+                }
+            }
+        }
+        return (PyObject *)result;
+    }
+
+    it = PyObject_GetIter(other);
+    if (it == NULL) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    while ((key = PyIter_Next(it)) != NULL) {
+        int rv;
+        setentry entry;
+        long hash = PyObject_Hash(key);
+
+        if (hash == -1) {
+            Py_DECREF(it);
+            Py_DECREF(result);
+            Py_DECREF(key);
+            return NULL;
+        }
+        entry.hash = hash;
+        entry.key = key;
+        rv = set_contains_entry(so, &entry);
+        if (rv == -1) {
+            Py_DECREF(it);
+            Py_DECREF(result);
+            Py_DECREF(key);
+            return NULL;
+        }
+        if (rv) {
+            if (set_add_entry(result, &entry) == -1) {
+                Py_DECREF(it);
+                Py_DECREF(result);
+                Py_DECREF(key);
+                return NULL;
+            }
+        }
+        Py_DECREF(key);
+    }
+    Py_DECREF(it);
+    if (PyErr_Occurred()) {
+        Py_DECREF(result);
+        return NULL;
+    }
+    return (PyObject *)result;
+}
+
+static PyObject *
+set_intersection_multi(PySetObject *so, PyObject *args)
+{
+    Py_ssize_t i;
+    PyObject *result = (PyObject *)so;
+
+    if (PyTuple_GET_SIZE(args) == 0)
+        return set_copy(so);
+
+    Py_INCREF(so);
+    for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+        PyObject *other = PyTuple_GET_ITEM(args, i);
+        PyObject *newresult = set_intersection((PySetObject *)result, other);
+        if (newresult == NULL) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        Py_DECREF(result);
+        result = newresult;
+    }
+    return result;
+}
+
+PyDoc_STRVAR(intersection_doc,
+"Return the intersection of two or more sets as a new set.\n\
+\n\
+(i.e. elements that are common to all of the sets.)");
+
+static PyObject *
+set_intersection_update(PySetObject *so, PyObject *other)
+{
+    PyObject *tmp;
+
+    tmp = set_intersection(so, other);
+    if (tmp == NULL)
+        return NULL;
+    set_swap_bodies(so, (PySetObject *)tmp);
+    Py_DECREF(tmp);
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+set_intersection_update_multi(PySetObject *so, PyObject *args)
+{
+    PyObject *tmp;
+
+    tmp = set_intersection_multi(so, args);
+    if (tmp == NULL)
+        return NULL;
+    set_swap_bodies(so, (PySetObject *)tmp);
+    Py_DECREF(tmp);
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(intersection_update_doc,
+"Update a set with the intersection of itself and another.");
+
+static PyObject *
+set_and(PySetObject *so, PyObject *other)
+{
+    if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return set_intersection(so, other);
+}
+
+static PyObject *
+set_iand(PySetObject *so, PyObject *other)
+{
+    PyObject *result;
+
+    if (!PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    result = set_intersection_update(so, other);
+    if (result == NULL)
+        return NULL;
+    Py_DECREF(result);
+    Py_INCREF(so);
+    return (PyObject *)so;
+}
+
+static PyObject *
+set_isdisjoint(PySetObject *so, PyObject *other)
+{
+    PyObject *key, *it, *tmp;
+
+    if ((PyObject *)so == other) {
+        if (PySet_GET_SIZE(so) == 0)
+            Py_RETURN_TRUE;
+        else
+            Py_RETURN_FALSE;
+    }
+
+    if (PyAnySet_CheckExact(other)) {
+        Py_ssize_t pos = 0;
+        setentry *entry;
+
+        if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
+            tmp = (PyObject *)so;
+            so = (PySetObject *)other;
+            other = tmp;
+        }
+        while (set_next((PySetObject *)other, &pos, &entry)) {
+            int rv = set_contains_entry(so, entry);
+            if (rv == -1)
+                return NULL;
+            if (rv)
+                Py_RETURN_FALSE;
+        }
+        Py_RETURN_TRUE;
+    }
+
+    it = PyObject_GetIter(other);
+    if (it == NULL)
+        return NULL;
+
+    while ((key = PyIter_Next(it)) != NULL) {
+        int rv;
+        setentry entry;
+        long hash = PyObject_Hash(key);
+
+        if (hash == -1) {
+            Py_DECREF(key);
+            Py_DECREF(it);
+            return NULL;
+        }
+        entry.hash = hash;
+        entry.key = key;
+        rv = set_contains_entry(so, &entry);
+        Py_DECREF(key);
+        if (rv == -1) {
+            Py_DECREF(it);
+            return NULL;
+        }
+        if (rv) {
+            Py_DECREF(it);
+            Py_RETURN_FALSE;
+        }
+    }
+    Py_DECREF(it);
+    if (PyErr_Occurred())
+        return NULL;
+    Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(isdisjoint_doc,
+"Return True if two sets have a null intersection.");
+
+static int
+set_difference_update_internal(PySetObject *so, PyObject *other)
+{
+    if ((PyObject *)so == other)
+        return set_clear_internal(so);
+
+    if (PyAnySet_Check(other)) {
+        setentry *entry;
+        Py_ssize_t pos = 0;
+
+        while (set_next((PySetObject *)other, &pos, &entry))
+            if (set_discard_entry(so, entry) == -1)
+                return -1;
+    } else {
+        PyObject *key, *it;
+        it = PyObject_GetIter(other);
+        if (it == NULL)
+            return -1;
+
+        while ((key = PyIter_Next(it)) != NULL) {
+            if (set_discard_key(so, key) == -1) {
+                Py_DECREF(it);
+                Py_DECREF(key);
+                return -1;
+            }
+            Py_DECREF(key);
+        }
+        Py_DECREF(it);
+        if (PyErr_Occurred())
+            return -1;
+    }
+    /* If more than 1/5 are dummies, then resize them away. */
+    if ((so->fill - so->used) * 5 < so->mask)
+        return 0;
+    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+static PyObject *
+set_difference_update(PySetObject *so, PyObject *args)
+{
+    Py_ssize_t i;
+
+    for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+        PyObject *other = PyTuple_GET_ITEM(args, i);
+        if (set_difference_update_internal(so, other) == -1)
+            return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(difference_update_doc,
+"Remove all elements of another set from this set.");
+
+static PyObject *
+set_difference(PySetObject *so, PyObject *other)
+{
+    PyObject *result;
+    setentry *entry;
+    Py_ssize_t pos = 0;
+
+    if (!PyAnySet_Check(other)  && !PyDict_CheckExact(other)) {
+        result = set_copy(so);
+        if (result == NULL)
+            return NULL;
+        if (set_difference_update_internal((PySetObject *)result, other) != -1)
+            return result;
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    result = make_new_set(Py_TYPE(so), NULL);
+    if (result == NULL)
+        return NULL;
+
+    if (PyDict_CheckExact(other)) {
+        while (set_next(so, &pos, &entry)) {
+            setentry entrycopy;
+            entrycopy.hash = entry->hash;
+            entrycopy.key = entry->key;
+            if (!_PyDict_Contains(other, entry->key, entry->hash)) {
+                if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
+                    Py_DECREF(result);
+                    return NULL;
+                }
+            }
+        }
+        return result;
+    }
+
+    while (set_next(so, &pos, &entry)) {
+        int rv = set_contains_entry((PySetObject *)other, entry);
+        if (rv == -1) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        if (!rv) {
+            if (set_add_entry((PySetObject *)result, entry) == -1) {
+                Py_DECREF(result);
+                return NULL;
+            }
+        }
+    }
+    return result;
+}
+
+static PyObject *
+set_difference_multi(PySetObject *so, PyObject *args)
+{
+    Py_ssize_t i;
+    PyObject *result, *other;
+
+    if (PyTuple_GET_SIZE(args) == 0)
+        return set_copy(so);
+
+    other = PyTuple_GET_ITEM(args, 0);
+    result = set_difference(so, other);
+    if (result == NULL)
+        return NULL;
+
+    for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
+        other = PyTuple_GET_ITEM(args, i);
+        if (set_difference_update_internal((PySetObject *)result, other) == -1) {
+            Py_DECREF(result);
+            return NULL;
+        }
+    }
+    return result;
+}
+
+PyDoc_STRVAR(difference_doc,
+"Return the difference of two or more sets as a new set.\n\
+\n\
+(i.e. all elements that are in this set but not the others.)");
+static PyObject *
+set_sub(PySetObject *so, PyObject *other)
+{
+    if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return set_difference(so, other);
+}
+
+static PyObject *
+set_isub(PySetObject *so, PyObject *other)
+{
+    if (!PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    if (set_difference_update_internal(so, other) == -1)
+        return NULL;
+    Py_INCREF(so);
+    return (PyObject *)so;
+}
+
+static PyObject *
+set_symmetric_difference_update(PySetObject *so, PyObject *other)
+{
+    PySetObject *otherset;
+    PyObject *key;
+    Py_ssize_t pos = 0;
+    setentry *entry;
+
+    if ((PyObject *)so == other)
+        return set_clear(so);
+
+    if (PyDict_CheckExact(other)) {
+        PyObject *value;
+        int rv;
+        long hash;
+        while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+            setentry an_entry;
+
+            Py_INCREF(key);
+            an_entry.hash = hash;
+            an_entry.key = key;
+
+            rv = set_discard_entry(so, &an_entry);
+            if (rv == -1) {
+                Py_DECREF(key);
+                return NULL;
+            }
+            if (rv == DISCARD_NOTFOUND) {
+                if (set_add_entry(so, &an_entry) == -1) {
+                    Py_DECREF(key);
+                    return NULL;
+                }
+            }
+            Py_DECREF(key);
+        }
+        Py_RETURN_NONE;
+    }
+
+    if (PyAnySet_Check(other)) {
+        Py_INCREF(other);
+        otherset = (PySetObject *)other;
+    } else {
+        otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);
+        if (otherset == NULL)
+            return NULL;
+    }
+
+    while (set_next(otherset, &pos, &entry)) {
+        int rv = set_discard_entry(so, entry);
+        if (rv == -1) {
+            Py_DECREF(otherset);
+            return NULL;
+        }
+        if (rv == DISCARD_NOTFOUND) {
+            if (set_add_entry(so, entry) == -1) {
+                Py_DECREF(otherset);
+                return NULL;
+            }
+        }
+    }
+    Py_DECREF(otherset);
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(symmetric_difference_update_doc,
+"Update a set with the symmetric difference of itself and another.");
+
+static PyObject *
+set_symmetric_difference(PySetObject *so, PyObject *other)
+{
+    PyObject *rv;
+    PySetObject *otherset;
+
+    otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);
+    if (otherset == NULL)
+        return NULL;
+    rv = set_symmetric_difference_update(otherset, (PyObject *)so);
+    if (rv == NULL)
+        return NULL;
+    Py_DECREF(rv);
+    return (PyObject *)otherset;
+}
+
+PyDoc_STRVAR(symmetric_difference_doc,
+"Return the symmetric difference of two sets as a new set.\n\
+\n\
+(i.e. all elements that are in exactly one of the sets.)");
+
+static PyObject *
+set_xor(PySetObject *so, PyObject *other)
+{
+    if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return set_symmetric_difference(so, other);
+}
+
+static PyObject *
+set_ixor(PySetObject *so, PyObject *other)
+{
+    PyObject *result;
+
+    if (!PyAnySet_Check(other)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    result = set_symmetric_difference_update(so, other);
+    if (result == NULL)
+        return NULL;
+    Py_DECREF(result);
+    Py_INCREF(so);
+    return (PyObject *)so;
+}
+
+static PyObject *
+set_issubset(PySetObject *so, PyObject *other)
+{
+    setentry *entry;
+    Py_ssize_t pos = 0;
+
+    if (!PyAnySet_Check(other)) {
+        PyObject *tmp, *result;
+        tmp = make_new_set(&PySet_Type, other);
+        if (tmp == NULL)
+            return NULL;
+        result = set_issubset(so, tmp);
+        Py_DECREF(tmp);
+        return result;
+    }
+    if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
+        Py_RETURN_FALSE;
+
+    while (set_next(so, &pos, &entry)) {
+        int rv = set_contains_entry((PySetObject *)other, entry);
+        if (rv == -1)
+            return NULL;
+        if (!rv)
+            Py_RETURN_FALSE;
+    }
+    Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
+
+static PyObject *
+set_issuperset(PySetObject *so, PyObject *other)
+{
+    PyObject *tmp, *result;
+
+    if (!PyAnySet_Check(other)) {
+        tmp = make_new_set(&PySet_Type, other);
+        if (tmp == NULL)
+            return NULL;
+        result = set_issuperset(so, tmp);
+        Py_DECREF(tmp);
+        return result;
+    }
+    return set_issubset((PySetObject *)other, (PyObject *)so);
+}
+
+PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
+
+static PyObject *
+set_richcompare(PySetObject *v, PyObject *w, int op)
+{
+    PyObject *r1, *r2;
+
+    if(!PyAnySet_Check(w)) {
+        if (op == Py_EQ)
+            Py_RETURN_FALSE;
+        if (op == Py_NE)
+            Py_RETURN_TRUE;
+        PyErr_SetString(PyExc_TypeError, "can only compare to a set");
+        return NULL;
+    }
+    switch (op) {
+    case Py_EQ:
+        if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
+            Py_RETURN_FALSE;
+        if (v->hash != -1  &&
+            ((PySetObject *)w)->hash != -1 &&
+            v->hash != ((PySetObject *)w)->hash)
+            Py_RETURN_FALSE;
+        return set_issubset(v, w);
+    case Py_NE:
+        r1 = set_richcompare(v, w, Py_EQ);
+        if (r1 == NULL)
+            return NULL;
+        r2 = PyBool_FromLong(PyObject_Not(r1));
+        Py_DECREF(r1);
+        return r2;
+    case Py_LE:
+        return set_issubset(v, w);
+    case Py_GE:
+        return set_issuperset(v, w);
+    case Py_LT:
+        if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
+            Py_RETURN_FALSE;
+        return set_issubset(v, w);
+    case Py_GT:
+        if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
+            Py_RETURN_FALSE;
+        return set_issuperset(v, w);
+    }
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+static int
+set_nocmp(PyObject *self, PyObject *other)
+{
+    PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");
+    return -1;
+}
+
+static PyObject *
+set_add(PySetObject *so, PyObject *key)
+{
+    if (set_add_key(so, key) == -1)
+        return NULL;
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(add_doc,
+"Add an element to a set.\n\
+\n\
+This has no effect if the element is already present.");
+
+static int
+set_contains(PySetObject *so, PyObject *key)
+{
+    PyObject *tmpkey;
+    int rv;
+
+    rv = set_contains_key(so, key);
+    if (rv == -1) {
+        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+            return -1;
+        PyErr_Clear();
+        tmpkey = make_new_set(&PyFrozenSet_Type, key);
+        if (tmpkey == NULL)
+            return -1;
+        rv = set_contains_key(so, tmpkey);
+        Py_DECREF(tmpkey);
+    }
+    return rv;
+}
+
+static PyObject *
+set_direct_contains(PySetObject *so, PyObject *key)
+{
+    long result;
+
+    result = set_contains(so, key);
+    if (result == -1)
+        return NULL;
+    return PyBool_FromLong(result);
+}
+
+PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
+
+static PyObject *
+set_remove(PySetObject *so, PyObject *key)
+{
+    PyObject *tmpkey;
+    int rv;
+
+    rv = set_discard_key(so, key);
+    if (rv == -1) {
+        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+            return NULL;
+        PyErr_Clear();
+        tmpkey = make_new_set(&PyFrozenSet_Type, key);
+        if (tmpkey == NULL)
+            return NULL;
+        rv = set_discard_key(so, tmpkey);
+        Py_DECREF(tmpkey);
+        if (rv == -1)
+            return NULL;
+    }
+
+    if (rv == DISCARD_NOTFOUND) {
+        set_key_error(key);
+        return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(remove_doc,
+"Remove an element from a set; it must be a member.\n\
+\n\
+If the element is not a member, raise a KeyError.");
+
+static PyObject *
+set_discard(PySetObject *so, PyObject *key)
+{
+    PyObject *tmpkey;
+    int rv;
+
+    rv = set_discard_key(so, key);
+    if (rv == -1) {
+        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+            return NULL;
+        PyErr_Clear();
+        tmpkey = make_new_set(&PyFrozenSet_Type, key);
+        if (tmpkey == NULL)
+            return NULL;
+        rv = set_discard_key(so, tmpkey);
+        Py_DECREF(tmpkey);
+        if (rv == -1)
+            return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(discard_doc,
+"Remove an element from a set if it is a member.\n\
+\n\
+If the element is not a member, do nothing.");
+
+static PyObject *
+set_reduce(PySetObject *so)
+{
+    PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
+
+    keys = PySequence_List((PyObject *)so);
+    if (keys == NULL)
+        goto done;
+    args = PyTuple_Pack(1, keys);
+    if (args == NULL)
+        goto done;
+    dict = PyObject_GetAttrString((PyObject *)so, "__dict__");
+    if (dict == NULL) {
+        PyErr_Clear();
+        dict = Py_None;
+        Py_INCREF(dict);
+    }
+    result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
+done:
+    Py_XDECREF(args);
+    Py_XDECREF(keys);
+    Py_XDECREF(dict);
+    return result;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyObject *
+set_sizeof(PySetObject *so)
+{
+    Py_ssize_t res;
+
+    res = sizeof(PySetObject);
+    if (so->table != so->smalltable)
+        res = res + (so->mask + 1) * sizeof(setentry);
+    return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
+static int
+set_init(PySetObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *iterable = NULL;
+
+    if (!PyAnySet_Check(self))
+        return -1;
+    if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
+        return -1;
+    if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
+        return -1;
+    set_clear_internal(self);
+    self->hash = -1;
+    if (iterable == NULL)
+        return 0;
+    return set_update_internal(self, iterable);
+}
+
+static PySequenceMethods set_as_sequence = {
+    set_len,                            /* sq_length */
+    0,                                  /* sq_concat */
+    0,                                  /* sq_repeat */
+    0,                                  /* sq_item */
+    0,                                  /* sq_slice */
+    0,                                  /* sq_ass_item */
+    0,                                  /* sq_ass_slice */
+    (objobjproc)set_contains,           /* sq_contains */
+};
+
+/* set object ********************************************************/
+
+#ifdef Py_DEBUG
+static PyObject *test_c_api(PySetObject *so);
+
+PyDoc_STRVAR(test_c_api_doc, "Exercises C API.  Returns True.\n\
+All is well if assertions don't fail.");
+#endif
+
+static PyMethodDef set_methods[] = {
+    {"add",             (PyCFunction)set_add,           METH_O,
+     add_doc},
+    {"clear",           (PyCFunction)set_clear,         METH_NOARGS,
+     clear_doc},
+    {"__contains__",(PyCFunction)set_direct_contains,           METH_O | METH_COEXIST,
+     contains_doc},
+    {"copy",            (PyCFunction)set_copy,          METH_NOARGS,
+     copy_doc},
+    {"discard",         (PyCFunction)set_discard,       METH_O,
+     discard_doc},
+    {"difference",      (PyCFunction)set_difference_multi,      METH_VARARGS,
+     difference_doc},
+    {"difference_update",       (PyCFunction)set_difference_update,     METH_VARARGS,
+     difference_update_doc},
+    {"intersection",(PyCFunction)set_intersection_multi,        METH_VARARGS,
+     intersection_doc},
+    {"intersection_update",(PyCFunction)set_intersection_update_multi,          METH_VARARGS,
+     intersection_update_doc},
+    {"isdisjoint",      (PyCFunction)set_isdisjoint,    METH_O,
+     isdisjoint_doc},
+    {"issubset",        (PyCFunction)set_issubset,      METH_O,
+     issubset_doc},
+    {"issuperset",      (PyCFunction)set_issuperset,    METH_O,
+     issuperset_doc},
+    {"pop",             (PyCFunction)set_pop,           METH_NOARGS,
+     pop_doc},
+    {"__reduce__",      (PyCFunction)set_reduce,        METH_NOARGS,
+     reduce_doc},
+    {"remove",          (PyCFunction)set_remove,        METH_O,
+     remove_doc},
+    {"__sizeof__",      (PyCFunction)set_sizeof,        METH_NOARGS,
+     sizeof_doc},
+    {"symmetric_difference",(PyCFunction)set_symmetric_difference,      METH_O,
+     symmetric_difference_doc},
+    {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update,        METH_O,
+     symmetric_difference_update_doc},
+#ifdef Py_DEBUG
+    {"test_c_api",      (PyCFunction)test_c_api,        METH_NOARGS,
+     test_c_api_doc},
+#endif
+    {"union",           (PyCFunction)set_union,         METH_VARARGS,
+     union_doc},
+    {"update",          (PyCFunction)set_update,        METH_VARARGS,
+     update_doc},
+    {NULL,              NULL}   /* sentinel */
+};
+
+static PyNumberMethods set_as_number = {
+    0,                                  /*nb_add*/
+    (binaryfunc)set_sub,                /*nb_subtract*/
+    0,                                  /*nb_multiply*/
+    0,                                  /*nb_divide*/
+    0,                                  /*nb_remainder*/
+    0,                                  /*nb_divmod*/
+    0,                                  /*nb_power*/
+    0,                                  /*nb_negative*/
+    0,                                  /*nb_positive*/
+    0,                                  /*nb_absolute*/
+    0,                                  /*nb_nonzero*/
+    0,                                  /*nb_invert*/
+    0,                                  /*nb_lshift*/
+    0,                                  /*nb_rshift*/
+    (binaryfunc)set_and,                /*nb_and*/
+    (binaryfunc)set_xor,                /*nb_xor*/
+    (binaryfunc)set_or,                 /*nb_or*/
+    0,                                  /*nb_coerce*/
+    0,                                  /*nb_int*/
+    0,                                  /*nb_long*/
+    0,                                  /*nb_float*/
+    0,                                  /*nb_oct*/
+    0,                                  /*nb_hex*/
+    0,                                  /*nb_inplace_add*/
+    (binaryfunc)set_isub,               /*nb_inplace_subtract*/
+    0,                                  /*nb_inplace_multiply*/
+    0,                                  /*nb_inplace_divide*/
+    0,                                  /*nb_inplace_remainder*/
+    0,                                  /*nb_inplace_power*/
+    0,                                  /*nb_inplace_lshift*/
+    0,                                  /*nb_inplace_rshift*/
+    (binaryfunc)set_iand,               /*nb_inplace_and*/
+    (binaryfunc)set_ixor,               /*nb_inplace_xor*/
+    (binaryfunc)set_ior,                /*nb_inplace_or*/
+};
+
+PyDoc_STRVAR(set_doc,
+"set() -> new empty set object\n\
+set(iterable) -> new set object\n\
+\n\
+Build an unordered collection of unique elements.");
+
+PyTypeObject PySet_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "set",                              /* tp_name */
+    sizeof(PySetObject),                /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    /* methods */
+    (destructor)set_dealloc,            /* tp_dealloc */
+    (printfunc)set_tp_print,            /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    set_nocmp,                          /* tp_compare */
+    (reprfunc)set_repr,                 /* tp_repr */
+    &set_as_number,                     /* tp_as_number */
+    &set_as_sequence,                   /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    (hashfunc)PyObject_HashNotImplemented,      /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,            /* tp_flags */
+    set_doc,                            /* tp_doc */
+    (traverseproc)set_traverse,         /* tp_traverse */
+    (inquiry)set_clear_internal,        /* tp_clear */
+    (richcmpfunc)set_richcompare,       /* tp_richcompare */
+    offsetof(PySetObject, weakreflist),         /* tp_weaklistoffset */
+    (getiterfunc)set_iter,      /* tp_iter */
+    0,                                  /* tp_iternext */
+    set_methods,                        /* tp_methods */
+    0,                                  /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
+    0,                                  /* tp_dictoffset */
+    (initproc)set_init,                 /* tp_init */
+    PyType_GenericAlloc,                /* tp_alloc */
+    set_new,                            /* tp_new */
+    PyObject_GC_Del,                    /* tp_free */
+};
+
+/* frozenset object ********************************************************/
+
+
+static PyMethodDef frozenset_methods[] = {
+    {"__contains__",(PyCFunction)set_direct_contains,           METH_O | METH_COEXIST,
+     contains_doc},
+    {"copy",            (PyCFunction)frozenset_copy,    METH_NOARGS,
+     copy_doc},
+    {"difference",      (PyCFunction)set_difference_multi,      METH_VARARGS,
+     difference_doc},
+    {"intersection",(PyCFunction)set_intersection_multi,        METH_VARARGS,
+     intersection_doc},
+    {"isdisjoint",      (PyCFunction)set_isdisjoint,    METH_O,
+     isdisjoint_doc},
+    {"issubset",        (PyCFunction)set_issubset,      METH_O,
+     issubset_doc},
+    {"issuperset",      (PyCFunction)set_issuperset,    METH_O,
+     issuperset_doc},
+    {"__reduce__",      (PyCFunction)set_reduce,        METH_NOARGS,
+     reduce_doc},
+    {"__sizeof__",      (PyCFunction)set_sizeof,        METH_NOARGS,
+     sizeof_doc},
+    {"symmetric_difference",(PyCFunction)set_symmetric_difference,      METH_O,
+     symmetric_difference_doc},
+    {"union",           (PyCFunction)set_union,         METH_VARARGS,
+     union_doc},
+    {NULL,              NULL}   /* sentinel */
+};
+
+static PyNumberMethods frozenset_as_number = {
+    0,                                  /*nb_add*/
+    (binaryfunc)set_sub,                /*nb_subtract*/
+    0,                                  /*nb_multiply*/
+    0,                                  /*nb_divide*/
+    0,                                  /*nb_remainder*/
+    0,                                  /*nb_divmod*/
+    0,                                  /*nb_power*/
+    0,                                  /*nb_negative*/
+    0,                                  /*nb_positive*/
+    0,                                  /*nb_absolute*/
+    0,                                  /*nb_nonzero*/
+    0,                                  /*nb_invert*/
+    0,                                  /*nb_lshift*/
+    0,                                  /*nb_rshift*/
+    (binaryfunc)set_and,                /*nb_and*/
+    (binaryfunc)set_xor,                /*nb_xor*/
+    (binaryfunc)set_or,                 /*nb_or*/
+};
+
+PyDoc_STRVAR(frozenset_doc,
+"frozenset() -> empty frozenset object\n\
+frozenset(iterable) -> frozenset object\n\
+\n\
+Build an immutable unordered collection of unique elements.");
+
+PyTypeObject PyFrozenSet_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "frozenset",                        /* tp_name */
+    sizeof(PySetObject),                /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    /* methods */
+    (destructor)set_dealloc,            /* tp_dealloc */
+    (printfunc)set_tp_print,            /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    set_nocmp,                          /* tp_compare */
+    (reprfunc)set_repr,                 /* tp_repr */
+    &frozenset_as_number,               /* tp_as_number */
+    &set_as_sequence,                   /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    frozenset_hash,                     /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE,            /* tp_flags */
+    frozenset_doc,                      /* tp_doc */
+    (traverseproc)set_traverse,         /* tp_traverse */
+    (inquiry)set_clear_internal,        /* tp_clear */
+    (richcmpfunc)set_richcompare,       /* tp_richcompare */
+    offsetof(PySetObject, weakreflist),         /* tp_weaklistoffset */
+    (getiterfunc)set_iter,              /* tp_iter */
+    0,                                  /* tp_iternext */
+    frozenset_methods,                  /* tp_methods */
+    0,                                  /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
+    0,                                  /* tp_dictoffset */
+    0,                                  /* tp_init */
+    PyType_GenericAlloc,                /* tp_alloc */
+    frozenset_new,                      /* tp_new */
+    PyObject_GC_Del,                    /* tp_free */
+};
+
+
+/***** C API functions *************************************************/
+
+PyObject *
+PySet_New(PyObject *iterable)
+{
+    return make_new_set(&PySet_Type, iterable);
+}
+
+PyObject *
+PyFrozenSet_New(PyObject *iterable)
+{
+    return make_new_set(&PyFrozenSet_Type, iterable);
+}
+
+Py_ssize_t
+PySet_Size(PyObject *anyset)
+{
+    if (!PyAnySet_Check(anyset)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return PySet_GET_SIZE(anyset);
+}
+
+int
+PySet_Clear(PyObject *set)
+{
+    if (!PySet_Check(set)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return set_clear_internal((PySetObject *)set);
+}
+
+int
+PySet_Contains(PyObject *anyset, PyObject *key)
+{
+    if (!PyAnySet_Check(anyset)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return set_contains_key((PySetObject *)anyset, key);
+}
+
+int
+PySet_Discard(PyObject *set, PyObject *key)
+{
+    if (!PySet_Check(set)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return set_discard_key((PySetObject *)set, key);
+}
+
+int
+PySet_Add(PyObject *anyset, PyObject *key)
+{
+    if (!PySet_Check(anyset) &&
+        (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return set_add_key((PySetObject *)anyset, key);
+}
+
+int
+_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key)
+{
+    setentry *entry_ptr;
+
+    if (!PyAnySet_Check(set)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (set_next((PySetObject *)set, pos, &entry_ptr) == 0)
+        return 0;
+    *key = entry_ptr->key;
+    return 1;
+}
+
+int
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+{
+    setentry *entry;
+
+    if (!PyAnySet_Check(set)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (set_next((PySetObject *)set, pos, &entry) == 0)
+        return 0;
+    *key = entry->key;
+    *hash = entry->hash;
+    return 1;
+}
+
+PyObject *
+PySet_Pop(PyObject *set)
+{
+    if (!PySet_Check(set)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return set_pop((PySetObject *)set);
+}
+
+int
+_PySet_Update(PyObject *set, PyObject *iterable)
+{
+    if (!PySet_Check(set)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    return set_update_internal((PySetObject *)set, iterable);
+}
+
+#ifdef Py_DEBUG
+
+/* Test code to be called with any three element set.
+   Returns True and original set is restored. */
+
+#define assertRaises(call_return_value, exception)              \
+    do {                                                        \
+        assert(call_return_value);                              \
+        assert(PyErr_ExceptionMatches(exception));              \
+        PyErr_Clear();                                          \
+    } while(0)
+
+static PyObject *
+test_c_api(PySetObject *so)
+{
+    Py_ssize_t count;
+    char *s;
+    Py_ssize_t i;
+    PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;
+    PyObject *ob = (PyObject *)so;
+    PyObject *str;
+
+    /* Verify preconditions */
+    assert(PyAnySet_Check(ob));
+    assert(PyAnySet_CheckExact(ob));
+    assert(!PyFrozenSet_CheckExact(ob));
+
+    /* so.clear(); so |= set("abc"); */
+    str = PyString_FromString("abc");
+    if (str == NULL)
+        return NULL;
+    set_clear_internal(so);
+    if (set_update_internal(so, str) == -1) {
+        Py_DECREF(str);
+        return NULL;
+    }
+    Py_DECREF(str);
+
+    /* Exercise type/size checks */
+    assert(PySet_Size(ob) == 3);
+    assert(PySet_GET_SIZE(ob) == 3);
+
+    /* Raise TypeError for non-iterable constructor arguments */
+    assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
+    assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
+
+    /* Raise TypeError for unhashable key */
+    dup = PySet_New(ob);
+    assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
+    assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
+    assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
+
+    /* Exercise successful pop, contains, add, and discard */
+    elem = PySet_Pop(ob);
+    assert(PySet_Contains(ob, elem) == 0);
+    assert(PySet_GET_SIZE(ob) == 2);
+    assert(PySet_Add(ob, elem) == 0);
+    assert(PySet_Contains(ob, elem) == 1);
+    assert(PySet_GET_SIZE(ob) == 3);
+    assert(PySet_Discard(ob, elem) == 1);
+    assert(PySet_GET_SIZE(ob) == 2);
+    assert(PySet_Discard(ob, elem) == 0);
+    assert(PySet_GET_SIZE(ob) == 2);
+
+    /* Exercise clear */
+    dup2 = PySet_New(dup);
+    assert(PySet_Clear(dup2) == 0);
+    assert(PySet_Size(dup2) == 0);
+    Py_DECREF(dup2);
+
+    /* Raise SystemError on clear or update of frozen set */
+    f = PyFrozenSet_New(dup);
+    assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
+    assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
+    assert(PySet_Add(f, elem) == 0);
+    Py_INCREF(f);
+    assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
+    Py_DECREF(f);
+    Py_DECREF(f);
+
+    /* Exercise direct iteration */
+    i = 0, count = 0;
+    while (_PySet_Next((PyObject *)dup, &i, &x)) {
+        s = PyString_AsString(x);
+        assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
+        count++;
+    }
+    assert(count == 3);
+
+    /* Exercise updates */
+    dup2 = PySet_New(NULL);
+    assert(_PySet_Update(dup2, dup) == 0);
+    assert(PySet_Size(dup2) == 3);
+    assert(_PySet_Update(dup2, dup) == 0);
+    assert(PySet_Size(dup2) == 3);
+    Py_DECREF(dup2);
+
+    /* Raise SystemError when self argument is not a set or frozenset. */
+    t = PyTuple_New(0);
+    assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
+    assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
+    Py_DECREF(t);
+
+    /* Raise SystemError when self argument is not a set. */
+    f = PyFrozenSet_New(dup);
+    assert(PySet_Size(f) == 3);
+    assert(PyFrozenSet_CheckExact(f));
+    assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
+    assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
+    Py_DECREF(f);
+
+    /* Raise KeyError when popping from an empty set */
+    assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
+    Py_DECREF(ob);
+    assert(PySet_GET_SIZE(ob) == 0);
+    assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
+
+    /* Restore the set from the copy using the PyNumber API */
+    assert(PyNumber_InPlaceOr(ob, dup) == ob);
+    Py_DECREF(ob);
+
+    /* Verify constructors accept NULL arguments */
+    f = PySet_New(NULL);
+    assert(f != NULL);
+    assert(PySet_GET_SIZE(f) == 0);
+    Py_DECREF(f);
+    f = PyFrozenSet_New(NULL);
+    assert(f != NULL);
+    assert(PyFrozenSet_CheckExact(f));
+    assert(PySet_GET_SIZE(f) == 0);
+    Py_DECREF(f);
+
+    Py_DECREF(elem);
+    Py_DECREF(dup);
+    Py_RETURN_TRUE;
+}
+
+#undef assertRaises
+
+#endif
diff --git a/Python-2.7.5/Objects/sliceobject.c b/Python-2.7.5/Objects/sliceobject.c
new file mode 100644
index 0000000..767a50a
--- /dev/null
+++ b/Python-2.7.5/Objects/sliceobject.c
@@ -0,0 +1,362 @@
+/*
+Written by Jim Hugunin and Chris Chase.
+
+This includes both the singular ellipsis object and slice objects.
+
+Guido, feel free to do whatever you want in the way of copyrights
+for this file.
+*/
+
+/*
+Py_Ellipsis encodes the '...' rubber index token. It is similar to
+the Py_NoneStruct in that there is no way to create other objects of
+this type and there is exactly one in existence.
+*/
+
+#include "Python.h"
+#include "structmember.h"
+
+static PyObject *
+ellipsis_repr(PyObject *op)
+{
+    return PyString_FromString("Ellipsis");
+}
+
+PyTypeObject PyEllipsis_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "ellipsis",                         /* tp_name */
+    0,                                  /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    0, /*never called*/                 /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    0,                                  /* tp_compare */
+    ellipsis_repr,                      /* tp_repr */
+    0,                                  /* tp_as_number */
+    0,                                  /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+};
+
+PyObject _Py_EllipsisObject = {
+    _PyObject_EXTRA_INIT
+    1, &PyEllipsis_Type
+};
+
+
+/* Slice object implementation
+
+   start, stop, and step are python objects with None indicating no
+   index is present.
+*/
+
+PyObject *
+PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
+{
+    PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type);
+
+    if (obj == NULL)
+        return NULL;
+
+    if (step == NULL) step = Py_None;
+    Py_INCREF(step);
+    if (start == NULL) start = Py_None;
+    Py_INCREF(start);
+    if (stop == NULL) stop = Py_None;
+    Py_INCREF(stop);
+
+    obj->step = step;
+    obj->start = start;
+    obj->stop = stop;
+
+    return (PyObject *) obj;
+}
+
+PyObject *
+_PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop)
+{
+    PyObject *start, *end, *slice;
+    start = PyInt_FromSsize_t(istart);
+    if (!start)
+        return NULL;
+    end = PyInt_FromSsize_t(istop);
+    if (!end) {
+        Py_DECREF(start);
+        return NULL;
+    }
+
+    slice = PySlice_New(start, end, NULL);
+    Py_DECREF(start);
+    Py_DECREF(end);
+    return slice;
+}
+
+int
+PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
+                   Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
+{
+    /* XXX support long ints */
+    if (r->step == Py_None) {
+        *step = 1;
+    } else {
+        if (!PyInt_Check(r->step) && !PyLong_Check(r->step)) return -1;
+        *step = PyInt_AsSsize_t(r->step);
+    }
+    if (r->start == Py_None) {
+        *start = *step < 0 ? length-1 : 0;
+    } else {
+        if (!PyInt_Check(r->start) && !PyLong_Check(r->step)) return -1;
+        *start = PyInt_AsSsize_t(r->start);
+        if (*start < 0) *start += length;
+    }
+    if (r->stop == Py_None) {
+        *stop = *step < 0 ? -1 : length;
+    } else {
+        if (!PyInt_Check(r->stop) && !PyLong_Check(r->step)) return -1;
+        *stop = PyInt_AsSsize_t(r->stop);
+        if (*stop < 0) *stop += length;
+    }
+    if (*stop > length) return -1;
+    if (*start >= length) return -1;
+    if (*step == 0) return -1;
+    return 0;
+}
+
+int
+PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
+                     Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
+{
+    /* this is harder to get right than you might think */
+
+    Py_ssize_t defstart, defstop;
+
+    if (r->step == Py_None) {
+        *step = 1;
+    }
+    else {
+        if (!_PyEval_SliceIndex(r->step, step)) return -1;
+        if (*step == 0) {
+            PyErr_SetString(PyExc_ValueError,
+                            "slice step cannot be zero");
+            return -1;
+        }
+    }
+
+    defstart = *step < 0 ? length-1 : 0;
+    defstop = *step < 0 ? -1 : length;
+
+    if (r->start == Py_None) {
+        *start = defstart;
+    }
+    else {
+        if (!_PyEval_SliceIndex(r->start, start)) return -1;
+        if (*start < 0) *start += length;
+        if (*start < 0) *start = (*step < 0) ? -1 : 0;
+        if (*start >= length)
+            *start = (*step < 0) ? length - 1 : length;
+    }
+
+    if (r->stop == Py_None) {
+        *stop = defstop;
+    }
+    else {
+        if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
+        if (*stop < 0) *stop += length;
+        if (*stop < 0) *stop = (*step < 0) ? -1 : 0;
+        if (*stop >= length)
+            *stop = (*step < 0) ? length - 1 : length;
+    }
+
+    if ((*step < 0 && *stop >= *start)
+        || (*step > 0 && *start >= *stop)) {
+        *slicelength = 0;
+    }
+    else if (*step < 0) {
+        *slicelength = (*stop-*start+1)/(*step)+1;
+    }
+    else {
+        *slicelength = (*stop-*start-1)/(*step)+1;
+    }
+
+    return 0;
+}
+
+static PyObject *
+slice_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+    PyObject *start, *stop, *step;
+
+    start = stop = step = NULL;
+
+    if (!_PyArg_NoKeywords("slice()", kw))
+        return NULL;
+
+    if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step))
+        return NULL;
+
+    /* This swapping of stop and start is to maintain similarity with
+       range(). */
+    if (stop == NULL) {
+        stop = start;
+        start = NULL;
+    }
+    return PySlice_New(start, stop, step);
+}
+
+PyDoc_STRVAR(slice_doc,
+"slice(stop)\n\
+slice(start, stop[, step])\n\
+\n\
+Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).");
+
+static void
+slice_dealloc(PySliceObject *r)
+{
+    Py_DECREF(r->step);
+    Py_DECREF(r->start);
+    Py_DECREF(r->stop);
+    PyObject_Del(r);
+}
+
+static PyObject *
+slice_repr(PySliceObject *r)
+{
+    PyObject *s, *comma;
+
+    s = PyString_FromString("slice(");
+    comma = PyString_FromString(", ");
+    PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
+    PyString_Concat(&s, comma);
+    PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
+    PyString_Concat(&s, comma);
+    PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
+    PyString_ConcatAndDel(&s, PyString_FromString(")"));
+    Py_DECREF(comma);
+    return s;
+}
+
+static PyMemberDef slice_members[] = {
+    {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
+    {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
+    {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
+    {0}
+};
+
+static PyObject*
+slice_indices(PySliceObject* self, PyObject* len)
+{
+    Py_ssize_t ilen, start, stop, step, slicelength;
+
+    ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError);
+
+    if (ilen == -1 && PyErr_Occurred()) {
+        return NULL;
+    }
+
+    if (PySlice_GetIndicesEx(self, ilen, &start, &stop,
+                             &step, &slicelength) < 0) {
+        return NULL;
+    }
+
+    return Py_BuildValue("(nnn)", start, stop, step);
+}
+
+PyDoc_STRVAR(slice_indices_doc,
+"S.indices(len) -> (start, stop, stride)\n\
+\n\
+Assuming a sequence of length len, calculate the start and stop\n\
+indices, and the stride length of the extended slice described by\n\
+S. Out of bounds indices are clipped in a manner consistent with the\n\
+handling of normal slices.");
+
+static PyObject *
+slice_reduce(PySliceObject* self)
+{
+    return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step);
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyMethodDef slice_methods[] = {
+    {"indices",         (PyCFunction)slice_indices,
+     METH_O,            slice_indices_doc},
+    {"__reduce__",      (PyCFunction)slice_reduce,
+     METH_NOARGS,       reduce_doc},
+    {NULL, NULL}
+};
+
+static int
+slice_compare(PySliceObject *v, PySliceObject *w)
+{
+    int result = 0;
+
+    if (v == w)
+        return 0;
+
+    if (PyObject_Cmp(v->start, w->start, &result) < 0)
+        return -2;
+    if (result != 0)
+        return result;
+    if (PyObject_Cmp(v->stop, w->stop, &result) < 0)
+        return -2;
+    if (result != 0)
+        return result;
+    if (PyObject_Cmp(v->step, w->step, &result) < 0)
+        return -2;
+    return result;
+}
+
+static long
+slice_hash(PySliceObject *v)
+{
+    PyErr_SetString(PyExc_TypeError, "unhashable type");
+    return -1L;
+}
+
+PyTypeObject PySlice_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "slice",                    /* Name of this type */
+    sizeof(PySliceObject),      /* Basic object size */
+    0,                          /* Item size for varobject */
+    (destructor)slice_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    (cmpfunc)slice_compare,                     /* tp_compare */
+    (reprfunc)slice_repr,                       /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)slice_hash,                       /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    slice_doc,                                  /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    slice_methods,                              /* tp_methods */
+    slice_members,                              /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    slice_new,                                  /* tp_new */
+};
diff --git a/Python-2.7.5/Objects/stringlib/README.txt b/Python-2.7.5/Objects/stringlib/README.txt
new file mode 100644
index 0000000..ab506d6
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/README.txt
@@ -0,0 +1,40 @@
+bits shared by the stringobject and unicodeobject implementations (and
+possibly other modules, in a not too distant future).
+
+the stuff in here is included into relevant places; see the individual
+source files for details.
+
+--------------------------------------------------------------------
+the following defines used by the different modules:
+
+STRINGLIB_CHAR
+
+    the type used to hold a character (char or Py_UNICODE)
+
+STRINGLIB_EMPTY
+
+    a PyObject representing the empty string, only to be used if
+    STRINGLIB_MUTABLE is 0
+
+Py_ssize_t STRINGLIB_LEN(PyObject*)
+
+    returns the length of the given string object (which must be of the
+    right type)
+
+PyObject* STRINGLIB_NEW(STRINGLIB_CHAR*, Py_ssize_t)
+
+    creates a new string object
+
+STRINGLIB_CHAR* STRINGLIB_STR(PyObject*)
+
+    returns the pointer to the character data for the given string
+    object (which must be of the right type)
+
+int STRINGLIB_CHECK_EXACT(PyObject *)
+
+    returns true if the object is an instance of our type, not a subclass
+
+STRINGLIB_MUTABLE
+
+    must be 0 or 1 to tell the cpp macros in stringlib code if the object
+    being operated on is mutable or not
diff --git a/Python-2.7.5/Objects/stringlib/count.h b/Python-2.7.5/Objects/stringlib/count.h
new file mode 100644
index 0000000..de34f96
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/count.h
@@ -0,0 +1,30 @@
+/* stringlib: count implementation */
+
+#ifndef STRINGLIB_COUNT_H
+#define STRINGLIB_COUNT_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_count(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                Py_ssize_t maxcount)
+{
+    Py_ssize_t count;
+
+    if (str_len < 0)
+        return 0; /* start > len(str) */
+    if (sub_len == 0)
+        return (str_len < maxcount) ? str_len + 1 : maxcount;
+
+    count = fastsearch(str, str_len, sub, sub_len, maxcount, FAST_COUNT);
+
+    if (count < 0)
+        return 0; /* no match */
+
+    return count;
+}
+
+#endif
diff --git a/Python-2.7.5/Objects/stringlib/ctype.h b/Python-2.7.5/Objects/stringlib/ctype.h
new file mode 100644
index 0000000..739cf3d
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/ctype.h
@@ -0,0 +1,109 @@
+/* NOTE: this API is -ONLY- for use with single byte character strings. */
+/* Do not use it with Unicode. */
+
+#include "bytes_methods.h"
+
+static PyObject*
+stringlib_isspace(PyObject *self)
+{
+    return _Py_bytes_isspace(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isalpha(PyObject *self)
+{
+    return _Py_bytes_isalpha(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isalnum(PyObject *self)
+{
+    return _Py_bytes_isalnum(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isdigit(PyObject *self)
+{
+    return _Py_bytes_isdigit(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_islower(PyObject *self)
+{
+    return _Py_bytes_islower(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isupper(PyObject *self)
+{
+    return _Py_bytes_isupper(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_istitle(PyObject *self)
+{
+    return _Py_bytes_istitle(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+
+/* functions that return a new object partially translated by ctype funcs: */
+
+static PyObject*
+stringlib_lower(PyObject *self)
+{
+    PyObject* newobj;
+    newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+    if (!newobj)
+            return NULL;
+    _Py_bytes_lower(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+                 STRINGLIB_LEN(self));
+    return newobj;
+}
+
+static PyObject*
+stringlib_upper(PyObject *self)
+{
+    PyObject* newobj;
+    newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+    if (!newobj)
+            return NULL;
+    _Py_bytes_upper(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+                 STRINGLIB_LEN(self));
+    return newobj;
+}
+
+static PyObject*
+stringlib_title(PyObject *self)
+{
+    PyObject* newobj;
+    newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+    if (!newobj)
+            return NULL;
+    _Py_bytes_title(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+                 STRINGLIB_LEN(self));
+    return newobj;
+}
+
+static PyObject*
+stringlib_capitalize(PyObject *self)
+{
+    PyObject* newobj;
+    newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+    if (!newobj)
+            return NULL;
+    _Py_bytes_capitalize(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+                      STRINGLIB_LEN(self));
+    return newobj;
+}
+
+static PyObject*
+stringlib_swapcase(PyObject *self)
+{
+    PyObject* newobj;
+    newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+    if (!newobj)
+            return NULL;
+    _Py_bytes_swapcase(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+                    STRINGLIB_LEN(self));
+    return newobj;
+}
diff --git a/Python-2.7.5/Objects/stringlib/fastsearch.h b/Python-2.7.5/Objects/stringlib/fastsearch.h
new file mode 100644
index 0000000..e231c58
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/fastsearch.h
@@ -0,0 +1,160 @@
+/* stringlib: fastsearch implementation */
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#define STRINGLIB_FASTSEARCH_H
+
+/* fast search/count implementation, based on a mix between boyer-
+   moore and horspool, with a few more bells and whistles on the top.
+   for some more background, see: http://effbot.org/zone/stringlib.htm */
+
+/* note: fastsearch may access s[n], which isn't a problem when using
+   Python's ordinary string types, but may cause problems if you're
+   using this code in other contexts.  also, the count mode returns -1
+   if there cannot possible be a match in the target string, and 0 if
+   it has actually checked for matches, but didn't find any.  callers
+   beware! */
+
+#define FAST_COUNT 0
+#define FAST_SEARCH 1
+#define FAST_RSEARCH 2
+
+#if LONG_BIT >= 128
+#define STRINGLIB_BLOOM_WIDTH 128
+#elif LONG_BIT >= 64
+#define STRINGLIB_BLOOM_WIDTH 64
+#elif LONG_BIT >= 32
+#define STRINGLIB_BLOOM_WIDTH 32
+#else
+#error "LONG_BIT is smaller than 32"
+#endif
+
+#define STRINGLIB_BLOOM_ADD(mask, ch) \
+    ((mask |= (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
+#define STRINGLIB_BLOOM(mask, ch)     \
+    ((mask &  (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
+
+Py_LOCAL_INLINE(Py_ssize_t)
+fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n,
+           const STRINGLIB_CHAR* p, Py_ssize_t m,
+           Py_ssize_t maxcount, int mode)
+{
+    unsigned long mask;
+    Py_ssize_t skip, count = 0;
+    Py_ssize_t i, j, mlast, w;
+
+    w = n - m;
+
+    if (w < 0 || (mode == FAST_COUNT && maxcount == 0))
+        return -1;
+
+    /* look for special cases */
+    if (m <= 1) {
+        if (m <= 0)
+            return -1;
+        /* use special case for 1-character strings */
+        if (mode == FAST_COUNT) {
+            for (i = 0; i < n; i++)
+                if (s[i] == p[0]) {
+                    count++;
+                    if (count == maxcount)
+                        return maxcount;
+                }
+            return count;
+        } else if (mode == FAST_SEARCH) {
+            for (i = 0; i < n; i++)
+                if (s[i] == p[0])
+                    return i;
+        } else {    /* FAST_RSEARCH */
+            for (i = n - 1; i > -1; i--)
+                if (s[i] == p[0])
+                    return i;
+        }
+        return -1;
+    }
+
+    mlast = m - 1;
+    skip = mlast - 1;
+    mask = 0;
+
+    if (mode != FAST_RSEARCH) {
+
+        /* create compressed boyer-moore delta 1 table */
+
+        /* process pattern[:-1] */
+        for (i = 0; i < mlast; i++) {
+            STRINGLIB_BLOOM_ADD(mask, p[i]);
+            if (p[i] == p[mlast])
+                skip = mlast - i - 1;
+        }
+        /* process pattern[-1] outside the loop */
+        STRINGLIB_BLOOM_ADD(mask, p[mlast]);
+
+        for (i = 0; i <= w; i++) {
+            /* note: using mlast in the skip path slows things down on x86 */
+            if (s[i+m-1] == p[m-1]) {
+                /* candidate match */
+                for (j = 0; j < mlast; j++)
+                    if (s[i+j] != p[j])
+                        break;
+                if (j == mlast) {
+                    /* got a match! */
+                    if (mode != FAST_COUNT)
+                        return i;
+                    count++;
+                    if (count == maxcount)
+                        return maxcount;
+                    i = i + mlast;
+                    continue;
+                }
+                /* miss: check if next character is part of pattern */
+                if (!STRINGLIB_BLOOM(mask, s[i+m]))
+                    i = i + m;
+                else
+                    i = i + skip;
+            } else {
+                /* skip: check if next character is part of pattern */
+                if (!STRINGLIB_BLOOM(mask, s[i+m]))
+                    i = i + m;
+            }
+        }
+    } else {    /* FAST_RSEARCH */
+
+        /* create compressed boyer-moore delta 1 table */
+
+        /* process pattern[0] outside the loop */
+        STRINGLIB_BLOOM_ADD(mask, p[0]);
+        /* process pattern[:0:-1] */
+        for (i = mlast; i > 0; i--) {
+            STRINGLIB_BLOOM_ADD(mask, p[i]);
+            if (p[i] == p[0])
+                skip = i - 1;
+        }
+
+        for (i = w; i >= 0; i--) {
+            if (s[i] == p[0]) {
+                /* candidate match */
+                for (j = mlast; j > 0; j--)
+                    if (s[i+j] != p[j])
+                        break;
+                if (j == 0)
+                    /* got a match! */
+                    return i;
+                /* miss: check if previous character is part of pattern */
+                if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
+                    i = i - m;
+                else
+                    i = i - skip;
+            } else {
+                /* skip: check if previous character is part of pattern */
+                if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
+                    i = i - m;
+            }
+        }
+    }
+
+    if (mode != FAST_COUNT)
+        return -1;
+    return count;
+}
+
+#endif
diff --git a/Python-2.7.5/Objects/stringlib/find.h b/Python-2.7.5/Objects/stringlib/find.h
new file mode 100644
index 0000000..ce615dc
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/find.h
@@ -0,0 +1,175 @@
+/* stringlib: find/index implementation */
+
+#ifndef STRINGLIB_FIND_H
+#define STRINGLIB_FIND_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+               const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+               Py_ssize_t offset)
+{
+    Py_ssize_t pos;
+
+    if (str_len < 0)
+        return -1;
+    if (sub_len == 0)
+        return offset;
+
+    pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_SEARCH);
+
+    if (pos >= 0)
+        pos += offset;
+
+    return pos;
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                Py_ssize_t offset)
+{
+    Py_ssize_t pos;
+
+    if (str_len < 0)
+        return -1;
+    if (sub_len == 0)
+        return str_len + offset;
+
+    pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_RSEARCH);
+
+    if (pos >= 0)
+        pos += offset;
+
+    return pos;
+}
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len)         \
+    if (end > len)                              \
+        end = len;                              \
+    else if (end < 0) {                         \
+        end += len;                             \
+        if (end < 0)                            \
+            end = 0;                            \
+    }                                           \
+    if (start < 0) {                            \
+        start += len;                           \
+        if (start < 0)                          \
+            start = 0;                          \
+    }
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                     const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                     Py_ssize_t start, Py_ssize_t end)
+{
+    ADJUST_INDICES(start, end, str_len);
+    return stringlib_find(str + start, end - start, sub, sub_len, start);
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                      const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+                      Py_ssize_t start, Py_ssize_t end)
+{
+    ADJUST_INDICES(start, end, str_len);
+    return stringlib_rfind(str + start, end - start, sub, sub_len, start);
+}
+
+#ifdef STRINGLIB_WANT_CONTAINS_OBJ
+
+Py_LOCAL_INLINE(int)
+stringlib_contains_obj(PyObject* str, PyObject* sub)
+{
+    return stringlib_find(
+        STRINGLIB_STR(str), STRINGLIB_LEN(str),
+        STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
+        ) != -1;
+}
+
+#endif /* STRINGLIB_WANT_CONTAINS_OBJ */
+
+/*
+This function is a helper for the "find" family (find, rfind, index,
+rindex) and for count, startswith and endswith, because they all have
+the same behaviour for the arguments.
+
+It does not touch the variables received until it knows everything 
+is ok.
+*/
+
+#define FORMAT_BUFFER_SIZE 50
+
+Py_LOCAL_INLINE(int)
+stringlib_parse_args_finds(const char * function_name, PyObject *args,
+                           PyObject **subobj,
+                           Py_ssize_t *start, Py_ssize_t *end)
+{
+    PyObject *tmp_subobj;
+    Py_ssize_t tmp_start = 0;
+    Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
+    PyObject *obj_start=Py_None, *obj_end=Py_None;
+    char format[FORMAT_BUFFER_SIZE] = "O|OO:";
+    size_t len = strlen(format);
+
+    strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1);
+    format[FORMAT_BUFFER_SIZE - 1] = '\0';
+
+    if (!PyArg_ParseTuple(args, format, &tmp_subobj, &obj_start, &obj_end))
+        return 0;
+
+    /* To support None in "start" and "end" arguments, meaning
+       the same as if they were not passed.
+    */
+    if (obj_start != Py_None)
+        if (!_PyEval_SliceIndex(obj_start, &tmp_start))
+            return 0;
+    if (obj_end != Py_None)
+        if (!_PyEval_SliceIndex(obj_end, &tmp_end))
+            return 0;
+
+    *start = tmp_start;
+    *end = tmp_end;
+    *subobj = tmp_subobj;
+    return 1;
+}
+
+#undef FORMAT_BUFFER_SIZE
+
+#if STRINGLIB_IS_UNICODE
+
+/*
+Wraps stringlib_parse_args_finds() and additionally ensures that the
+first argument is a unicode object.
+
+Note that we receive a pointer to the pointer of the substring object,
+so when we create that object in this function we don't DECREF it,
+because it continues living in the caller functions (those functions, 
+after finishing using the substring, must DECREF it).
+*/
+
+Py_LOCAL_INLINE(int)
+stringlib_parse_args_finds_unicode(const char * function_name, PyObject *args,
+                                   PyUnicodeObject **substring,
+                                   Py_ssize_t *start, Py_ssize_t *end)
+{
+    PyObject *tmp_substring;
+
+    if(stringlib_parse_args_finds(function_name, args, &tmp_substring,
+                                  start, end)) {
+        tmp_substring = PyUnicode_FromObject(tmp_substring);
+        if (!tmp_substring)
+            return 0;
+        *substring = (PyUnicodeObject *)tmp_substring;
+        return 1;
+    }
+    return 0;
+}
+
+#endif /* STRINGLIB_IS_UNICODE */
+
+#endif /* STRINGLIB_FIND_H */
diff --git a/Python-2.7.5/Objects/stringlib/formatter.h b/Python-2.7.5/Objects/stringlib/formatter.h
new file mode 100644
index 0000000..6b28224
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/formatter.h
@@ -0,0 +1,1529 @@
+/* implements the string, long, and float formatters.  that is,
+   string.__format__, etc. */
+
+#include <locale.h>
+
+/* Before including this, you must include either:
+   stringlib/unicodedefs.h
+   stringlib/stringdefs.h
+
+   Also, you should define the names:
+   FORMAT_STRING
+   FORMAT_LONG
+   FORMAT_FLOAT
+   FORMAT_COMPLEX
+   to be whatever you want the public names of these functions to
+   be.  These are the only non-static functions defined here.
+*/
+
+/* Raises an exception about an unknown presentation type for this
+ * type. */
+
+static void
+unknown_presentation_type(STRINGLIB_CHAR presentation_type,
+                          const char* type_name)
+{
+#if STRINGLIB_IS_UNICODE
+    /* If STRINGLIB_CHAR is Py_UNICODE, %c might be out-of-range,
+       hence the two cases. If it is char, gcc complains that the
+       condition below is always true, hence the ifdef. */
+    if (presentation_type > 32 && presentation_type < 128)
+#endif
+        PyErr_Format(PyExc_ValueError,
+                     "Unknown format code '%c' "
+                     "for object of type '%.200s'",
+                     (char)presentation_type,
+                     type_name);
+#if STRINGLIB_IS_UNICODE
+    else
+        PyErr_Format(PyExc_ValueError,
+                     "Unknown format code '\\x%x' "
+                     "for object of type '%.200s'",
+                     (unsigned int)presentation_type,
+                     type_name);
+#endif
+}
+
+static void
+invalid_comma_type(STRINGLIB_CHAR presentation_type)
+{
+#if STRINGLIB_IS_UNICODE
+    /* See comment in unknown_presentation_type */
+    if (presentation_type > 32 && presentation_type < 128)
+#endif
+        PyErr_Format(PyExc_ValueError,
+                     "Cannot specify ',' with '%c'.",
+                     (char)presentation_type);
+#if STRINGLIB_IS_UNICODE
+    else
+        PyErr_Format(PyExc_ValueError,
+                     "Cannot specify ',' with '\\x%x'.",
+                     (unsigned int)presentation_type);
+#endif
+}
+
+/*
+    get_integer consumes 0 or more decimal digit characters from an
+    input string, updates *result with the corresponding positive
+    integer, and returns the number of digits consumed.
+
+    returns -1 on error.
+*/
+static int
+get_integer(STRINGLIB_CHAR **ptr, STRINGLIB_CHAR *end,
+                  Py_ssize_t *result)
+{
+    Py_ssize_t accumulator, digitval;
+    int numdigits;
+    accumulator = numdigits = 0;
+    for (;;(*ptr)++, numdigits++) {
+        if (*ptr >= end)
+            break;
+        digitval = STRINGLIB_TODECIMAL(**ptr);
+        if (digitval < 0)
+            break;
+        /*
+           Detect possible overflow before it happens:
+
+              accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
+              accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
+        */
+        if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
+            PyErr_Format(PyExc_ValueError,
+                         "Too many decimal digits in format string");
+            return -1;
+        }
+        accumulator = accumulator * 10 + digitval;
+    }
+    *result = accumulator;
+    return numdigits;
+}
+
+/************************************************************************/
+/*********** standard format specifier parsing **************************/
+/************************************************************************/
+
+/* returns true if this character is a specifier alignment token */
+Py_LOCAL_INLINE(int)
+is_alignment_token(STRINGLIB_CHAR c)
+{
+    switch (c) {
+    case '<': case '>': case '=': case '^':
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+/* returns true if this character is a sign element */
+Py_LOCAL_INLINE(int)
+is_sign_element(STRINGLIB_CHAR c)
+{
+    switch (c) {
+    case ' ': case '+': case '-':
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+
+typedef struct {
+    STRINGLIB_CHAR fill_char;
+    STRINGLIB_CHAR align;
+    int alternate;
+    STRINGLIB_CHAR sign;
+    Py_ssize_t width;
+    int thousands_separators;
+    Py_ssize_t precision;
+    STRINGLIB_CHAR type;
+} InternalFormatSpec;
+
+
+#if 0
+/* Occassionally useful for debugging. Should normally be commented out. */
+static void
+DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
+{
+    printf("internal format spec: fill_char %d\n", format->fill_char);
+    printf("internal format spec: align %d\n", format->align);
+    printf("internal format spec: alternate %d\n", format->alternate);
+    printf("internal format spec: sign %d\n", format->sign);
+    printf("internal format spec: width %zd\n", format->width);
+    printf("internal format spec: thousands_separators %d\n",
+           format->thousands_separators);
+    printf("internal format spec: precision %zd\n", format->precision);
+    printf("internal format spec: type %c\n", format->type);
+    printf("\n");
+}
+#endif
+
+
+/*
+  ptr points to the start of the format_spec, end points just past its end.
+  fills in format with the parsed information.
+  returns 1 on success, 0 on failure.
+  if failure, sets the exception
+*/
+static int
+parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
+                                  Py_ssize_t format_spec_len,
+                                  InternalFormatSpec *format,
+                                  char default_type,
+                                  char default_align)
+{
+    STRINGLIB_CHAR *ptr = format_spec;
+    STRINGLIB_CHAR *end = format_spec + format_spec_len;
+
+    /* end-ptr is used throughout this code to specify the length of
+       the input string */
+
+    Py_ssize_t consumed;
+    int align_specified = 0;
+
+    format->fill_char = '\0';
+    format->align = default_align;
+    format->alternate = 0;
+    format->sign = '\0';
+    format->width = -1;
+    format->thousands_separators = 0;
+    format->precision = -1;
+    format->type = default_type;
+
+    /* If the second char is an alignment token,
+       then parse the fill char */
+    if (end-ptr >= 2 && is_alignment_token(ptr[1])) {
+        format->align = ptr[1];
+        format->fill_char = ptr[0];
+        align_specified = 1;
+        ptr += 2;
+    }
+    else if (end-ptr >= 1 && is_alignment_token(ptr[0])) {
+        format->align = ptr[0];
+        align_specified = 1;
+        ++ptr;
+    }
+
+    /* Parse the various sign options */
+    if (end-ptr >= 1 && is_sign_element(ptr[0])) {
+        format->sign = ptr[0];
+        ++ptr;
+    }
+
+    /* If the next character is #, we're in alternate mode.  This only
+       applies to integers. */
+    if (end-ptr >= 1 && ptr[0] == '#') {
+        format->alternate = 1;
+        ++ptr;
+    }
+
+    /* The special case for 0-padding (backwards compat) */
+    if (format->fill_char == '\0' && end-ptr >= 1 && ptr[0] == '0') {
+        format->fill_char = '0';
+        if (!align_specified) {
+            format->align = '=';
+        }
+        ++ptr;
+    }
+
+    consumed = get_integer(&ptr, end, &format->width);
+    if (consumed == -1)
+        /* Overflow error. Exception already set. */
+        return 0;
+
+    /* If consumed is 0, we didn't consume any characters for the
+       width. In that case, reset the width to -1, because
+       get_integer() will have set it to zero. -1 is how we record
+       that the width wasn't specified. */
+    if (consumed == 0)
+        format->width = -1;
+
+    /* Comma signifies add thousands separators */
+    if (end-ptr && ptr[0] == ',') {
+        format->thousands_separators = 1;
+        ++ptr;
+    }
+
+    /* Parse field precision */
+    if (end-ptr && ptr[0] == '.') {
+        ++ptr;
+
+        consumed = get_integer(&ptr, end, &format->precision);
+        if (consumed == -1)
+            /* Overflow error. Exception already set. */
+            return 0;
+
+        /* Not having a precision after a dot is an error. */
+        if (consumed == 0) {
+            PyErr_Format(PyExc_ValueError,
+                         "Format specifier missing precision");
+            return 0;
+        }
+
+    }
+
+    /* Finally, parse the type field. */
+
+    if (end-ptr > 1) {
+        /* More than one char remain, invalid conversion spec. */
+        PyErr_Format(PyExc_ValueError, "Invalid conversion specification");
+        return 0;
+    }
+
+    if (end-ptr == 1) {
+        format->type = ptr[0];
+        ++ptr;
+    }
+
+    /* Do as much validating as we can, just by looking at the format
+       specifier.  Do not take into account what type of formatting
+       we're doing (int, float, string). */
+
+    if (format->thousands_separators) {
+        switch (format->type) {
+        case 'd':
+        case 'e':
+        case 'f':
+        case 'g':
+        case 'E':
+        case 'G':
+        case '%':
+        case 'F':
+        case '\0':
+            /* These are allowed. See PEP 378.*/
+            break;
+        default:
+            invalid_comma_type(format->type);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+/* Calculate the padding needed. */
+static void
+calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align,
+             Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding,
+             Py_ssize_t *n_total)
+{
+    if (width >= 0) {
+        if (nchars > width)
+            *n_total = nchars;
+        else
+            *n_total = width;
+    }
+    else {
+        /* not specified, use all of the chars and no more */
+        *n_total = nchars;
+    }
+
+    /* Figure out how much leading space we need, based on the
+       aligning */
+    if (align == '>')
+        *n_lpadding = *n_total - nchars;
+    else if (align == '^')
+        *n_lpadding = (*n_total - nchars) / 2;
+    else if (align == '<' || align == '=')
+        *n_lpadding = 0;
+    else {
+        /* We should never have an unspecified alignment. */
+        *n_lpadding = 0;
+        assert(0);
+    }
+
+    *n_rpadding = *n_total - nchars - *n_lpadding;
+}
+
+/* Do the padding, and return a pointer to where the caller-supplied
+   content goes. */
+static STRINGLIB_CHAR *
+fill_padding(STRINGLIB_CHAR *p, Py_ssize_t nchars, STRINGLIB_CHAR fill_char,
+             Py_ssize_t n_lpadding, Py_ssize_t n_rpadding)
+{
+    /* Pad on left. */
+    if (n_lpadding)
+        STRINGLIB_FILL(p, fill_char, n_lpadding);
+
+    /* Pad on right. */
+    if (n_rpadding)
+        STRINGLIB_FILL(p + nchars + n_lpadding, fill_char, n_rpadding);
+
+    /* Pointer to the user content. */
+    return p + n_lpadding;
+}
+
+#if defined FORMAT_FLOAT || defined FORMAT_LONG || defined FORMAT_COMPLEX
+/************************************************************************/
+/*********** common routines for numeric formatting *********************/
+/************************************************************************/
+
+/* Locale type codes. */
+#define LT_CURRENT_LOCALE 0
+#define LT_DEFAULT_LOCALE 1
+#define LT_NO_LOCALE 2
+
+/* Locale info needed for formatting integers and the part of floats
+   before and including the decimal. Note that locales only support
+   8-bit chars, not unicode. */
+typedef struct {
+    char *decimal_point;
+    char *thousands_sep;
+    char *grouping;
+} LocaleInfo;
+
+/* describes the layout for an integer, see the comment in
+   calc_number_widths() for details */
+typedef struct {
+    Py_ssize_t n_lpadding;
+    Py_ssize_t n_prefix;
+    Py_ssize_t n_spadding;
+    Py_ssize_t n_rpadding;
+    char sign;
+    Py_ssize_t n_sign;      /* number of digits needed for sign (0/1) */
+    Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including
+                                    any grouping chars. */
+    Py_ssize_t n_decimal;   /* 0 if only an integer */
+    Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part,
+                               excluding the decimal itself, if
+                               present. */
+
+    /* These 2 are not the widths of fields, but are needed by
+       STRINGLIB_GROUPING. */
+    Py_ssize_t n_digits;    /* The number of digits before a decimal
+                               or exponent. */
+    Py_ssize_t n_min_width; /* The min_width we used when we computed
+                               the n_grouped_digits width. */
+} NumberFieldWidths;
+
+
+/* Given a number of the form:
+   digits[remainder]
+   where ptr points to the start and end points to the end, find where
+    the integer part ends. This could be a decimal, an exponent, both,
+    or neither.
+   If a decimal point is present, set *has_decimal and increment
+    remainder beyond it.
+   Results are undefined (but shouldn't crash) for improperly
+    formatted strings.
+*/
+static void
+parse_number(STRINGLIB_CHAR *ptr, Py_ssize_t len,
+             Py_ssize_t *n_remainder, int *has_decimal)
+{
+    STRINGLIB_CHAR *end = ptr + len;
+    STRINGLIB_CHAR *remainder;
+
+    while (ptr<end && isdigit(*ptr))
+        ++ptr;
+    remainder = ptr;
+
+    /* Does remainder start with a decimal point? */
+    *has_decimal = ptr<end && *remainder == '.';
+
+    /* Skip the decimal point. */
+    if (*has_decimal)
+        remainder++;
+
+    *n_remainder = end - remainder;
+}
+
+/* not all fields of format are used.  for example, precision is
+   unused.  should this take discrete params in order to be more clear
+   about what it does?  or is passing a single format parameter easier
+   and more efficient enough to justify a little obfuscation? */
+static Py_ssize_t
+calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
+                   STRINGLIB_CHAR sign_char, STRINGLIB_CHAR *number,
+                   Py_ssize_t n_number, Py_ssize_t n_remainder,
+                   int has_decimal, const LocaleInfo *locale,
+                   const InternalFormatSpec *format)
+{
+    Py_ssize_t n_non_digit_non_padding;
+    Py_ssize_t n_padding;
+
+    spec->n_digits = n_number - n_remainder - (has_decimal?1:0);
+    spec->n_lpadding = 0;
+    spec->n_prefix = n_prefix;
+    spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0;
+    spec->n_remainder = n_remainder;
+    spec->n_spadding = 0;
+    spec->n_rpadding = 0;
+    spec->sign = '\0';
+    spec->n_sign = 0;
+
+    /* the output will look like:
+       |                                                                                         |
+       | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> |
+       |                                                                                         |
+
+       sign is computed from format->sign and the actual
+       sign of the number
+
+       prefix is given (it's for the '0x' prefix)
+
+       digits is already known
+
+       the total width is either given, or computed from the
+       actual digits
+
+       only one of lpadding, spadding, and rpadding can be non-zero,
+       and it's calculated from the width and other fields
+    */
+
+    /* compute the various parts we're going to write */
+    switch (format->sign) {
+    case '+':
+        /* always put a + or - */
+        spec->n_sign = 1;
+        spec->sign = (sign_char == '-' ? '-' : '+');
+        break;
+    case ' ':
+        spec->n_sign = 1;
+        spec->sign = (sign_char == '-' ? '-' : ' ');
+        break;
+    default:
+        /* Not specified, or the default (-) */
+        if (sign_char == '-') {
+            spec->n_sign = 1;
+            spec->sign = '-';
+        }
+    }
+
+    /* The number of chars used for non-digits and non-padding. */
+    n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
+        spec->n_remainder;
+
+    /* min_width can go negative, that's okay. format->width == -1 means
+       we don't care. */
+    if (format->fill_char == '0' && format->align == '=')
+        spec->n_min_width = format->width - n_non_digit_non_padding;
+    else
+        spec->n_min_width = 0;
+
+    if (spec->n_digits == 0)
+        /* This case only occurs when using 'c' formatting, we need
+           to special case it because the grouping code always wants
+           to have at least one character. */
+        spec->n_grouped_digits = 0;
+    else
+        spec->n_grouped_digits = STRINGLIB_GROUPING(NULL, 0, NULL,
+                                                    spec->n_digits,
+                                                    spec->n_min_width,
+                                                    locale->grouping,
+                                                    locale->thousands_sep);
+
+    /* Given the desired width and the total of digit and non-digit
+       space we consume, see if we need any padding. format->width can
+       be negative (meaning no padding), but this code still works in
+       that case. */
+    n_padding = format->width -
+                        (n_non_digit_non_padding + spec->n_grouped_digits);
+    if (n_padding > 0) {
+        /* Some padding is needed. Determine if it's left, space, or right. */
+        switch (format->align) {
+        case '<':
+            spec->n_rpadding = n_padding;
+            break;
+        case '^':
+            spec->n_lpadding = n_padding / 2;
+            spec->n_rpadding = n_padding - spec->n_lpadding;
+            break;
+        case '=':
+            spec->n_spadding = n_padding;
+            break;
+        case '>':
+            spec->n_lpadding = n_padding;
+            break;
+        default:
+            /* Shouldn't get here, but treat it as '>' */
+            spec->n_lpadding = n_padding;
+            assert(0);
+            break;
+        }
+    }
+    return spec->n_lpadding + spec->n_sign + spec->n_prefix +
+        spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
+        spec->n_remainder + spec->n_rpadding;
+}
+
+/* Fill in the digit parts of a numbers's string representation,
+   as determined in calc_number_widths().
+   No error checking, since we know the buffer is the correct size. */
+static void
+fill_number(STRINGLIB_CHAR *buf, const NumberFieldWidths *spec,
+            STRINGLIB_CHAR *digits, Py_ssize_t n_digits,
+            STRINGLIB_CHAR *prefix, STRINGLIB_CHAR fill_char,
+            LocaleInfo *locale, int toupper)
+{
+    /* Used to keep track of digits, decimal, and remainder. */
+    STRINGLIB_CHAR *p = digits;
+
+#ifndef NDEBUG
+    Py_ssize_t r;
+#endif
+
+    if (spec->n_lpadding) {
+        STRINGLIB_FILL(buf, fill_char, spec->n_lpadding);
+        buf += spec->n_lpadding;
+    }
+    if (spec->n_sign == 1) {
+        *buf++ = spec->sign;
+    }
+    if (spec->n_prefix) {
+        memmove(buf,
+                prefix,
+                spec->n_prefix * sizeof(STRINGLIB_CHAR));
+        if (toupper) {
+            Py_ssize_t t;
+            for (t = 0; t < spec->n_prefix; ++t)
+                buf[t] = STRINGLIB_TOUPPER(buf[t]);
+        }
+        buf += spec->n_prefix;
+    }
+    if (spec->n_spadding) {
+        STRINGLIB_FILL(buf, fill_char, spec->n_spadding);
+        buf += spec->n_spadding;
+    }
+
+    /* Only for type 'c' special case, it has no digits. */
+    if (spec->n_digits != 0) {
+        /* Fill the digits with InsertThousandsGrouping. */
+#ifndef NDEBUG
+        r =
+#endif
+            STRINGLIB_GROUPING(buf, spec->n_grouped_digits, digits,
+                               spec->n_digits, spec->n_min_width,
+                               locale->grouping, locale->thousands_sep);
+#ifndef NDEBUG
+        assert(r == spec->n_grouped_digits);
+#endif
+        p += spec->n_digits;
+    }
+    if (toupper) {
+        Py_ssize_t t;
+        for (t = 0; t < spec->n_grouped_digits; ++t)
+            buf[t] = STRINGLIB_TOUPPER(buf[t]);
+    }
+    buf += spec->n_grouped_digits;
+
+    if (spec->n_decimal) {
+        Py_ssize_t t;
+        for (t = 0; t < spec->n_decimal; ++t)
+            buf[t] = locale->decimal_point[t];
+        buf += spec->n_decimal;
+        p += 1;
+    }
+
+    if (spec->n_remainder) {
+        memcpy(buf, p, spec->n_remainder * sizeof(STRINGLIB_CHAR));
+        buf += spec->n_remainder;
+        p += spec->n_remainder;
+    }
+
+    if (spec->n_rpadding) {
+        STRINGLIB_FILL(buf, fill_char, spec->n_rpadding);
+        buf += spec->n_rpadding;
+    }
+}
+
+static char no_grouping[1] = {CHAR_MAX};
+
+/* Find the decimal point character(s?), thousands_separator(s?), and
+   grouping description, either for the current locale if type is
+   LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
+   none if LT_NO_LOCALE. */
+static void
+get_locale_info(int type, LocaleInfo *locale_info)
+{
+    switch (type) {
+    case LT_CURRENT_LOCALE: {
+        struct lconv *locale_data = localeconv();
+        locale_info->decimal_point = locale_data->decimal_point;
+        locale_info->thousands_sep = locale_data->thousands_sep;
+        locale_info->grouping = locale_data->grouping;
+        break;
+    }
+    case LT_DEFAULT_LOCALE:
+        locale_info->decimal_point = ".";
+        locale_info->thousands_sep = ",";
+        locale_info->grouping = "\3"; /* Group every 3 characters.  The
+                                         (implicit) trailing 0 means repeat
+                                         infinitely. */
+        break;
+    case LT_NO_LOCALE:
+        locale_info->decimal_point = ".";
+        locale_info->thousands_sep = "";
+        locale_info->grouping = no_grouping;
+        break;
+    default:
+        assert(0);
+    }
+}
+
+#endif /* FORMAT_FLOAT || FORMAT_LONG || FORMAT_COMPLEX */
+
+/************************************************************************/
+/*********** string formatting ******************************************/
+/************************************************************************/
+
+static PyObject *
+format_string_internal(PyObject *value, const InternalFormatSpec *format)
+{
+    Py_ssize_t lpad;
+    Py_ssize_t rpad;
+    Py_ssize_t total;
+    STRINGLIB_CHAR *p;
+    Py_ssize_t len = STRINGLIB_LEN(value);
+    PyObject *result = NULL;
+
+    /* sign is not allowed on strings */
+    if (format->sign != '\0') {
+        PyErr_SetString(PyExc_ValueError,
+                        "Sign not allowed in string format specifier");
+        goto done;
+    }
+
+    /* alternate is not allowed on strings */
+    if (format->alternate) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Alternate form (#) not allowed in string format "
+                        "specifier");
+        goto done;
+    }
+
+    /* '=' alignment not allowed on strings */
+    if (format->align == '=') {
+        PyErr_SetString(PyExc_ValueError,
+                        "'=' alignment not allowed "
+                        "in string format specifier");
+        goto done;
+    }
+
+    /* if precision is specified, output no more that format.precision
+       characters */
+    if (format->precision >= 0 && len >= format->precision) {
+        len = format->precision;
+    }
+
+    calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
+
+    /* allocate the resulting string */
+    result = STRINGLIB_NEW(NULL, total);
+    if (result == NULL)
+        goto done;
+
+    /* Write into that space. First the padding. */
+    p = fill_padding(STRINGLIB_STR(result), len,
+                     format->fill_char=='\0'?' ':format->fill_char,
+                     lpad, rpad);
+
+    /* Then the source string. */
+    memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR));
+
+done:
+    return result;
+}
+
+
+/************************************************************************/
+/*********** long formatting ********************************************/
+/************************************************************************/
+
+#if defined FORMAT_LONG || defined FORMAT_INT
+typedef PyObject*
+(*IntOrLongToString)(PyObject *value, int base);
+
+static PyObject *
+format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
+                            IntOrLongToString tostring)
+{
+    PyObject *result = NULL;
+    PyObject *tmp = NULL;
+    STRINGLIB_CHAR *pnumeric_chars;
+    STRINGLIB_CHAR numeric_char;
+    STRINGLIB_CHAR sign_char = '\0';
+    Py_ssize_t n_digits;       /* count of digits need from the computed
+                                  string */
+    Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
+                                   produces non-digits */
+    Py_ssize_t n_prefix = 0;   /* Count of prefix chars, (e.g., '0x') */
+    Py_ssize_t n_total;
+    STRINGLIB_CHAR *prefix = NULL;
+    NumberFieldWidths spec;
+    long x;
+
+    /* Locale settings, either from the actual locale or
+       from a hard-code pseudo-locale */
+    LocaleInfo locale;
+
+    /* no precision allowed on integers */
+    if (format->precision != -1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Precision not allowed in integer format specifier");
+        goto done;
+    }
+
+    /* special case for character formatting */
+    if (format->type == 'c') {
+        /* error to specify a sign */
+        if (format->sign != '\0') {
+            PyErr_SetString(PyExc_ValueError,
+                            "Sign not allowed with integer"
+                            " format specifier 'c'");
+            goto done;
+        }
+
+        /* Error to specify a comma. */
+        if (format->thousands_separators) {
+            PyErr_SetString(PyExc_ValueError,
+                            "Thousands separators not allowed with integer"
+                            " format specifier 'c'");
+            goto done;
+        }
+
+        /* taken from unicodeobject.c formatchar() */
+        /* Integer input truncated to a character */
+/* XXX: won't work for int */
+        x = PyLong_AsLong(value);
+        if (x == -1 && PyErr_Occurred())
+            goto done;
+#ifdef Py_UNICODE_WIDE
+        if (x < 0 || x > 0x10ffff) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "%c arg not in range(0x110000) "
+                            "(wide Python build)");
+            goto done;
+        }
+#else
+        if (x < 0 || x > 0xffff) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "%c arg not in range(0x10000) "
+                            "(narrow Python build)");
+            goto done;
+        }
+#endif
+        numeric_char = (STRINGLIB_CHAR)x;
+        pnumeric_chars = &numeric_char;
+        n_digits = 1;
+
+        /* As a sort-of hack, we tell calc_number_widths that we only
+           have "remainder" characters. calc_number_widths thinks
+           these are characters that don't get formatted, only copied
+           into the output string. We do this for 'c' formatting,
+           because the characters are likely to be non-digits. */
+        n_remainder = 1;
+    }
+    else {
+        int base;
+        int leading_chars_to_skip = 0;  /* Number of characters added by
+                                           PyNumber_ToBase that we want to
+                                           skip over. */
+
+        /* Compute the base and how many characters will be added by
+           PyNumber_ToBase */
+        switch (format->type) {
+        case 'b':
+            base = 2;
+            leading_chars_to_skip = 2; /* 0b */
+            break;
+        case 'o':
+            base = 8;
+            leading_chars_to_skip = 2; /* 0o */
+            break;
+        case 'x':
+        case 'X':
+            base = 16;
+            leading_chars_to_skip = 2; /* 0x */
+            break;
+        default:  /* shouldn't be needed, but stops a compiler warning */
+        case 'd':
+        case 'n':
+            base = 10;
+            break;
+        }
+
+        /* The number of prefix chars is the same as the leading
+           chars to skip */
+        if (format->alternate)
+            n_prefix = leading_chars_to_skip;
+
+        /* Do the hard part, converting to a string in a given base */
+        tmp = tostring(value, base);
+        if (tmp == NULL)
+            goto done;
+
+        pnumeric_chars = STRINGLIB_STR(tmp);
+        n_digits = STRINGLIB_LEN(tmp);
+
+        prefix = pnumeric_chars;
+
+        /* Remember not to modify what pnumeric_chars points to.  it
+           might be interned.  Only modify it after we copy it into a
+           newly allocated output buffer. */
+
+        /* Is a sign character present in the output?  If so, remember it
+           and skip it */
+        if (pnumeric_chars[0] == '-') {
+            sign_char = pnumeric_chars[0];
+            ++prefix;
+            ++leading_chars_to_skip;
+        }
+
+        /* Skip over the leading chars (0x, 0b, etc.) */
+        n_digits -= leading_chars_to_skip;
+        pnumeric_chars += leading_chars_to_skip;
+    }
+
+    /* Determine the grouping, separator, and decimal point, if any. */
+    get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+                    (format->thousands_separators ?
+                     LT_DEFAULT_LOCALE :
+                     LT_NO_LOCALE),
+                    &locale);
+
+    /* Calculate how much memory we'll need. */
+    n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars,
+                       n_digits, n_remainder, 0, &locale, format);
+
+    /* Allocate the memory. */
+    result = STRINGLIB_NEW(NULL, n_total);
+    if (!result)
+        goto done;
+
+    /* Populate the memory. */
+    fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits,
+                prefix, format->fill_char == '\0' ? ' ' : format->fill_char,
+                &locale, format->type == 'X');
+
+done:
+    Py_XDECREF(tmp);
+    return result;
+}
+#endif /* defined FORMAT_LONG || defined FORMAT_INT */
+
+/************************************************************************/
+/*********** float formatting *******************************************/
+/************************************************************************/
+
+#ifdef FORMAT_FLOAT
+#if STRINGLIB_IS_UNICODE
+static void
+strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len)
+{
+    Py_ssize_t i;
+    for (i = 0; i < len; ++i)
+        buffer[i] = (Py_UNICODE)charbuffer[i];
+}
+#endif
+
+/* much of this is taken from unicodeobject.c */
+static PyObject *
+format_float_internal(PyObject *value,
+                      const InternalFormatSpec *format)
+{
+    char *buf = NULL;       /* buffer returned from PyOS_double_to_string */
+    Py_ssize_t n_digits;
+    Py_ssize_t n_remainder;
+    Py_ssize_t n_total;
+    int has_decimal;
+    double val;
+    Py_ssize_t precision = format->precision;
+    Py_ssize_t default_precision = 6;
+    STRINGLIB_CHAR type = format->type;
+    int add_pct = 0;
+    STRINGLIB_CHAR *p;
+    NumberFieldWidths spec;
+    int flags = 0;
+    PyObject *result = NULL;
+    STRINGLIB_CHAR sign_char = '\0';
+    int float_type; /* Used to see if we have a nan, inf, or regular float. */
+
+#if STRINGLIB_IS_UNICODE
+    Py_UNICODE *unicode_tmp = NULL;
+#endif
+
+    /* Locale settings, either from the actual locale or
+       from a hard-code pseudo-locale */
+    LocaleInfo locale;
+
+    /* Alternate is not allowed on floats. */
+    if (format->alternate) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Alternate form (#) not allowed in float format "
+                        "specifier");
+        goto done;
+    }
+
+    if (type == '\0') {
+        /* Omitted type specifier. This is like 'g' but with at least one
+           digit after the decimal point, and different default precision.*/
+        type = 'g';
+        default_precision = PyFloat_STR_PRECISION;
+        flags |= Py_DTSF_ADD_DOT_0;
+    }
+
+    if (type == 'n')
+        /* 'n' is the same as 'g', except for the locale used to
+           format the result. We take care of that later. */
+        type = 'g';
+
+    val = PyFloat_AsDouble(value);
+    if (val == -1.0 && PyErr_Occurred())
+        goto done;
+
+    if (type == '%') {
+        type = 'f';
+        val *= 100;
+        add_pct = 1;
+    }
+
+    if (precision < 0)
+        precision = default_precision;
+
+    /* Cast "type", because if we're in unicode we need to pass a
+       8-bit char. This is safe, because we've restricted what "type"
+       can be. */
+    buf = PyOS_double_to_string(val, (char)type, precision, flags,
+                                &float_type);
+    if (buf == NULL)
+        goto done;
+    n_digits = strlen(buf);
+
+    if (add_pct) {
+        /* We know that buf has a trailing zero (since we just called
+           strlen() on it), and we don't use that fact any more. So we
+           can just write over the trailing zero. */
+        buf[n_digits] = '%';
+        n_digits += 1;
+    }
+
+    /* Since there is no unicode version of PyOS_double_to_string,
+       just use the 8 bit version and then convert to unicode. */
+#if STRINGLIB_IS_UNICODE
+    unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE));
+    if (unicode_tmp == NULL) {
+        PyErr_NoMemory();
+        goto done;
+    }
+    strtounicode(unicode_tmp, buf, n_digits);
+    p = unicode_tmp;
+#else
+    p = buf;
+#endif
+
+    /* Is a sign character present in the output?  If so, remember it
+       and skip it */
+    if (*p == '-') {
+        sign_char = *p;
+        ++p;
+        --n_digits;
+    }
+
+    /* Determine if we have any "remainder" (after the digits, might include
+       decimal or exponent or both (or neither)) */
+    parse_number(p, n_digits, &n_remainder, &has_decimal);
+
+    /* Determine the grouping, separator, and decimal point, if any. */
+    get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+                    (format->thousands_separators ?
+                     LT_DEFAULT_LOCALE :
+                     LT_NO_LOCALE),
+                    &locale);
+
+    /* Calculate how much memory we'll need. */
+    n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits,
+                                 n_remainder, has_decimal, &locale, format);
+
+    /* Allocate the memory. */
+    result = STRINGLIB_NEW(NULL, n_total);
+    if (result == NULL)
+        goto done;
+
+    /* Populate the memory. */
+    fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL,
+                format->fill_char == '\0' ? ' ' : format->fill_char, &locale,
+                0);
+
+done:
+    PyMem_Free(buf);
+#if STRINGLIB_IS_UNICODE
+    PyMem_Free(unicode_tmp);
+#endif
+    return result;
+}
+#endif /* FORMAT_FLOAT */
+
+/************************************************************************/
+/*********** complex formatting *****************************************/
+/************************************************************************/
+
+#ifdef FORMAT_COMPLEX
+
+static PyObject *
+format_complex_internal(PyObject *value,
+                        const InternalFormatSpec *format)
+{
+    double re;
+    double im;
+    char *re_buf = NULL;       /* buffer returned from PyOS_double_to_string */
+    char *im_buf = NULL;       /* buffer returned from PyOS_double_to_string */
+
+    InternalFormatSpec tmp_format = *format;
+    Py_ssize_t n_re_digits;
+    Py_ssize_t n_im_digits;
+    Py_ssize_t n_re_remainder;
+    Py_ssize_t n_im_remainder;
+    Py_ssize_t n_re_total;
+    Py_ssize_t n_im_total;
+    int re_has_decimal;
+    int im_has_decimal;
+    Py_ssize_t precision = format->precision;
+    Py_ssize_t default_precision = 6;
+    STRINGLIB_CHAR type = format->type;
+    STRINGLIB_CHAR *p_re;
+    STRINGLIB_CHAR *p_im;
+    NumberFieldWidths re_spec;
+    NumberFieldWidths im_spec;
+    int flags = 0;
+    PyObject *result = NULL;
+    STRINGLIB_CHAR *p;
+    STRINGLIB_CHAR re_sign_char = '\0';
+    STRINGLIB_CHAR im_sign_char = '\0';
+    int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
+    int im_float_type;
+    int add_parens = 0;
+    int skip_re = 0;
+    Py_ssize_t lpad;
+    Py_ssize_t rpad;
+    Py_ssize_t total;
+
+#if STRINGLIB_IS_UNICODE
+    Py_UNICODE *re_unicode_tmp = NULL;
+    Py_UNICODE *im_unicode_tmp = NULL;
+#endif
+
+    /* Locale settings, either from the actual locale or
+       from a hard-code pseudo-locale */
+    LocaleInfo locale;
+
+    /* Alternate is not allowed on complex. */
+    if (format->alternate) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Alternate form (#) not allowed in complex format "
+                        "specifier");
+        goto done;
+    }
+
+    /* Neither is zero pading. */
+    if (format->fill_char == '0') {
+        PyErr_SetString(PyExc_ValueError,
+                        "Zero padding is not allowed in complex format "
+                        "specifier");
+        goto done;
+    }
+
+    /* Neither is '=' alignment . */
+    if (format->align == '=') {
+        PyErr_SetString(PyExc_ValueError,
+                        "'=' alignment flag is not allowed in complex format "
+                        "specifier");
+        goto done;
+    }
+
+    re = PyComplex_RealAsDouble(value);
+    if (re == -1.0 && PyErr_Occurred())
+        goto done;
+    im = PyComplex_ImagAsDouble(value);
+    if (im == -1.0 && PyErr_Occurred())
+        goto done;
+
+    if (type == '\0') {
+        /* Omitted type specifier. Should be like str(self). */
+        type = 'g';
+        default_precision = PyFloat_STR_PRECISION;
+        if (re == 0.0 && copysign(1.0, re) == 1.0)
+            skip_re = 1;
+        else
+            add_parens = 1;
+    }
+
+    if (type == 'n')
+        /* 'n' is the same as 'g', except for the locale used to
+           format the result. We take care of that later. */
+        type = 'g';
+
+    if (precision < 0)
+        precision = default_precision;
+
+    /* Cast "type", because if we're in unicode we need to pass a
+       8-bit char. This is safe, because we've restricted what "type"
+       can be. */
+    re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
+                                   &re_float_type);
+    if (re_buf == NULL)
+        goto done;
+    im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
+                                   &im_float_type);
+    if (im_buf == NULL)
+        goto done;
+
+    n_re_digits = strlen(re_buf);
+    n_im_digits = strlen(im_buf);
+
+    /* Since there is no unicode version of PyOS_double_to_string,
+       just use the 8 bit version and then convert to unicode. */
+#if STRINGLIB_IS_UNICODE
+    re_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_re_digits)*sizeof(Py_UNICODE));
+    if (re_unicode_tmp == NULL) {
+        PyErr_NoMemory();
+        goto done;
+    }
+    strtounicode(re_unicode_tmp, re_buf, n_re_digits);
+    p_re = re_unicode_tmp;
+
+    im_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_im_digits)*sizeof(Py_UNICODE));
+    if (im_unicode_tmp == NULL) {
+        PyErr_NoMemory();
+        goto done;
+    }
+    strtounicode(im_unicode_tmp, im_buf, n_im_digits);
+    p_im = im_unicode_tmp;
+#else
+    p_re = re_buf;
+    p_im = im_buf;
+#endif
+
+    /* Is a sign character present in the output?  If so, remember it
+       and skip it */
+    if (*p_re == '-') {
+        re_sign_char = *p_re;
+        ++p_re;
+        --n_re_digits;
+    }
+    if (*p_im == '-') {
+        im_sign_char = *p_im;
+        ++p_im;
+        --n_im_digits;
+    }
+
+    /* Determine if we have any "remainder" (after the digits, might include
+       decimal or exponent or both (or neither)) */
+    parse_number(p_re, n_re_digits, &n_re_remainder, &re_has_decimal);
+    parse_number(p_im, n_im_digits, &n_im_remainder, &im_has_decimal);
+
+    /* Determine the grouping, separator, and decimal point, if any. */
+    get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+                    (format->thousands_separators ?
+                     LT_DEFAULT_LOCALE :
+                     LT_NO_LOCALE),
+                    &locale);
+
+    /* Turn off any padding. We'll do it later after we've composed
+       the numbers without padding. */
+    tmp_format.fill_char = '\0';
+    tmp_format.align = '<';
+    tmp_format.width = -1;
+
+    /* Calculate how much memory we'll need. */
+    n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, p_re,
+                                    n_re_digits, n_re_remainder,
+                                    re_has_decimal, &locale, &tmp_format);
+
+    /* Same formatting, but always include a sign, unless the real part is
+     * going to be omitted, in which case we use whatever sign convention was
+     * requested by the original format. */
+    if (!skip_re)
+        tmp_format.sign = '+';
+    n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, p_im,
+                                    n_im_digits, n_im_remainder,
+                                    im_has_decimal, &locale, &tmp_format);
+
+    if (skip_re)
+        n_re_total = 0;
+
+    /* Add 1 for the 'j', and optionally 2 for parens. */
+    calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
+                 format->width, format->align, &lpad, &rpad, &total);
+
+    result = STRINGLIB_NEW(NULL, total);
+    if (result == NULL)
+        goto done;
+
+    /* Populate the memory. First, the padding. */
+    p = fill_padding(STRINGLIB_STR(result),
+                     n_re_total + n_im_total + 1 + add_parens * 2,
+                     format->fill_char=='\0' ? ' ' : format->fill_char,
+                     lpad, rpad);
+
+    if (add_parens)
+        *p++ = '(';
+
+    if (!skip_re) {
+        fill_number(p, &re_spec, p_re, n_re_digits, NULL, 0, &locale, 0);
+        p += n_re_total;
+    }
+    fill_number(p, &im_spec, p_im, n_im_digits, NULL, 0, &locale, 0);
+    p += n_im_total;
+    *p++ = 'j';
+
+    if (add_parens)
+        *p++ = ')';
+
+done:
+    PyMem_Free(re_buf);
+    PyMem_Free(im_buf);
+#if STRINGLIB_IS_UNICODE
+    PyMem_Free(re_unicode_tmp);
+    PyMem_Free(im_unicode_tmp);
+#endif
+    return result;
+}
+#endif /* FORMAT_COMPLEX */
+
+/************************************************************************/
+/*********** built in formatters ****************************************/
+/************************************************************************/
+PyObject *
+FORMAT_STRING(PyObject *obj,
+              STRINGLIB_CHAR *format_spec,
+              Py_ssize_t format_spec_len)
+{
+    InternalFormatSpec format;
+    PyObject *result = NULL;
+
+    /* check for the special case of zero length format spec, make
+       it equivalent to str(obj) */
+    if (format_spec_len == 0) {
+        result = STRINGLIB_TOSTR(obj);
+        goto done;
+    }
+
+    /* parse the format_spec */
+    if (!parse_internal_render_format_spec(format_spec, format_spec_len,
+                                           &format, 's', '<'))
+        goto done;
+
+    /* type conversion? */
+    switch (format.type) {
+    case 's':
+        /* no type conversion needed, already a string.  do the formatting */
+        result = format_string_internal(obj, &format);
+        break;
+    default:
+        /* unknown */
+        unknown_presentation_type(format.type, obj->ob_type->tp_name);
+        goto done;
+    }
+
+done:
+    return result;
+}
+
+#if defined FORMAT_LONG || defined FORMAT_INT
+static PyObject*
+format_int_or_long(PyObject* obj,
+                   STRINGLIB_CHAR *format_spec,
+                   Py_ssize_t format_spec_len,
+                   IntOrLongToString tostring)
+{
+    PyObject *result = NULL;
+    PyObject *tmp = NULL;
+    InternalFormatSpec format;
+
+    /* check for the special case of zero length format spec, make
+       it equivalent to str(obj) */
+    if (format_spec_len == 0) {
+        result = STRINGLIB_TOSTR(obj);
+        goto done;
+    }
+
+    /* parse the format_spec */
+    if (!parse_internal_render_format_spec(format_spec,
+                                           format_spec_len,
+                                           &format, 'd', '>'))
+        goto done;
+
+    /* type conversion? */
+    switch (format.type) {
+    case 'b':
+    case 'c':
+    case 'd':
+    case 'o':
+    case 'x':
+    case 'X':
+    case 'n':
+        /* no type conversion needed, already an int (or long).  do
+           the formatting */
+            result = format_int_or_long_internal(obj, &format, tostring);
+        break;
+
+    case 'e':
+    case 'E':
+    case 'f':
+    case 'F':
+    case 'g':
+    case 'G':
+    case '%':
+        /* convert to float */
+        tmp = PyNumber_Float(obj);
+        if (tmp == NULL)
+            goto done;
+        result = format_float_internal(tmp, &format);
+        break;
+
+    default:
+        /* unknown */
+        unknown_presentation_type(format.type, obj->ob_type->tp_name);
+        goto done;
+    }
+
+done:
+    Py_XDECREF(tmp);
+    return result;
+}
+#endif /* FORMAT_LONG || defined FORMAT_INT */
+
+#ifdef FORMAT_LONG
+/* Need to define long_format as a function that will convert a long
+   to a string.  In 3.0, _PyLong_Format has the correct signature.  In
+   2.x, we need to fudge a few parameters */
+#if PY_VERSION_HEX >= 0x03000000
+#define long_format _PyLong_Format
+#else
+static PyObject*
+long_format(PyObject* value, int base)
+{
+    /* Convert to base, don't add trailing 'L', and use the new octal
+       format. We already know this is a long object */
+    assert(PyLong_Check(value));
+    /* convert to base, don't add 'L', and use the new octal format */
+    return _PyLong_Format(value, base, 0, 1);
+}
+#endif
+
+PyObject *
+FORMAT_LONG(PyObject *obj,
+            STRINGLIB_CHAR *format_spec,
+            Py_ssize_t format_spec_len)
+{
+    return format_int_or_long(obj, format_spec, format_spec_len,
+                              long_format);
+}
+#endif /* FORMAT_LONG */
+
+#ifdef FORMAT_INT
+/* this is only used for 2.x, not 3.0 */
+static PyObject*
+int_format(PyObject* value, int base)
+{
+    /* Convert to base, and use the new octal format. We already
+       know this is an int object */
+    assert(PyInt_Check(value));
+    return _PyInt_Format((PyIntObject*)value, base, 1);
+}
+
+PyObject *
+FORMAT_INT(PyObject *obj,
+           STRINGLIB_CHAR *format_spec,
+           Py_ssize_t format_spec_len)
+{
+    return format_int_or_long(obj, format_spec, format_spec_len,
+                              int_format);
+}
+#endif /* FORMAT_INT */
+
+#ifdef FORMAT_FLOAT
+PyObject *
+FORMAT_FLOAT(PyObject *obj,
+             STRINGLIB_CHAR *format_spec,
+             Py_ssize_t format_spec_len)
+{
+    PyObject *result = NULL;
+    InternalFormatSpec format;
+
+    /* check for the special case of zero length format spec, make
+       it equivalent to str(obj) */
+    if (format_spec_len == 0) {
+        result = STRINGLIB_TOSTR(obj);
+        goto done;
+    }
+
+    /* parse the format_spec */
+    if (!parse_internal_render_format_spec(format_spec,
+                                           format_spec_len,
+                                           &format, '\0', '>'))
+        goto done;
+
+    /* type conversion? */
+    switch (format.type) {
+    case '\0': /* No format code: like 'g', but with at least one decimal. */
+    case 'e':
+    case 'E':
+    case 'f':
+    case 'F':
+    case 'g':
+    case 'G':
+    case 'n':
+    case '%':
+        /* no conversion, already a float.  do the formatting */
+        result = format_float_internal(obj, &format);
+        break;
+
+    default:
+        /* unknown */
+        unknown_presentation_type(format.type, obj->ob_type->tp_name);
+        goto done;
+    }
+
+done:
+    return result;
+}
+#endif /* FORMAT_FLOAT */
+
+#ifdef FORMAT_COMPLEX
+PyObject *
+FORMAT_COMPLEX(PyObject *obj,
+               STRINGLIB_CHAR *format_spec,
+               Py_ssize_t format_spec_len)
+{
+    PyObject *result = NULL;
+    InternalFormatSpec format;
+
+    /* check for the special case of zero length format spec, make
+       it equivalent to str(obj) */
+    if (format_spec_len == 0) {
+        result = STRINGLIB_TOSTR(obj);
+        goto done;
+    }
+
+    /* parse the format_spec */
+    if (!parse_internal_render_format_spec(format_spec,
+                                           format_spec_len,
+                                           &format, '\0', '>'))
+        goto done;
+
+    /* type conversion? */
+    switch (format.type) {
+    case '\0': /* No format code: like 'g', but with at least one decimal. */
+    case 'e':
+    case 'E':
+    case 'f':
+    case 'F':
+    case 'g':
+    case 'G':
+    case 'n':
+        /* no conversion, already a complex.  do the formatting */
+        result = format_complex_internal(obj, &format);
+        break;
+
+    default:
+        /* unknown */
+        unknown_presentation_type(format.type, obj->ob_type->tp_name);
+        goto done;
+    }
+
+done:
+    return result;
+}
+#endif /* FORMAT_COMPLEX */
diff --git a/Python-2.7.5/Objects/stringlib/localeutil.h b/Python-2.7.5/Objects/stringlib/localeutil.h
new file mode 100644
index 0000000..f548133
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/localeutil.h
@@ -0,0 +1,212 @@
+/* stringlib: locale related helpers implementation */
+
+#ifndef STRINGLIB_LOCALEUTIL_H
+#define STRINGLIB_LOCALEUTIL_H
+
+#include <locale.h>
+
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+typedef struct {
+    const char *grouping;
+    char previous;
+    Py_ssize_t i; /* Where we're currently pointing in grouping. */
+} GroupGenerator;
+
+static void
+_GroupGenerator_init(GroupGenerator *self, const char *grouping)
+{
+    self->grouping = grouping;
+    self->i = 0;
+    self->previous = 0;
+}
+
+/* Returns the next grouping, or 0 to signify end. */
+static Py_ssize_t
+_GroupGenerator_next(GroupGenerator *self)
+{
+    /* Note that we don't really do much error checking here. If a
+       grouping string contains just CHAR_MAX, for example, then just
+       terminate the generator. That shouldn't happen, but at least we
+       fail gracefully. */
+    switch (self->grouping[self->i]) {
+    case 0:
+        return self->previous;
+    case CHAR_MAX:
+        /* Stop the generator. */
+        return 0;
+    default: {
+        char ch = self->grouping[self->i];
+        self->previous = ch;
+        self->i++;
+        return (Py_ssize_t)ch;
+    }
+    }
+}
+
+/* Fill in some digits, leading zeros, and thousands separator. All
+   are optional, depending on when we're called. */
+static void
+fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
+     Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep,
+     Py_ssize_t thousands_sep_len)
+{
+#if STRINGLIB_IS_UNICODE
+    Py_ssize_t i;
+#endif
+
+    if (thousands_sep) {
+        *buffer_end -= thousands_sep_len;
+
+        /* Copy the thousands_sep chars into the buffer. */
+#if STRINGLIB_IS_UNICODE
+        /* Convert from the char's of the thousands_sep from
+           the locale into unicode. */
+        for (i = 0; i < thousands_sep_len; ++i)
+            (*buffer_end)[i] = thousands_sep[i];
+#else
+        /* No conversion, just memcpy the thousands_sep. */
+        memcpy(*buffer_end, thousands_sep, thousands_sep_len);
+#endif
+    }
+
+    *buffer_end -= n_chars;
+    *digits_end -= n_chars;
+    memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR));
+
+    *buffer_end -= n_zeros;
+    STRINGLIB_FILL(*buffer_end, '0', n_zeros);
+}
+
+/**
+ * _Py_InsertThousandsGrouping:
+ * @buffer: A pointer to the start of a string.
+ * @n_buffer: Number of characters in @buffer.
+ * @digits: A pointer to the digits we're reading from. If count
+ *          is non-NULL, this is unused.
+ * @n_digits: The number of digits in the string, in which we want
+ *            to put the grouping chars.
+ * @min_width: The minimum width of the digits in the output string.
+ *             Output will be zero-padded on the left to fill.
+ * @grouping: see definition in localeconv().
+ * @thousands_sep: see definition in localeconv().
+ *
+ * There are 2 modes: counting and filling. If @buffer is NULL,
+ *  we are in counting mode, else filling mode.
+ * If counting, the required buffer size is returned.
+ * If filling, we know the buffer will be large enough, so we don't
+ *  need to pass in the buffer size.
+ * Inserts thousand grouping characters (as defined by grouping and
+ *  thousands_sep) into the string between buffer and buffer+n_digits.
+ *
+ * Return value: 0 on error, else 1.  Note that no error can occur if
+ *  count is non-NULL.
+ *
+ * This name won't be used, the includer of this file should define
+ *  it to be the actual function name, based on unicode or string.
+ *
+ * As closely as possible, this code mimics the logic in decimal.py's
+    _insert_thousands_sep().
+ **/
+Py_ssize_t
+_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
+                            Py_ssize_t n_buffer,
+                            STRINGLIB_CHAR *digits,
+                            Py_ssize_t n_digits,
+                            Py_ssize_t min_width,
+                            const char *grouping,
+                            const char *thousands_sep)
+{
+    Py_ssize_t count = 0;
+    Py_ssize_t n_zeros;
+    int loop_broken = 0;
+    int use_separator = 0; /* First time through, don't append the
+                              separator. They only go between
+                              groups. */
+    STRINGLIB_CHAR *buffer_end = NULL;
+    STRINGLIB_CHAR *digits_end = NULL;
+    Py_ssize_t l;
+    Py_ssize_t n_chars;
+    Py_ssize_t thousands_sep_len = strlen(thousands_sep);
+    Py_ssize_t remaining = n_digits; /* Number of chars remaining to
+                                        be looked at */
+    /* A generator that returns all of the grouping widths, until it
+       returns 0. */
+    GroupGenerator groupgen;
+    _GroupGenerator_init(&groupgen, grouping);
+
+    if (buffer) {
+        buffer_end = buffer + n_buffer;
+        digits_end = digits + n_digits;
+    }
+
+    while ((l = _GroupGenerator_next(&groupgen)) > 0) {
+        l = MIN(l, MAX(MAX(remaining, min_width), 1));
+        n_zeros = MAX(0, l - remaining);
+        n_chars = MAX(0, MIN(remaining, l));
+
+        /* Use n_zero zero's and n_chars chars */
+
+        /* Count only, don't do anything. */
+        count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
+
+        if (buffer) {
+            /* Copy into the output buffer. */
+            fill(&digits_end, &buffer_end, n_chars, n_zeros,
+                 use_separator ? thousands_sep : NULL, thousands_sep_len);
+        }
+
+        /* Use a separator next time. */
+        use_separator = 1;
+
+        remaining -= n_chars;
+        min_width -= l;
+
+        if (remaining <= 0 && min_width <= 0) {
+            loop_broken = 1;
+            break;
+        }
+        min_width -= thousands_sep_len;
+    }
+    if (!loop_broken) {
+        /* We left the loop without using a break statement. */
+
+        l = MAX(MAX(remaining, min_width), 1);
+        n_zeros = MAX(0, l - remaining);
+        n_chars = MAX(0, MIN(remaining, l));
+
+        /* Use n_zero zero's and n_chars chars */
+        count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
+        if (buffer) {
+            /* Copy into the output buffer. */
+            fill(&digits_end, &buffer_end, n_chars, n_zeros,
+                 use_separator ? thousands_sep : NULL, thousands_sep_len);
+        }
+    }
+    return count;
+}
+
+/**
+ * _Py_InsertThousandsGroupingLocale:
+ * @buffer: A pointer to the start of a string.
+ * @n_digits: The number of digits in the string, in which we want
+ *            to put the grouping chars.
+ *
+ * Reads thee current locale and calls _Py_InsertThousandsGrouping().
+ **/
+Py_ssize_t
+_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer,
+                                  Py_ssize_t n_buffer,
+                                  STRINGLIB_CHAR *digits,
+                                  Py_ssize_t n_digits,
+                                  Py_ssize_t min_width)
+{
+        struct lconv *locale_data = localeconv();
+        const char *grouping = locale_data->grouping;
+        const char *thousands_sep = locale_data->thousands_sep;
+
+        return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits,
+                                           min_width, grouping, thousands_sep);
+}
+#endif /* STRINGLIB_LOCALEUTIL_H */
diff --git a/Python-2.7.5/Objects/stringlib/partition.h b/Python-2.7.5/Objects/stringlib/partition.h
new file mode 100644
index 0000000..0170bdd
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/partition.h
@@ -0,0 +1,110 @@
+/* stringlib: partition implementation */
+
+#ifndef STRINGLIB_PARTITION_H
+#define STRINGLIB_PARTITION_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(PyObject*)
+stringlib_partition(PyObject* str_obj,
+                    const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                    PyObject* sep_obj,
+                    const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
+{
+    PyObject* out;
+    Py_ssize_t pos;
+
+    if (sep_len == 0) {
+        PyErr_SetString(PyExc_ValueError, "empty separator");
+        return NULL;
+    }
+
+    out = PyTuple_New(3);
+    if (!out)
+        return NULL;
+
+    pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_SEARCH);
+
+    if (pos < 0) {
+#if STRINGLIB_MUTABLE
+        PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
+        PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
+        PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
+#else
+        Py_INCREF(str_obj);
+        PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
+        Py_INCREF(STRINGLIB_EMPTY);
+        PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+        Py_INCREF(STRINGLIB_EMPTY);
+        PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
+#endif
+        return out;
+    }
+
+    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
+    Py_INCREF(sep_obj);
+    PyTuple_SET_ITEM(out, 1, sep_obj);
+    pos += sep_len;
+    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+Py_LOCAL_INLINE(PyObject*)
+stringlib_rpartition(PyObject* str_obj,
+                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                     PyObject* sep_obj,
+                     const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
+{
+    PyObject* out;
+    Py_ssize_t pos;
+
+    if (sep_len == 0) {
+        PyErr_SetString(PyExc_ValueError, "empty separator");
+        return NULL;
+    }
+
+    out = PyTuple_New(3);
+    if (!out)
+        return NULL;
+
+    pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
+
+    if (pos < 0) {
+#if STRINGLIB_MUTABLE
+        PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
+        PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
+        PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
+#else
+        Py_INCREF(STRINGLIB_EMPTY);
+        PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
+        Py_INCREF(STRINGLIB_EMPTY);
+        PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+        Py_INCREF(str_obj);
+        PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
+#endif
+        return out;
+    }
+
+    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
+    Py_INCREF(sep_obj);
+    PyTuple_SET_ITEM(out, 1, sep_obj);
+    pos += sep_len;
+    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
+
+    if (PyErr_Occurred()) {
+        Py_DECREF(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+#endif
diff --git a/Python-2.7.5/Objects/stringlib/split.h b/Python-2.7.5/Objects/stringlib/split.h
new file mode 100644
index 0000000..60e7767
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/split.h
@@ -0,0 +1,394 @@
+/* stringlib: split implementation */
+
+#ifndef STRINGLIB_SPLIT_H
+#define STRINGLIB_SPLIT_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+/* Overallocate the initial list to reduce the number of reallocs for small
+   split sizes.  Eg, "A A A A A A A A A A".split() (10 elements) has three
+   resizes, to sizes 4, 8, then 16.  Most observed string splits are for human
+   text (roughly 11 words per line) and field delimited data (usually 1-10
+   fields).  For large strings the split algorithms are bandwidth limited
+   so increasing the preallocation likely will not improve things.*/
+
+#define MAX_PREALLOC 12
+
+/* 5 splits gives 6 elements */
+#define PREALLOC_SIZE(maxsplit) \
+    (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
+
+#define SPLIT_APPEND(data, left, right)         \
+    sub = STRINGLIB_NEW((data) + (left),        \
+                        (right) - (left));      \
+    if (sub == NULL)                            \
+        goto onError;                           \
+    if (PyList_Append(list, sub)) {             \
+        Py_DECREF(sub);                         \
+        goto onError;                           \
+    }                                           \
+    else                                        \
+        Py_DECREF(sub);
+
+#define SPLIT_ADD(data, left, right) {          \
+    sub = STRINGLIB_NEW((data) + (left),        \
+                        (right) - (left));      \
+    if (sub == NULL)                            \
+        goto onError;                           \
+    if (count < MAX_PREALLOC) {                 \
+        PyList_SET_ITEM(list, count, sub);      \
+    } else {                                    \
+        if (PyList_Append(list, sub)) {         \
+            Py_DECREF(sub);                     \
+            goto onError;                       \
+        }                                       \
+        else                                    \
+            Py_DECREF(sub);                     \
+    }                                           \
+    count++; }
+
+
+/* Always force the list to the expected size. */
+#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split_whitespace(PyObject* str_obj,
+                           const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                           Py_ssize_t maxcount)
+{
+    Py_ssize_t i, j, count=0;
+    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+    PyObject *sub;
+
+    if (list == NULL)
+        return NULL;
+
+    i = j = 0;
+    while (maxcount-- > 0) {
+        while (i < str_len && STRINGLIB_ISSPACE(str[i]))
+            i++;
+        if (i == str_len) break;
+        j = i; i++;
+        while (i < str_len && !STRINGLIB_ISSPACE(str[i]))
+            i++;
+#ifndef STRINGLIB_MUTABLE
+        if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
+            /* No whitespace in str_obj, so just use it as list[0] */
+            Py_INCREF(str_obj);
+            PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+            count++;
+            break;
+        }
+#endif
+        SPLIT_ADD(str, j, i);
+    }
+
+    if (i < str_len) {
+        /* Only occurs when maxcount was reached */
+        /* Skip any remaining whitespace and copy to end of string */
+        while (i < str_len && STRINGLIB_ISSPACE(str[i]))
+            i++;
+        if (i != str_len)
+            SPLIT_ADD(str, i, str_len);
+    }
+    FIX_PREALLOC_SIZE(list);
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split_char(PyObject* str_obj,
+                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                     const STRINGLIB_CHAR ch,
+                     Py_ssize_t maxcount)
+{
+    Py_ssize_t i, j, count=0;
+    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+    PyObject *sub;
+
+    if (list == NULL)
+        return NULL;
+
+    i = j = 0;
+    while ((j < str_len) && (maxcount-- > 0)) {
+        for(; j < str_len; j++) {
+            /* I found that using memchr makes no difference */
+            if (str[j] == ch) {
+                SPLIT_ADD(str, i, j);
+                i = j = j + 1;
+                break;
+            }
+        }
+    }
+#ifndef STRINGLIB_MUTABLE
+    if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+        /* ch not in str_obj, so just use str_obj as list[0] */
+        Py_INCREF(str_obj);
+        PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+        count++;
+    } else
+#endif
+    if (i <= str_len) {
+        SPLIT_ADD(str, i, str_len);
+    }
+    FIX_PREALLOC_SIZE(list);
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split(PyObject* str_obj,
+                const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
+                Py_ssize_t maxcount)
+{
+    Py_ssize_t i, j, pos, count=0;
+    PyObject *list, *sub;
+
+    if (sep_len == 0) {
+        PyErr_SetString(PyExc_ValueError, "empty separator");
+        return NULL;
+    }
+    else if (sep_len == 1)
+        return stringlib_split_char(str_obj, str, str_len, sep[0], maxcount);
+
+    list = PyList_New(PREALLOC_SIZE(maxcount));
+    if (list == NULL)
+        return NULL;
+
+    i = j = 0;
+    while (maxcount-- > 0) {
+        pos = fastsearch(str+i, str_len-i, sep, sep_len, -1, FAST_SEARCH);
+        if (pos < 0)
+            break;
+        j = i + pos;
+        SPLIT_ADD(str, i, j);
+        i = j + sep_len;
+    }
+#ifndef STRINGLIB_MUTABLE
+    if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+        /* No match in str_obj, so just use it as list[0] */
+        Py_INCREF(str_obj);
+        PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+        count++;
+    } else
+#endif
+    {
+        SPLIT_ADD(str, i, str_len);
+    }
+    FIX_PREALLOC_SIZE(list);
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit_whitespace(PyObject* str_obj,
+                            const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                            Py_ssize_t maxcount)
+{
+    Py_ssize_t i, j, count=0;
+    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+    PyObject *sub;
+
+    if (list == NULL)
+        return NULL;
+
+    i = j = str_len - 1;
+    while (maxcount-- > 0) {
+        while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
+            i--;
+        if (i < 0) break;
+        j = i; i--;
+        while (i >= 0 && !STRINGLIB_ISSPACE(str[i]))
+            i--;
+#ifndef STRINGLIB_MUTABLE
+        if (j == str_len - 1 && i < 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+            /* No whitespace in str_obj, so just use it as list[0] */
+            Py_INCREF(str_obj);
+            PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+            count++;
+            break;
+        }
+#endif
+        SPLIT_ADD(str, i + 1, j + 1);
+    }
+
+    if (i >= 0) {
+        /* Only occurs when maxcount was reached */
+        /* Skip any remaining whitespace and copy to beginning of string */
+        while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
+            i--;
+        if (i >= 0)
+            SPLIT_ADD(str, 0, i + 1);
+    }
+    FIX_PREALLOC_SIZE(list);
+    if (PyList_Reverse(list) < 0)
+        goto onError;
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit_char(PyObject* str_obj,
+                      const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                      const STRINGLIB_CHAR ch,
+                      Py_ssize_t maxcount)
+{
+    Py_ssize_t i, j, count=0;
+    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+    PyObject *sub;
+
+    if (list == NULL)
+        return NULL;
+
+    i = j = str_len - 1;
+    while ((i >= 0) && (maxcount-- > 0)) {
+        for(; i >= 0; i--) {
+            if (str[i] == ch) {
+                SPLIT_ADD(str, i + 1, j + 1);
+                j = i = i - 1;
+                break;
+            }
+        }
+    }
+#ifndef STRINGLIB_MUTABLE
+    if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+        /* ch not in str_obj, so just use str_obj as list[0] */
+        Py_INCREF(str_obj);
+        PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+        count++;
+    } else
+#endif
+    if (j >= -1) {
+        SPLIT_ADD(str, 0, j + 1);
+    }
+    FIX_PREALLOC_SIZE(list);
+    if (PyList_Reverse(list) < 0)
+        goto onError;
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit(PyObject* str_obj,
+                 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                 const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
+                 Py_ssize_t maxcount)
+{
+    Py_ssize_t j, pos, count=0;
+    PyObject *list, *sub;
+
+    if (sep_len == 0) {
+        PyErr_SetString(PyExc_ValueError, "empty separator");
+        return NULL;
+    }
+    else if (sep_len == 1)
+        return stringlib_rsplit_char(str_obj, str, str_len, sep[0], maxcount);
+
+    list = PyList_New(PREALLOC_SIZE(maxcount));
+    if (list == NULL)
+        return NULL;
+
+    j = str_len;
+    while (maxcount-- > 0) {
+        pos = fastsearch(str, j, sep, sep_len, -1, FAST_RSEARCH);
+        if (pos < 0)
+            break;
+        SPLIT_ADD(str, pos + sep_len, j);
+        j = pos;
+    }
+#ifndef STRINGLIB_MUTABLE
+    if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+        /* No match in str_obj, so just use it as list[0] */
+        Py_INCREF(str_obj);
+        PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+        count++;
+    } else
+#endif
+    {
+        SPLIT_ADD(str, 0, j);
+    }
+    FIX_PREALLOC_SIZE(list);
+    if (PyList_Reverse(list) < 0)
+        goto onError;
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_splitlines(PyObject* str_obj,
+                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+                     int keepends)
+{
+    /* This does not use the preallocated list because splitlines is
+       usually run with hundreds of newlines.  The overhead of
+       switching between PyList_SET_ITEM and append causes about a
+       2-3% slowdown for that common case.  A smarter implementation
+       could move the if check out, so the SET_ITEMs are done first
+       and the appends only done when the prealloc buffer is full.
+       That's too much work for little gain.*/
+
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    PyObject *list = PyList_New(0);
+    PyObject *sub;
+
+    if (list == NULL)
+        return NULL;
+
+    for (i = j = 0; i < str_len; ) {
+        Py_ssize_t eol;
+
+        /* Find a line and append it */
+        while (i < str_len && !STRINGLIB_ISLINEBREAK(str[i]))
+            i++;
+
+        /* Skip the line break reading CRLF as one line break */
+        eol = i;
+        if (i < str_len) {
+            if (str[i] == '\r' && i + 1 < str_len && str[i+1] == '\n')
+                i += 2;
+            else
+                i++;
+            if (keepends)
+                eol = i;
+        }
+#ifndef STRINGLIB_MUTABLE
+        if (j == 0 && eol == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
+            /* No linebreak in str_obj, so just use it as list[0] */
+            if (PyList_Append(list, str_obj))
+                goto onError;
+            break;
+        }
+#endif
+        SPLIT_APPEND(str, j, eol);
+        j = i;
+    }
+    return list;
+
+  onError:
+    Py_DECREF(list);
+    return NULL;
+}
+
+#endif
diff --git a/Python-2.7.5/Objects/stringlib/string_format.h b/Python-2.7.5/Objects/stringlib/string_format.h
new file mode 100644
index 0000000..965e1ad
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/string_format.h
@@ -0,0 +1,1361 @@
+/*
+    string_format.h -- implementation of string.format().
+
+    It uses the Objects/stringlib conventions, so that it can be
+    compiled for both unicode and string objects.
+*/
+
+
+/* Defines for Python 2.6 compatibility */
+#if PY_VERSION_HEX < 0x03000000
+#define PyLong_FromSsize_t _PyLong_FromSsize_t
+#endif
+
+/* Defines for more efficiently reallocating the string buffer */
+#define INITIAL_SIZE_INCREMENT 100
+#define SIZE_MULTIPLIER 2
+#define MAX_SIZE_INCREMENT  3200
+
+
+/************************************************************************/
+/***********   Global data structures and forward declarations  *********/
+/************************************************************************/
+
+/*
+   A SubString consists of the characters between two string or
+   unicode pointers.
+*/
+typedef struct {
+    STRINGLIB_CHAR *ptr;
+    STRINGLIB_CHAR *end;
+} SubString;
+
+
+typedef enum {
+    ANS_INIT,
+    ANS_AUTO,
+    ANS_MANUAL
+} AutoNumberState;   /* Keep track if we're auto-numbering fields */
+
+/* Keeps track of our auto-numbering state, and which number field we're on */
+typedef struct {
+    AutoNumberState an_state;
+    int an_field_number;
+} AutoNumber;
+
+
+/* forward declaration for recursion */
+static PyObject *
+build_string(SubString *input, PyObject *args, PyObject *kwargs,
+             int recursion_depth, AutoNumber *auto_number);
+
+
+
+/************************************************************************/
+/**************************  Utility  functions  ************************/
+/************************************************************************/
+
+static void
+AutoNumber_Init(AutoNumber *auto_number)
+{
+    auto_number->an_state = ANS_INIT;
+    auto_number->an_field_number = 0;
+}
+
+/* fill in a SubString from a pointer and length */
+Py_LOCAL_INLINE(void)
+SubString_init(SubString *str, STRINGLIB_CHAR *p, Py_ssize_t len)
+{
+    str->ptr = p;
+    if (p == NULL)
+        str->end = NULL;
+    else
+        str->end = str->ptr + len;
+}
+
+/* return a new string.  if str->ptr is NULL, return None */
+Py_LOCAL_INLINE(PyObject *)
+SubString_new_object(SubString *str)
+{
+    if (str->ptr == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
+}
+
+/* return a new string.  if str->ptr is NULL, return None */
+Py_LOCAL_INLINE(PyObject *)
+SubString_new_object_or_empty(SubString *str)
+{
+    if (str->ptr == NULL) {
+        return STRINGLIB_NEW(NULL, 0);
+    }
+    return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
+}
+
+/* Return 1 if an error has been detected switching between automatic
+   field numbering and manual field specification, else return 0. Set
+   ValueError on error. */
+static int
+autonumber_state_error(AutoNumberState state, int field_name_is_empty)
+{
+    if (state == ANS_MANUAL) {
+        if (field_name_is_empty) {
+            PyErr_SetString(PyExc_ValueError, "cannot switch from "
+                            "manual field specification to "
+                            "automatic field numbering");
+            return 1;
+        }
+    }
+    else {
+        if (!field_name_is_empty) {
+            PyErr_SetString(PyExc_ValueError, "cannot switch from "
+                            "automatic field numbering to "
+                            "manual field specification");
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
+/************************************************************************/
+/***********    Output string management functions       ****************/
+/************************************************************************/
+
+typedef struct {
+    STRINGLIB_CHAR *ptr;
+    STRINGLIB_CHAR *end;
+    PyObject *obj;
+    Py_ssize_t size_increment;
+} OutputString;
+
+/* initialize an OutputString object, reserving size characters */
+static int
+output_initialize(OutputString *output, Py_ssize_t size)
+{
+    output->obj = STRINGLIB_NEW(NULL, size);
+    if (output->obj == NULL)
+        return 0;
+
+    output->ptr = STRINGLIB_STR(output->obj);
+    output->end = STRINGLIB_LEN(output->obj) + output->ptr;
+    output->size_increment = INITIAL_SIZE_INCREMENT;
+
+    return 1;
+}
+
+/*
+    output_extend reallocates the output string buffer.
+    It returns a status:  0 for a failed reallocation,
+    1 for success.
+*/
+
+static int
+output_extend(OutputString *output, Py_ssize_t count)
+{
+    STRINGLIB_CHAR *startptr = STRINGLIB_STR(output->obj);
+    Py_ssize_t curlen = output->ptr - startptr;
+    Py_ssize_t maxlen = curlen + count + output->size_increment;
+
+    if (STRINGLIB_RESIZE(&output->obj, maxlen) < 0)
+        return 0;
+    startptr = STRINGLIB_STR(output->obj);
+    output->ptr = startptr + curlen;
+    output->end = startptr + maxlen;
+    if (output->size_increment < MAX_SIZE_INCREMENT)
+        output->size_increment *= SIZE_MULTIPLIER;
+    return 1;
+}
+
+/*
+    output_data dumps characters into our output string
+    buffer.
+
+    In some cases, it has to reallocate the string.
+
+    It returns a status:  0 for a failed reallocation,
+    1 for success.
+*/
+static int
+output_data(OutputString *output, const STRINGLIB_CHAR *s, Py_ssize_t count)
+{
+    if ((count > output->end - output->ptr) && !output_extend(output, count))
+        return 0;
+    memcpy(output->ptr, s, count * sizeof(STRINGLIB_CHAR));
+    output->ptr += count;
+    return 1;
+}
+
+/************************************************************************/
+/***********  Format string parsing -- integers and identifiers *********/
+/************************************************************************/
+
+static Py_ssize_t
+get_integer(const SubString *str)
+{
+    Py_ssize_t accumulator = 0;
+    Py_ssize_t digitval;
+    STRINGLIB_CHAR *p;
+
+    /* empty string is an error */
+    if (str->ptr >= str->end)
+        return -1;
+
+    for (p = str->ptr; p < str->end; p++) {
+        digitval = STRINGLIB_TODECIMAL(*p);
+        if (digitval < 0)
+            return -1;
+        /*
+           Detect possible overflow before it happens:
+
+              accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
+              accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
+        */
+        if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
+            PyErr_Format(PyExc_ValueError,
+                         "Too many decimal digits in format string");
+            return -1;
+        }
+        accumulator = accumulator * 10 + digitval;
+    }
+    return accumulator;
+}
+
+/************************************************************************/
+/******** Functions to get field objects and specification strings ******/
+/************************************************************************/
+
+/* do the equivalent of obj.name */
+static PyObject *
+getattr(PyObject *obj, SubString *name)
+{
+    PyObject *newobj;
+    PyObject *str = SubString_new_object(name);
+    if (str == NULL)
+        return NULL;
+    newobj = PyObject_GetAttr(obj, str);
+    Py_DECREF(str);
+    return newobj;
+}
+
+/* do the equivalent of obj[idx], where obj is a sequence */
+static PyObject *
+getitem_sequence(PyObject *obj, Py_ssize_t idx)
+{
+    return PySequence_GetItem(obj, idx);
+}
+
+/* do the equivalent of obj[idx], where obj is not a sequence */
+static PyObject *
+getitem_idx(PyObject *obj, Py_ssize_t idx)
+{
+    PyObject *newobj;
+    PyObject *idx_obj = PyLong_FromSsize_t(idx);
+    if (idx_obj == NULL)
+        return NULL;
+    newobj = PyObject_GetItem(obj, idx_obj);
+    Py_DECREF(idx_obj);
+    return newobj;
+}
+
+/* do the equivalent of obj[name] */
+static PyObject *
+getitem_str(PyObject *obj, SubString *name)
+{
+    PyObject *newobj;
+    PyObject *str = SubString_new_object(name);
+    if (str == NULL)
+        return NULL;
+    newobj = PyObject_GetItem(obj, str);
+    Py_DECREF(str);
+    return newobj;
+}
+
+typedef struct {
+    /* the entire string we're parsing.  we assume that someone else
+       is managing its lifetime, and that it will exist for the
+       lifetime of the iterator.  can be empty */
+    SubString str;
+
+    /* pointer to where we are inside field_name */
+    STRINGLIB_CHAR *ptr;
+} FieldNameIterator;
+
+
+static int
+FieldNameIterator_init(FieldNameIterator *self, STRINGLIB_CHAR *ptr,
+                       Py_ssize_t len)
+{
+    SubString_init(&self->str, ptr, len);
+    self->ptr = self->str.ptr;
+    return 1;
+}
+
+static int
+_FieldNameIterator_attr(FieldNameIterator *self, SubString *name)
+{
+    STRINGLIB_CHAR c;
+
+    name->ptr = self->ptr;
+
+    /* return everything until '.' or '[' */
+    while (self->ptr < self->str.end) {
+        switch (c = *self->ptr++) {
+        case '[':
+        case '.':
+            /* backup so that we this character will be seen next time */
+            self->ptr--;
+            break;
+        default:
+            continue;
+        }
+        break;
+    }
+    /* end of string is okay */
+    name->end = self->ptr;
+    return 1;
+}
+
+static int
+_FieldNameIterator_item(FieldNameIterator *self, SubString *name)
+{
+    int bracket_seen = 0;
+    STRINGLIB_CHAR c;
+
+    name->ptr = self->ptr;
+
+    /* return everything until ']' */
+    while (self->ptr < self->str.end) {
+        switch (c = *self->ptr++) {
+        case ']':
+            bracket_seen = 1;
+            break;
+        default:
+            continue;
+        }
+        break;
+    }
+    /* make sure we ended with a ']' */
+    if (!bracket_seen) {
+        PyErr_SetString(PyExc_ValueError, "Missing ']' in format string");
+        return 0;
+    }
+
+    /* end of string is okay */
+    /* don't include the ']' */
+    name->end = self->ptr-1;
+    return 1;
+}
+
+/* returns 0 on error, 1 on non-error termination, and 2 if it returns a value */
+static int
+FieldNameIterator_next(FieldNameIterator *self, int *is_attribute,
+                       Py_ssize_t *name_idx, SubString *name)
+{
+    /* check at end of input */
+    if (self->ptr >= self->str.end)
+        return 1;
+
+    switch (*self->ptr++) {
+    case '.':
+        *is_attribute = 1;
+        if (_FieldNameIterator_attr(self, name) == 0)
+            return 0;
+        *name_idx = -1;
+        break;
+    case '[':
+        *is_attribute = 0;
+        if (_FieldNameIterator_item(self, name) == 0)
+            return 0;
+        *name_idx = get_integer(name);
+        if (*name_idx == -1 && PyErr_Occurred())
+            return 0;
+        break;
+    default:
+        /* Invalid character follows ']' */
+        PyErr_SetString(PyExc_ValueError, "Only '.' or '[' may "
+                        "follow ']' in format field specifier");
+        return 0;
+    }
+
+    /* empty string is an error */
+    if (name->ptr == name->end) {
+        PyErr_SetString(PyExc_ValueError, "Empty attribute in format string");
+        return 0;
+    }
+
+    return 2;
+}
+
+
+/* input: field_name
+   output: 'first' points to the part before the first '[' or '.'
+           'first_idx' is -1 if 'first' is not an integer, otherwise
+                       it's the value of first converted to an integer
+           'rest' is an iterator to return the rest
+*/
+static int
+field_name_split(STRINGLIB_CHAR *ptr, Py_ssize_t len, SubString *first,
+                 Py_ssize_t *first_idx, FieldNameIterator *rest,
+                 AutoNumber *auto_number)
+{
+    STRINGLIB_CHAR c;
+    STRINGLIB_CHAR *p = ptr;
+    STRINGLIB_CHAR *end = ptr + len;
+    int field_name_is_empty;
+    int using_numeric_index;
+
+    /* find the part up until the first '.' or '[' */
+    while (p < end) {
+        switch (c = *p++) {
+        case '[':
+        case '.':
+            /* backup so that we this character is available to the
+               "rest" iterator */
+            p--;
+            break;
+        default:
+            continue;
+        }
+        break;
+    }
+
+    /* set up the return values */
+    SubString_init(first, ptr, p - ptr);
+    FieldNameIterator_init(rest, p, end - p);
+
+    /* see if "first" is an integer, in which case it's used as an index */
+    *first_idx = get_integer(first);
+    if (*first_idx == -1 && PyErr_Occurred())
+        return 0;
+
+    field_name_is_empty = first->ptr >= first->end;
+
+    /* If the field name is omitted or if we have a numeric index
+       specified, then we're doing numeric indexing into args. */
+    using_numeric_index = field_name_is_empty || *first_idx != -1;
+
+    /* We always get here exactly one time for each field we're
+       processing. And we get here in field order (counting by left
+       braces). So this is the perfect place to handle automatic field
+       numbering if the field name is omitted. */
+
+    /* Check if we need to do the auto-numbering. It's not needed if
+       we're called from string.Format routines, because it's handled
+       in that class by itself. */
+    if (auto_number) {
+        /* Initialize our auto numbering state if this is the first
+           time we're either auto-numbering or manually numbering. */
+        if (auto_number->an_state == ANS_INIT && using_numeric_index)
+            auto_number->an_state = field_name_is_empty ?
+                ANS_AUTO : ANS_MANUAL;
+
+        /* Make sure our state is consistent with what we're doing
+           this time through. Only check if we're using a numeric
+           index. */
+        if (using_numeric_index)
+            if (autonumber_state_error(auto_number->an_state,
+                                       field_name_is_empty))
+                return 0;
+        /* Zero length field means we want to do auto-numbering of the
+           fields. */
+        if (field_name_is_empty)
+            *first_idx = (auto_number->an_field_number)++;
+    }
+
+    return 1;
+}
+
+
+/*
+    get_field_object returns the object inside {}, before the
+    format_spec.  It handles getindex and getattr lookups and consumes
+    the entire input string.
+*/
+static PyObject *
+get_field_object(SubString *input, PyObject *args, PyObject *kwargs,
+                 AutoNumber *auto_number)
+{
+    PyObject *obj = NULL;
+    int ok;
+    int is_attribute;
+    SubString name;
+    SubString first;
+    Py_ssize_t index;
+    FieldNameIterator rest;
+
+    if (!field_name_split(input->ptr, input->end - input->ptr, &first,
+                          &index, &rest, auto_number)) {
+        goto error;
+    }
+
+    if (index == -1) {
+        /* look up in kwargs */
+        PyObject *key = SubString_new_object(&first);
+        if (key == NULL)
+            goto error;
+        if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) {
+            PyErr_SetObject(PyExc_KeyError, key);
+            Py_DECREF(key);
+            goto error;
+        }
+        Py_DECREF(key);
+        Py_INCREF(obj);
+    }
+    else {
+        /* look up in args */
+        obj = PySequence_GetItem(args, index);
+        if (obj == NULL)
+            goto error;
+    }
+
+    /* iterate over the rest of the field_name */
+    while ((ok = FieldNameIterator_next(&rest, &is_attribute, &index,
+                                        &name)) == 2) {
+        PyObject *tmp;
+
+        if (is_attribute)
+            /* getattr lookup "." */
+            tmp = getattr(obj, &name);
+        else
+            /* getitem lookup "[]" */
+            if (index == -1)
+                tmp = getitem_str(obj, &name);
+            else
+                if (PySequence_Check(obj))
+                    tmp = getitem_sequence(obj, index);
+                else
+                    /* not a sequence */
+                    tmp = getitem_idx(obj, index);
+        if (tmp == NULL)
+            goto error;
+
+        /* assign to obj */
+        Py_DECREF(obj);
+        obj = tmp;
+    }
+    /* end of iterator, this is the non-error case */
+    if (ok == 1)
+        return obj;
+error:
+    Py_XDECREF(obj);
+    return NULL;
+}
+
+/************************************************************************/
+/*****************  Field rendering functions  **************************/
+/************************************************************************/
+
+/*
+    render_field() is the main function in this section.  It takes the
+    field object and field specification string generated by
+    get_field_and_spec, and renders the field into the output string.
+
+    render_field calls fieldobj.__format__(format_spec) method, and
+    appends to the output.
+*/
+static int
+render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
+{
+    int ok = 0;
+    PyObject *result = NULL;
+    PyObject *format_spec_object = NULL;
+    PyObject *(*formatter)(PyObject *, STRINGLIB_CHAR *, Py_ssize_t) = NULL;
+    STRINGLIB_CHAR* format_spec_start = format_spec->ptr ?
+            format_spec->ptr : NULL;
+    Py_ssize_t format_spec_len = format_spec->ptr ?
+            format_spec->end - format_spec->ptr : 0;
+
+    /* If we know the type exactly, skip the lookup of __format__ and just
+       call the formatter directly. */
+#if STRINGLIB_IS_UNICODE
+    if (PyUnicode_CheckExact(fieldobj))
+        formatter = _PyUnicode_FormatAdvanced;
+    /* Unfortunately, there's a problem with checking for int, long,
+       and float here.  If we're being included as unicode, their
+       formatters expect string format_spec args.  For now, just skip
+       this optimization for unicode.  This could be fixed, but it's a
+       hassle. */
+#else
+    if (PyString_CheckExact(fieldobj))
+        formatter = _PyBytes_FormatAdvanced;
+    else if (PyInt_CheckExact(fieldobj))
+        formatter =_PyInt_FormatAdvanced;
+    else if (PyLong_CheckExact(fieldobj))
+        formatter =_PyLong_FormatAdvanced;
+    else if (PyFloat_CheckExact(fieldobj))
+        formatter = _PyFloat_FormatAdvanced;
+#endif
+
+    if (formatter) {
+        /* we know exactly which formatter will be called when __format__ is
+           looked up, so call it directly, instead. */
+        result = formatter(fieldobj, format_spec_start, format_spec_len);
+    }
+    else {
+        /* We need to create an object out of the pointers we have, because
+           __format__ takes a string/unicode object for format_spec. */
+        format_spec_object = STRINGLIB_NEW(format_spec_start,
+                                           format_spec_len);
+        if (format_spec_object == NULL)
+            goto done;
+
+        result = PyObject_Format(fieldobj, format_spec_object);
+    }
+    if (result == NULL)
+        goto done;
+
+#if PY_VERSION_HEX >= 0x03000000
+    assert(PyUnicode_Check(result));
+#else
+    assert(PyString_Check(result) || PyUnicode_Check(result));
+
+    /* Convert result to our type.  We could be str, and result could
+       be unicode */
+    {
+        PyObject *tmp = STRINGLIB_TOSTR(result);
+        if (tmp == NULL)
+            goto done;
+        Py_DECREF(result);
+        result = tmp;
+    }
+#endif
+
+    ok = output_data(output,
+                     STRINGLIB_STR(result), STRINGLIB_LEN(result));
+done:
+    Py_XDECREF(format_spec_object);
+    Py_XDECREF(result);
+    return ok;
+}
+
+static int
+parse_field(SubString *str, SubString *field_name, SubString *format_spec,
+            STRINGLIB_CHAR *conversion)
+{
+    /* Note this function works if the field name is zero length,
+       which is good.  Zero length field names are handled later, in
+       field_name_split. */
+
+    STRINGLIB_CHAR c = 0;
+
+    /* initialize these, as they may be empty */
+    *conversion = '\0';
+    SubString_init(format_spec, NULL, 0);
+
+    /* Search for the field name.  it's terminated by the end of
+       the string, or a ':' or '!' */
+    field_name->ptr = str->ptr;
+    while (str->ptr < str->end) {
+        switch (c = *(str->ptr++)) {
+        case ':':
+        case '!':
+            break;
+        default:
+            continue;
+        }
+        break;
+    }
+
+    if (c == '!' || c == ':') {
+        /* we have a format specifier and/or a conversion */
+        /* don't include the last character */
+        field_name->end = str->ptr-1;
+
+        /* the format specifier is the rest of the string */
+        format_spec->ptr = str->ptr;
+        format_spec->end = str->end;
+
+        /* see if there's a conversion specifier */
+        if (c == '!') {
+            /* there must be another character present */
+            if (format_spec->ptr >= format_spec->end) {
+                PyErr_SetString(PyExc_ValueError,
+                                "end of format while looking for conversion "
+                                "specifier");
+                return 0;
+            }
+            *conversion = *(format_spec->ptr++);
+
+            /* if there is another character, it must be a colon */
+            if (format_spec->ptr < format_spec->end) {
+                c = *(format_spec->ptr++);
+                if (c != ':') {
+                    PyErr_SetString(PyExc_ValueError,
+                                    "expected ':' after format specifier");
+                    return 0;
+                }
+            }
+        }
+    }
+    else
+        /* end of string, there's no format_spec or conversion */
+        field_name->end = str->ptr;
+
+    return 1;
+}
+
+/************************************************************************/
+/******* Output string allocation and escape-to-markup processing  ******/
+/************************************************************************/
+
+/* MarkupIterator breaks the string into pieces of either literal
+   text, or things inside {} that need to be marked up.  it is
+   designed to make it easy to wrap a Python iterator around it, for
+   use with the Formatter class */
+
+typedef struct {
+    SubString str;
+} MarkupIterator;
+
+static int
+MarkupIterator_init(MarkupIterator *self, STRINGLIB_CHAR *ptr, Py_ssize_t len)
+{
+    SubString_init(&self->str, ptr, len);
+    return 1;
+}
+
+/* returns 0 on error, 1 on non-error termination, and 2 if it got a
+   string (or something to be expanded) */
+static int
+MarkupIterator_next(MarkupIterator *self, SubString *literal,
+                    int *field_present, SubString *field_name,
+                    SubString *format_spec, STRINGLIB_CHAR *conversion,
+                    int *format_spec_needs_expanding)
+{
+    int at_end;
+    STRINGLIB_CHAR c = 0;
+    STRINGLIB_CHAR *start;
+    int count;
+    Py_ssize_t len;
+    int markup_follows = 0;
+
+    /* initialize all of the output variables */
+    SubString_init(literal, NULL, 0);
+    SubString_init(field_name, NULL, 0);
+    SubString_init(format_spec, NULL, 0);
+    *conversion = '\0';
+    *format_spec_needs_expanding = 0;
+    *field_present = 0;
+
+    /* No more input, end of iterator.  This is the normal exit
+       path. */
+    if (self->str.ptr >= self->str.end)
+        return 1;
+
+    start = self->str.ptr;
+
+    /* First read any literal text. Read until the end of string, an
+       escaped '{' or '}', or an unescaped '{'.  In order to never
+       allocate memory and so I can just pass pointers around, if
+       there's an escaped '{' or '}' then we'll return the literal
+       including the brace, but no format object.  The next time
+       through, we'll return the rest of the literal, skipping past
+       the second consecutive brace. */
+    while (self->str.ptr < self->str.end) {
+        switch (c = *(self->str.ptr++)) {
+        case '{':
+        case '}':
+            markup_follows = 1;
+            break;
+        default:
+            continue;
+        }
+        break;
+    }
+
+    at_end = self->str.ptr >= self->str.end;
+    len = self->str.ptr - start;
+
+    if ((c == '}') && (at_end || (c != *self->str.ptr))) {
+        PyErr_SetString(PyExc_ValueError, "Single '}' encountered "
+                        "in format string");
+        return 0;
+    }
+    if (at_end && c == '{') {
+        PyErr_SetString(PyExc_ValueError, "Single '{' encountered "
+                        "in format string");
+        return 0;
+    }
+    if (!at_end) {
+        if (c == *self->str.ptr) {
+            /* escaped } or {, skip it in the input.  there is no
+               markup object following us, just this literal text */
+            self->str.ptr++;
+            markup_follows = 0;
+        }
+        else
+            len--;
+    }
+
+    /* record the literal text */
+    literal->ptr = start;
+    literal->end = start + len;
+
+    if (!markup_follows)
+        return 2;
+
+    /* this is markup, find the end of the string by counting nested
+       braces.  note that this prohibits escaped braces, so that
+       format_specs cannot have braces in them. */
+    *field_present = 1;
+    count = 1;
+
+    start = self->str.ptr;
+
+    /* we know we can't have a zero length string, so don't worry
+       about that case */
+    while (self->str.ptr < self->str.end) {
+        switch (c = *(self->str.ptr++)) {
+        case '{':
+            /* the format spec needs to be recursively expanded.
+               this is an optimization, and not strictly needed */
+            *format_spec_needs_expanding = 1;
+            count++;
+            break;
+        case '}':
+            count--;
+            if (count <= 0) {
+                /* we're done.  parse and get out */
+                SubString s;
+
+                SubString_init(&s, start, self->str.ptr - 1 - start);
+                if (parse_field(&s, field_name, format_spec, conversion) == 0)
+                    return 0;
+
+                /* success */
+                return 2;
+            }
+            break;
+        }
+    }
+
+    /* end of string while searching for matching '}' */
+    PyErr_SetString(PyExc_ValueError, "unmatched '{' in format");
+    return 0;
+}
+
+
+/* do the !r or !s conversion on obj */
+static PyObject *
+do_conversion(PyObject *obj, STRINGLIB_CHAR conversion)
+{
+    /* XXX in pre-3.0, do we need to convert this to unicode, since it
+       might have returned a string? */
+    switch (conversion) {
+    case 'r':
+        return PyObject_Repr(obj);
+    case 's':
+        return STRINGLIB_TOSTR(obj);
+    default:
+        if (conversion > 32 && conversion < 127) {
+                /* It's the ASCII subrange; casting to char is safe
+                   (assuming the execution character set is an ASCII
+                   superset). */
+                PyErr_Format(PyExc_ValueError,
+                     "Unknown conversion specifier %c",
+                     (char)conversion);
+        } else
+                PyErr_Format(PyExc_ValueError,
+                     "Unknown conversion specifier \\x%x",
+                     (unsigned int)conversion);
+        return NULL;
+    }
+}
+
+/* given:
+
+   {field_name!conversion:format_spec}
+
+   compute the result and write it to output.
+   format_spec_needs_expanding is an optimization.  if it's false,
+   just output the string directly, otherwise recursively expand the
+   format_spec string.
+
+   field_name is allowed to be zero length, in which case we
+   are doing auto field numbering.
+*/
+
+static int
+output_markup(SubString *field_name, SubString *format_spec,
+              int format_spec_needs_expanding, STRINGLIB_CHAR conversion,
+              OutputString *output, PyObject *args, PyObject *kwargs,
+              int recursion_depth, AutoNumber *auto_number)
+{
+    PyObject *tmp = NULL;
+    PyObject *fieldobj = NULL;
+    SubString expanded_format_spec;
+    SubString *actual_format_spec;
+    int result = 0;
+
+    /* convert field_name to an object */
+    fieldobj = get_field_object(field_name, args, kwargs, auto_number);
+    if (fieldobj == NULL)
+        goto done;
+
+    if (conversion != '\0') {
+        tmp = do_conversion(fieldobj, conversion);
+        if (tmp == NULL)
+            goto done;
+
+        /* do the assignment, transferring ownership: fieldobj = tmp */
+        Py_DECREF(fieldobj);
+        fieldobj = tmp;
+        tmp = NULL;
+    }
+
+    /* if needed, recurively compute the format_spec */
+    if (format_spec_needs_expanding) {
+        tmp = build_string(format_spec, args, kwargs, recursion_depth-1,
+                           auto_number);
+        if (tmp == NULL)
+            goto done;
+
+        /* note that in the case we're expanding the format string,
+           tmp must be kept around until after the call to
+           render_field. */
+        SubString_init(&expanded_format_spec,
+                       STRINGLIB_STR(tmp), STRINGLIB_LEN(tmp));
+        actual_format_spec = &expanded_format_spec;
+    }
+    else
+        actual_format_spec = format_spec;
+
+    if (render_field(fieldobj, actual_format_spec, output) == 0)
+        goto done;
+
+    result = 1;
+
+done:
+    Py_XDECREF(fieldobj);
+    Py_XDECREF(tmp);
+
+    return result;
+}
+
+/*
+    do_markup is the top-level loop for the format() method.  It
+    searches through the format string for escapes to markup codes, and
+    calls other functions to move non-markup text to the output,
+    and to perform the markup to the output.
+*/
+static int
+do_markup(SubString *input, PyObject *args, PyObject *kwargs,
+          OutputString *output, int recursion_depth, AutoNumber *auto_number)
+{
+    MarkupIterator iter;
+    int format_spec_needs_expanding;
+    int result;
+    int field_present;
+    SubString literal;
+    SubString field_name;
+    SubString format_spec;
+    STRINGLIB_CHAR conversion;
+
+    MarkupIterator_init(&iter, input->ptr, input->end - input->ptr);
+    while ((result = MarkupIterator_next(&iter, &literal, &field_present,
+                                         &field_name, &format_spec,
+                                         &conversion,
+                                         &format_spec_needs_expanding)) == 2) {
+        if (!output_data(output, literal.ptr, literal.end - literal.ptr))
+            return 0;
+        if (field_present)
+            if (!output_markup(&field_name, &format_spec,
+                               format_spec_needs_expanding, conversion, output,
+                               args, kwargs, recursion_depth, auto_number))
+                return 0;
+    }
+    return result;
+}
+
+
+/*
+    build_string allocates the output string and then
+    calls do_markup to do the heavy lifting.
+*/
+static PyObject *
+build_string(SubString *input, PyObject *args, PyObject *kwargs,
+             int recursion_depth, AutoNumber *auto_number)
+{
+    OutputString output;
+    PyObject *result = NULL;
+    Py_ssize_t count;
+
+    output.obj = NULL; /* needed so cleanup code always works */
+
+    /* check the recursion level */
+    if (recursion_depth <= 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Max string recursion exceeded");
+        goto done;
+    }
+
+    /* initial size is the length of the format string, plus the size
+       increment.  seems like a reasonable default */
+    if (!output_initialize(&output,
+                           input->end - input->ptr +
+                           INITIAL_SIZE_INCREMENT))
+        goto done;
+
+    if (!do_markup(input, args, kwargs, &output, recursion_depth,
+                   auto_number)) {
+        goto done;
+    }
+
+    count = output.ptr - STRINGLIB_STR(output.obj);
+    if (STRINGLIB_RESIZE(&output.obj, count) < 0) {
+        goto done;
+    }
+
+    /* transfer ownership to result */
+    result = output.obj;
+    output.obj = NULL;
+
+done:
+    Py_XDECREF(output.obj);
+    return result;
+}
+
+/************************************************************************/
+/*********** main routine ***********************************************/
+/************************************************************************/
+
+/* this is the main entry point */
+static PyObject *
+do_string_format(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    SubString input;
+
+    /* PEP 3101 says only 2 levels, so that
+       "{0:{1}}".format('abc', 's')            # works
+       "{0:{1:{2}}}".format('abc', 's', '')    # fails
+    */
+    int recursion_depth = 2;
+
+    AutoNumber auto_number;
+
+    AutoNumber_Init(&auto_number);
+    SubString_init(&input, STRINGLIB_STR(self), STRINGLIB_LEN(self));
+    return build_string(&input, args, kwargs, recursion_depth, &auto_number);
+}
+
+
+
+/************************************************************************/
+/*********** formatteriterator ******************************************/
+/************************************************************************/
+
+/* This is used to implement string.Formatter.vparse().  It exists so
+   Formatter can share code with the built in unicode.format() method.
+   It's really just a wrapper around MarkupIterator that is callable
+   from Python. */
+
+typedef struct {
+    PyObject_HEAD
+
+    STRINGLIB_OBJECT *str;
+
+    MarkupIterator it_markup;
+} formatteriterobject;
+
+static void
+formatteriter_dealloc(formatteriterobject *it)
+{
+    Py_XDECREF(it->str);
+    PyObject_FREE(it);
+}
+
+/* returns a tuple:
+   (literal, field_name, format_spec, conversion)
+
+   literal is any literal text to output.  might be zero length
+   field_name is the string before the ':'.  might be None
+   format_spec is the string after the ':'.  mibht be None
+   conversion is either None, or the string after the '!'
+*/
+static PyObject *
+formatteriter_next(formatteriterobject *it)
+{
+    SubString literal;
+    SubString field_name;
+    SubString format_spec;
+    STRINGLIB_CHAR conversion;
+    int format_spec_needs_expanding;
+    int field_present;
+    int result = MarkupIterator_next(&it->it_markup, &literal, &field_present,
+                                     &field_name, &format_spec, &conversion,
+                                     &format_spec_needs_expanding);
+
+    /* all of the SubString objects point into it->str, so no
+       memory management needs to be done on them */
+    assert(0 <= result && result <= 2);
+    if (result == 0 || result == 1)
+        /* if 0, error has already been set, if 1, iterator is empty */
+        return NULL;
+    else {
+        PyObject *literal_str = NULL;
+        PyObject *field_name_str = NULL;
+        PyObject *format_spec_str = NULL;
+        PyObject *conversion_str = NULL;
+        PyObject *tuple = NULL;
+
+        literal_str = SubString_new_object(&literal);
+        if (literal_str == NULL)
+            goto done;
+
+        field_name_str = SubString_new_object(&field_name);
+        if (field_name_str == NULL)
+            goto done;
+
+        /* if field_name is non-zero length, return a string for
+           format_spec (even if zero length), else return None */
+        format_spec_str = (field_present ?
+                           SubString_new_object_or_empty :
+                           SubString_new_object)(&format_spec);
+        if (format_spec_str == NULL)
+            goto done;
+
+        /* if the conversion is not specified, return a None,
+           otherwise create a one length string with the conversion
+           character */
+        if (conversion == '\0') {
+            conversion_str = Py_None;
+            Py_INCREF(conversion_str);
+        }
+        else
+            conversion_str = STRINGLIB_NEW(&conversion, 1);
+        if (conversion_str == NULL)
+            goto done;
+
+        tuple = PyTuple_Pack(4, literal_str, field_name_str, format_spec_str,
+                             conversion_str);
+    done:
+        Py_XDECREF(literal_str);
+        Py_XDECREF(field_name_str);
+        Py_XDECREF(format_spec_str);
+        Py_XDECREF(conversion_str);
+        return tuple;
+    }
+}
+
+static PyMethodDef formatteriter_methods[] = {
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyTypeObject PyFormatterIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "formatteriterator",                /* tp_name */
+    sizeof(formatteriterobject),        /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    /* methods */
+    (destructor)formatteriter_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 */
+    0,                                  /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+    0,                                  /* tp_doc */
+    0,                                  /* tp_traverse */
+    0,                                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    PyObject_SelfIter,                  /* tp_iter */
+    (iternextfunc)formatteriter_next,   /* tp_iternext */
+    formatteriter_methods,              /* tp_methods */
+    0,
+};
+
+/* unicode_formatter_parser is used to implement
+   string.Formatter.vformat.  it parses a string and returns tuples
+   describing the parsed elements.  It's a wrapper around
+   stringlib/string_format.h's MarkupIterator */
+static PyObject *
+formatter_parser(STRINGLIB_OBJECT *self)
+{
+    formatteriterobject *it;
+
+    it = PyObject_New(formatteriterobject, &PyFormatterIter_Type);
+    if (it == NULL)
+        return NULL;
+
+    /* take ownership, give the object to the iterator */
+    Py_INCREF(self);
+    it->str = self;
+
+    /* initialize the contained MarkupIterator */
+    MarkupIterator_init(&it->it_markup,
+                        STRINGLIB_STR(self),
+                        STRINGLIB_LEN(self));
+
+    return (PyObject *)it;
+}
+
+
+/************************************************************************/
+/*********** fieldnameiterator ******************************************/
+/************************************************************************/
+
+
+/* This is used to implement string.Formatter.vparse().  It parses the
+   field name into attribute and item values.  It's a Python-callable
+   wrapper around FieldNameIterator */
+
+typedef struct {
+    PyObject_HEAD
+
+    STRINGLIB_OBJECT *str;
+
+    FieldNameIterator it_field;
+} fieldnameiterobject;
+
+static void
+fieldnameiter_dealloc(fieldnameiterobject *it)
+{
+    Py_XDECREF(it->str);
+    PyObject_FREE(it);
+}
+
+/* returns a tuple:
+   (is_attr, value)
+   is_attr is true if we used attribute syntax (e.g., '.foo')
+              false if we used index syntax (e.g., '[foo]')
+   value is an integer or string
+*/
+static PyObject *
+fieldnameiter_next(fieldnameiterobject *it)
+{
+    int result;
+    int is_attr;
+    Py_ssize_t idx;
+    SubString name;
+
+    result = FieldNameIterator_next(&it->it_field, &is_attr,
+                                    &idx, &name);
+    if (result == 0 || result == 1)
+        /* if 0, error has already been set, if 1, iterator is empty */
+        return NULL;
+    else {
+        PyObject* result = NULL;
+        PyObject* is_attr_obj = NULL;
+        PyObject* obj = NULL;
+
+        is_attr_obj = PyBool_FromLong(is_attr);
+        if (is_attr_obj == NULL)
+            goto done;
+
+        /* either an integer or a string */
+        if (idx != -1)
+            obj = PyLong_FromSsize_t(idx);
+        else
+            obj = SubString_new_object(&name);
+        if (obj == NULL)
+            goto done;
+
+        /* return a tuple of values */
+        result = PyTuple_Pack(2, is_attr_obj, obj);
+
+    done:
+        Py_XDECREF(is_attr_obj);
+        Py_XDECREF(obj);
+        return result;
+    }
+}
+
+static PyMethodDef fieldnameiter_methods[] = {
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyTypeObject PyFieldNameIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "fieldnameiterator",                /* tp_name */
+    sizeof(fieldnameiterobject),        /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    /* methods */
+    (destructor)fieldnameiter_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 */
+    0,                                  /* tp_str */
+    PyObject_GenericGetAttr,            /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+    0,                                  /* tp_doc */
+    0,                                  /* tp_traverse */
+    0,                                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    PyObject_SelfIter,                  /* tp_iter */
+    (iternextfunc)fieldnameiter_next,   /* tp_iternext */
+    fieldnameiter_methods,              /* tp_methods */
+    0};
+
+/* unicode_formatter_field_name_split is used to implement
+   string.Formatter.vformat.  it takes an PEP 3101 "field name", and
+   returns a tuple of (first, rest): "first", the part before the
+   first '.' or '['; and "rest", an iterator for the rest of the field
+   name.  it's a wrapper around stringlib/string_format.h's
+   field_name_split.  The iterator it returns is a
+   FieldNameIterator */
+static PyObject *
+formatter_field_name_split(STRINGLIB_OBJECT *self)
+{
+    SubString first;
+    Py_ssize_t first_idx;
+    fieldnameiterobject *it;
+
+    PyObject *first_obj = NULL;
+    PyObject *result = NULL;
+
+    it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type);
+    if (it == NULL)
+        return NULL;
+
+    /* take ownership, give the object to the iterator.  this is
+       just to keep the field_name alive */
+    Py_INCREF(self);
+    it->str = self;
+
+    /* Pass in auto_number = NULL. We'll return an empty string for
+       first_obj in that case. */
+    if (!field_name_split(STRINGLIB_STR(self),
+                          STRINGLIB_LEN(self),
+                          &first, &first_idx, &it->it_field, NULL))
+        goto done;
+
+    /* first becomes an integer, if possible; else a string */
+    if (first_idx != -1)
+        first_obj = PyLong_FromSsize_t(first_idx);
+    else
+        /* convert "first" into a string object */
+        first_obj = SubString_new_object(&first);
+    if (first_obj == NULL)
+        goto done;
+
+    /* return a tuple of values */
+    result = PyTuple_Pack(2, first_obj, it);
+
+done:
+    Py_XDECREF(it);
+    Py_XDECREF(first_obj);
+    return result;
+}
diff --git a/Python-2.7.5/Objects/stringlib/stringdefs.h b/Python-2.7.5/Objects/stringlib/stringdefs.h
new file mode 100644
index 0000000..84e4616
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/stringdefs.h
@@ -0,0 +1,33 @@
+#ifndef STRINGLIB_STRINGDEFS_H
+#define STRINGLIB_STRINGDEFS_H
+
+/* this is sort of a hack.  there's at least one place (formatting
+   floats) where some stringlib code takes a different path if it's
+   compiled as unicode. */
+#define STRINGLIB_IS_UNICODE     0
+
+#define STRINGLIB_OBJECT         PyStringObject
+#define STRINGLIB_CHAR           char
+#define STRINGLIB_TYPE_NAME      "string"
+#define STRINGLIB_PARSE_CODE     "S"
+#define STRINGLIB_EMPTY          nullstring
+#define STRINGLIB_ISSPACE        Py_ISSPACE
+#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
+#define STRINGLIB_ISDECIMAL(x)   ((x >= '0') && (x <= '9'))
+#define STRINGLIB_TODECIMAL(x)   (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1)
+#define STRINGLIB_TOUPPER        Py_TOUPPER
+#define STRINGLIB_TOLOWER        Py_TOLOWER
+#define STRINGLIB_FILL           memset
+#define STRINGLIB_STR            PyString_AS_STRING
+#define STRINGLIB_LEN            PyString_GET_SIZE
+#define STRINGLIB_NEW            PyString_FromStringAndSize
+#define STRINGLIB_RESIZE         _PyString_Resize
+#define STRINGLIB_CHECK          PyString_Check
+#define STRINGLIB_CHECK_EXACT    PyString_CheckExact
+#define STRINGLIB_TOSTR          PyObject_Str
+#define STRINGLIB_GROUPING       _PyString_InsertThousandsGrouping
+#define STRINGLIB_GROUPING_LOCALE _PyString_InsertThousandsGroupingLocale
+
+#define STRINGLIB_WANT_CONTAINS_OBJ 1
+
+#endif /* !STRINGLIB_STRINGDEFS_H */
diff --git a/Python-2.7.5/Objects/stringlib/transmogrify.h b/Python-2.7.5/Objects/stringlib/transmogrify.h
new file mode 100644
index 0000000..1e132e5
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/transmogrify.h
@@ -0,0 +1,264 @@
+/* NOTE: this API is -ONLY- for use with single byte character strings. */
+/* Do not use it with Unicode. */
+
+/* the more complicated methods.  parts of these should be pulled out into the
+   shared code in bytes_methods.c to cut down on duplicate code bloat.  */
+
+PyDoc_STRVAR(expandtabs__doc__,
+"B.expandtabs([tabsize]) -> copy of B\n\
+\n\
+Return a copy of B where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+stringlib_expandtabs(PyObject *self, PyObject *args)
+{
+    const char *e, *p;
+    char *q;
+    size_t i, j;
+    PyObject *u;
+    int tabsize = 8;
+    
+    if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+        return NULL;
+    
+    /* First pass: determine size of output string */
+    i = j = 0;
+    e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
+    for (p = STRINGLIB_STR(self); p < e; p++)
+        if (*p == '\t') {
+            if (tabsize > 0) {
+                j += tabsize - (j % tabsize);
+                if (j > PY_SSIZE_T_MAX) {
+                    PyErr_SetString(PyExc_OverflowError,
+                                    "result is too long");
+                    return NULL;
+                }
+            }
+        }
+        else {
+            j++;
+            if (*p == '\n' || *p == '\r') {
+                i += j;
+                j = 0;
+                if (i > PY_SSIZE_T_MAX) {
+                    PyErr_SetString(PyExc_OverflowError,
+                                    "result is too long");
+                    return NULL;
+                }
+            }
+        }
+    
+    if ((i + j) > PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError, "result is too long");
+        return NULL;
+    }
+    
+    /* Second pass: create output string and fill it */
+    u = STRINGLIB_NEW(NULL, i + j);
+    if (!u)
+        return NULL;
+    
+    j = 0;
+    q = STRINGLIB_STR(u);
+    
+    for (p = STRINGLIB_STR(self); p < e; p++)
+        if (*p == '\t') {
+            if (tabsize > 0) {
+                i = tabsize - (j % tabsize);
+                j += i;
+                while (i--)
+                    *q++ = ' ';
+            }
+        }
+        else {
+            j++;
+            *q++ = *p;
+            if (*p == '\n' || *p == '\r')
+                j = 0;
+        }
+    
+    return u;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
+{
+    PyObject *u;
+
+    if (left < 0)
+        left = 0;
+    if (right < 0)
+        right = 0;
+
+    if (left == 0 && right == 0 && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+        /* We're defined as returning a copy;  If the object is mutable
+         * that means we must make an identical copy. */
+        return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+        Py_INCREF(self);
+        return (PyObject *)self;
+#endif /* STRINGLIB_MUTABLE */
+    }
+
+    u = STRINGLIB_NEW(NULL,
+				   left + STRINGLIB_LEN(self) + right);
+    if (u) {
+        if (left)
+            memset(STRINGLIB_STR(u), fill, left);
+        Py_MEMCPY(STRINGLIB_STR(u) + left,
+	       STRINGLIB_STR(self),
+	       STRINGLIB_LEN(self));
+        if (right)
+            memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self),
+		   fill, right);
+    }
+
+    return u;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+"B.ljust(width[, fillchar]) -> copy of B\n"
+"\n"
+"Return B left justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+stringlib_ljust(PyObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
+        return NULL;
+
+    if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+        /* We're defined as returning a copy;  If the object is mutable
+         * that means we must make an identical copy. */
+        return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+        Py_INCREF(self);
+        return (PyObject*) self;
+#endif
+    }
+
+    return pad(self, 0, width - STRINGLIB_LEN(self), fillchar);
+}
+
+
+PyDoc_STRVAR(rjust__doc__,
+"B.rjust(width[, fillchar]) -> copy of B\n"
+"\n"
+"Return B right justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+stringlib_rjust(PyObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
+        return NULL;
+
+    if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+        /* We're defined as returning a copy;  If the object is mutable
+         * that means we must make an identical copy. */
+        return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+        Py_INCREF(self);
+        return (PyObject*) self;
+#endif
+    }
+
+    return pad(self, width - STRINGLIB_LEN(self), 0, fillchar);
+}
+
+
+PyDoc_STRVAR(center__doc__,
+"B.center(width[, fillchar]) -> copy of B\n"
+"\n"
+"Return B centered in a string of length width.  Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+stringlib_center(PyObject *self, PyObject *args)
+{
+    Py_ssize_t marg, left;
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar))
+        return NULL;
+
+    if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+        /* We're defined as returning a copy;  If the object is mutable
+         * that means we must make an identical copy. */
+        return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+        Py_INCREF(self);
+        return (PyObject*) self;
+#endif
+    }
+
+    marg = width - STRINGLIB_LEN(self);
+    left = marg / 2 + (marg & width & 1);
+
+    return pad(self, left, marg - left, fillchar);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+"B.zfill(width) -> copy of B\n"
+"\n"
+"Pad a numeric string B with zeros on the left, to fill a field\n"
+"of the specified width.  B is never truncated.");
+
+static PyObject *
+stringlib_zfill(PyObject *self, PyObject *args)
+{
+    Py_ssize_t fill;
+    PyObject *s;
+    char *p;
+    Py_ssize_t width;
+
+    if (!PyArg_ParseTuple(args, "n:zfill", &width))
+        return NULL;
+
+    if (STRINGLIB_LEN(self) >= width) {
+        if (STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+            /* We're defined as returning a copy;  If the object is mutable
+             * that means we must make an identical copy. */
+            return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+            Py_INCREF(self);
+            return (PyObject*) self;
+#endif
+        }
+        else
+            return STRINGLIB_NEW(
+                STRINGLIB_STR(self),
+                STRINGLIB_LEN(self)
+            );
+    }
+
+    fill = width - STRINGLIB_LEN(self);
+
+    s = pad(self, fill, 0, '0');
+
+    if (s == NULL)
+        return NULL;
+
+    p = STRINGLIB_STR(s);
+    if (p[fill] == '+' || p[fill] == '-') {
+        /* move sign to beginning of string */
+        p[0] = p[fill];
+        p[fill] = '0';
+    }
+
+    return (PyObject*) s;
+}
diff --git a/Python-2.7.5/Objects/stringlib/unicodedefs.h b/Python-2.7.5/Objects/stringlib/unicodedefs.h
new file mode 100644
index 0000000..dd814f6
--- /dev/null
+++ b/Python-2.7.5/Objects/stringlib/unicodedefs.h
@@ -0,0 +1,37 @@
+#ifndef STRINGLIB_UNICODEDEFS_H
+#define STRINGLIB_UNICODEDEFS_H
+
+/* this is sort of a hack.  there's at least one place (formatting
+   floats) where some stringlib code takes a different path if it's
+   compiled as unicode. */
+#define STRINGLIB_IS_UNICODE     1
+
+#define STRINGLIB_OBJECT         PyUnicodeObject
+#define STRINGLIB_CHAR           Py_UNICODE
+#define STRINGLIB_TYPE_NAME      "unicode"
+#define STRINGLIB_PARSE_CODE     "U"
+#define STRINGLIB_EMPTY          unicode_empty
+#define STRINGLIB_ISSPACE        Py_UNICODE_ISSPACE
+#define STRINGLIB_ISLINEBREAK    BLOOM_LINEBREAK
+#define STRINGLIB_ISDECIMAL      Py_UNICODE_ISDECIMAL
+#define STRINGLIB_TODECIMAL      Py_UNICODE_TODECIMAL
+#define STRINGLIB_TOUPPER        Py_UNICODE_TOUPPER
+#define STRINGLIB_TOLOWER        Py_UNICODE_TOLOWER
+#define STRINGLIB_FILL           Py_UNICODE_FILL
+#define STRINGLIB_STR            PyUnicode_AS_UNICODE
+#define STRINGLIB_LEN            PyUnicode_GET_SIZE
+#define STRINGLIB_NEW            PyUnicode_FromUnicode
+#define STRINGLIB_RESIZE         PyUnicode_Resize
+#define STRINGLIB_CHECK          PyUnicode_Check
+#define STRINGLIB_CHECK_EXACT    PyUnicode_CheckExact
+#define STRINGLIB_GROUPING       _PyUnicode_InsertThousandsGrouping
+
+#if PY_VERSION_HEX < 0x03000000
+#define STRINGLIB_TOSTR          PyObject_Unicode
+#else
+#define STRINGLIB_TOSTR          PyObject_Str
+#endif
+
+#define STRINGLIB_WANT_CONTAINS_OBJ 1
+
+#endif /* !STRINGLIB_UNICODEDEFS_H */
diff --git a/Python-2.7.5/Objects/stringobject.c b/Python-2.7.5/Objects/stringobject.c
new file mode 100644
index 0000000..1209197
--- /dev/null
+++ b/Python-2.7.5/Objects/stringobject.c
@@ -0,0 +1,4845 @@
+/* String (str/bytes) object implementation */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include <ctype.h>
+#include <stddef.h>
+
+#ifdef COUNT_ALLOCS
+Py_ssize_t null_strings, one_strings;
+#endif
+
+static PyStringObject *characters[UCHAR_MAX + 1];
+static PyStringObject *nullstring;
+
+/* This dictionary holds all interned strings.  Note that references to
+   strings in this dictionary are *not* counted in the string's ob_refcnt.
+   When the interned string reaches a refcnt of 0 the string deallocation
+   function will delete the reference from this dictionary.
+
+   Another way to look at this is that to say that the actual reference
+   count of a string is:  s->ob_refcnt + (s->ob_sstate?2:0)
+*/
+static PyObject *interned;
+
+/* PyStringObject_SIZE gives the basic size of a string; any memory allocation
+   for a string of length n should request PyStringObject_SIZE + n bytes.
+
+   Using PyStringObject_SIZE instead of sizeof(PyStringObject) saves
+   3 bytes per string allocation on a typical system.
+*/
+#define PyStringObject_SIZE (offsetof(PyStringObject, ob_sval) + 1)
+
+/*
+   For PyString_FromString(), the parameter `str' points to a null-terminated
+   string containing exactly `size' bytes.
+
+   For PyString_FromStringAndSize(), the parameter the parameter `str' is
+   either NULL or else points to a string containing at least `size' bytes.
+   For PyString_FromStringAndSize(), the string in the `str' parameter does
+   not have to be null-terminated.  (Therefore it is safe to construct a
+   substring by calling `PyString_FromStringAndSize(origstring, substrlen)'.)
+   If `str' is NULL then PyString_FromStringAndSize() will allocate `size+1'
+   bytes (setting the last byte to the null terminating character) and you can
+   fill in the data yourself.  If `str' is non-NULL then the resulting
+   PyString object must be treated as immutable and you must not fill in nor
+   alter the data yourself, since the strings may be shared.
+
+   The PyObject member `op->ob_size', which denotes the number of "extra
+   items" in a variable-size object, will contain the number of bytes
+   allocated for string data, not counting the null terminating character.
+   It is therefore equal to the `size' parameter (for
+   PyString_FromStringAndSize()) or the length of the string in the `str'
+   parameter (for PyString_FromString()).
+*/
+PyObject *
+PyString_FromStringAndSize(const char *str, Py_ssize_t size)
+{
+    register PyStringObject *op;
+    if (size < 0) {
+        PyErr_SetString(PyExc_SystemError,
+            "Negative size passed to PyString_FromStringAndSize");
+        return NULL;
+    }
+    if (size == 0 && (op = nullstring) != NULL) {
+#ifdef COUNT_ALLOCS
+        null_strings++;
+#endif
+        Py_INCREF(op);
+        return (PyObject *)op;
+    }
+    if (size == 1 && str != NULL &&
+        (op = characters[*str & UCHAR_MAX]) != NULL)
+    {
+#ifdef COUNT_ALLOCS
+        one_strings++;
+#endif
+        Py_INCREF(op);
+        return (PyObject *)op;
+    }
+
+    if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
+        PyErr_SetString(PyExc_OverflowError, "string is too large");
+        return NULL;
+    }
+
+    /* Inline PyObject_NewVar */
+    op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
+    if (op == NULL)
+        return PyErr_NoMemory();
+    PyObject_INIT_VAR(op, &PyString_Type, size);
+    op->ob_shash = -1;
+    op->ob_sstate = SSTATE_NOT_INTERNED;
+    if (str != NULL)
+        Py_MEMCPY(op->ob_sval, str, size);
+    op->ob_sval[size] = '\0';
+    /* share short strings */
+    if (size == 0) {
+        PyObject *t = (PyObject *)op;
+        PyString_InternInPlace(&t);
+        op = (PyStringObject *)t;
+        nullstring = op;
+        Py_INCREF(op);
+    } else if (size == 1 && str != NULL) {
+        PyObject *t = (PyObject *)op;
+        PyString_InternInPlace(&t);
+        op = (PyStringObject *)t;
+        characters[*str & UCHAR_MAX] = op;
+        Py_INCREF(op);
+    }
+    return (PyObject *) op;
+}
+
+PyObject *
+PyString_FromString(const char *str)
+{
+    register size_t size;
+    register PyStringObject *op;
+
+    assert(str != NULL);
+    size = strlen(str);
+    if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
+        PyErr_SetString(PyExc_OverflowError,
+            "string is too long for a Python string");
+        return NULL;
+    }
+    if (size == 0 && (op = nullstring) != NULL) {
+#ifdef COUNT_ALLOCS
+        null_strings++;
+#endif
+        Py_INCREF(op);
+        return (PyObject *)op;
+    }
+    if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) {
+#ifdef COUNT_ALLOCS
+        one_strings++;
+#endif
+        Py_INCREF(op);
+        return (PyObject *)op;
+    }
+
+    /* Inline PyObject_NewVar */
+    op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
+    if (op == NULL)
+        return PyErr_NoMemory();
+    PyObject_INIT_VAR(op, &PyString_Type, size);
+    op->ob_shash = -1;
+    op->ob_sstate = SSTATE_NOT_INTERNED;
+    Py_MEMCPY(op->ob_sval, str, size+1);
+    /* share short strings */
+    if (size == 0) {
+        PyObject *t = (PyObject *)op;
+        PyString_InternInPlace(&t);
+        op = (PyStringObject *)t;
+        nullstring = op;
+        Py_INCREF(op);
+    } else if (size == 1) {
+        PyObject *t = (PyObject *)op;
+        PyString_InternInPlace(&t);
+        op = (PyStringObject *)t;
+        characters[*str & UCHAR_MAX] = op;
+        Py_INCREF(op);
+    }
+    return (PyObject *) op;
+}
+
+PyObject *
+PyString_FromFormatV(const char *format, va_list vargs)
+{
+    va_list count;
+    Py_ssize_t n = 0;
+    const char* f;
+    char *s;
+    PyObject* string;
+
+#ifdef VA_LIST_IS_ARRAY
+    Py_MEMCPY(count, vargs, sizeof(va_list));
+#else
+#ifdef  __va_copy
+    __va_copy(count, vargs);
+#else
+    count = vargs;
+#endif
+#endif
+    /* step 1: figure out how large a buffer we need */
+    for (f = format; *f; f++) {
+        if (*f == '%') {
+#ifdef HAVE_LONG_LONG
+            int longlongflag = 0;
+#endif
+            const char* p = f;
+            while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+                ;
+
+            /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+             * they don't affect the amount of space we reserve.
+             */
+            if (*f == 'l') {
+                if (f[1] == 'd' || f[1] == 'u') {
+                    ++f;
+                }
+#ifdef HAVE_LONG_LONG
+                else if (f[1] == 'l' &&
+                         (f[2] == 'd' || f[2] == 'u')) {
+                    longlongflag = 1;
+                    f += 2;
+                }
+#endif
+            }
+            else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+                ++f;
+            }
+
+            switch (*f) {
+            case 'c':
+                (void)va_arg(count, int);
+                /* fall through... */
+            case '%':
+                n++;
+                break;
+            case 'd': case 'u': case 'i': case 'x':
+                (void) va_arg(count, int);
+#ifdef HAVE_LONG_LONG
+                /* Need at most
+                   ceil(log10(256)*SIZEOF_LONG_LONG) digits,
+                   plus 1 for the sign.  53/22 is an upper
+                   bound for log10(256). */
+                if (longlongflag)
+                    n += 2 + (SIZEOF_LONG_LONG*53-1) / 22;
+                else
+#endif
+                    /* 20 bytes is enough to hold a 64-bit
+                       integer.  Decimal takes the most
+                       space.  This isn't enough for
+                       octal. */
+                    n += 20;
+
+                break;
+            case 's':
+                s = va_arg(count, char*);
+                n += strlen(s);
+                break;
+            case 'p':
+                (void) va_arg(count, int);
+                /* maximum 64-bit pointer representation:
+                 * 0xffffffffffffffff
+                 * so 19 characters is enough.
+                 * XXX I count 18 -- what's the extra for?
+                 */
+                n += 19;
+                break;
+            default:
+                /* if we stumble upon an unknown
+                   formatting code, copy the rest of
+                   the format string to the output
+                   string. (we cannot just skip the
+                   code, since there's no way to know
+                   what's in the argument list) */
+                n += strlen(p);
+                goto expand;
+            }
+        } else
+            n++;
+    }
+ expand:
+    /* step 2: fill the buffer */
+    /* Since we've analyzed how much space we need for the worst case,
+       use sprintf directly instead of the slower PyOS_snprintf. */
+    string = PyString_FromStringAndSize(NULL, n);
+    if (!string)
+        return NULL;
+
+    s = PyString_AsString(string);
+
+    for (f = format; *f; f++) {
+        if (*f == '%') {
+            const char* p = f++;
+            Py_ssize_t i;
+            int longflag = 0;
+#ifdef HAVE_LONG_LONG
+            int longlongflag = 0;
+#endif
+            int size_tflag = 0;
+            /* parse the width.precision part (we're only
+               interested in the precision value, if any) */
+            n = 0;
+            while (isdigit(Py_CHARMASK(*f)))
+                n = (n*10) + *f++ - '0';
+            if (*f == '.') {
+                f++;
+                n = 0;
+                while (isdigit(Py_CHARMASK(*f)))
+                    n = (n*10) + *f++ - '0';
+            }
+            while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+                f++;
+            /* Handle %ld, %lu, %lld and %llu. */
+            if (*f == 'l') {
+                if (f[1] == 'd' || f[1] == 'u') {
+                    longflag = 1;
+                    ++f;
+                }
+#ifdef HAVE_LONG_LONG
+                else if (f[1] == 'l' &&
+                         (f[2] == 'd' || f[2] == 'u')) {
+                    longlongflag = 1;
+                    f += 2;
+                }
+#endif
+            }
+            /* handle the size_t flag. */
+            else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+                size_tflag = 1;
+                ++f;
+            }
+
+            switch (*f) {
+            case 'c':
+                *s++ = va_arg(vargs, int);
+                break;
+            case 'd':
+                if (longflag)
+                    sprintf(s, "%ld", va_arg(vargs, long));
+#ifdef HAVE_LONG_LONG
+                else if (longlongflag)
+                    sprintf(s, "%" PY_FORMAT_LONG_LONG "d",
+                        va_arg(vargs, PY_LONG_LONG));
+#endif
+                else if (size_tflag)
+                    sprintf(s, "%" PY_FORMAT_SIZE_T "d",
+                        va_arg(vargs, Py_ssize_t));
+                else
+                    sprintf(s, "%d", va_arg(vargs, int));
+                s += strlen(s);
+                break;
+            case 'u':
+                if (longflag)
+                    sprintf(s, "%lu",
+                        va_arg(vargs, unsigned long));
+#ifdef HAVE_LONG_LONG
+                else if (longlongflag)
+                    sprintf(s, "%" PY_FORMAT_LONG_LONG "u",
+                        va_arg(vargs, PY_LONG_LONG));
+#endif
+                else if (size_tflag)
+                    sprintf(s, "%" PY_FORMAT_SIZE_T "u",
+                        va_arg(vargs, size_t));
+                else
+                    sprintf(s, "%u",
+                        va_arg(vargs, unsigned int));
+                s += strlen(s);
+                break;
+            case 'i':
+                sprintf(s, "%i", va_arg(vargs, int));
+                s += strlen(s);
+                break;
+            case 'x':
+                sprintf(s, "%x", va_arg(vargs, int));
+                s += strlen(s);
+                break;
+            case 's':
+                p = va_arg(vargs, char*);
+                i = strlen(p);
+                if (n > 0 && i > n)
+                    i = n;
+                Py_MEMCPY(s, p, i);
+                s += i;
+                break;
+            case 'p':
+                sprintf(s, "%p", va_arg(vargs, void*));
+                /* %p is ill-defined:  ensure leading 0x. */
+                if (s[1] == 'X')
+                    s[1] = 'x';
+                else if (s[1] != 'x') {
+                    memmove(s+2, s, strlen(s)+1);
+                    s[0] = '0';
+                    s[1] = 'x';
+                }
+                s += strlen(s);
+                break;
+            case '%':
+                *s++ = '%';
+                break;
+            default:
+                strcpy(s, p);
+                s += strlen(s);
+                goto end;
+            }
+        } else
+            *s++ = *f;
+    }
+
+ end:
+    if (_PyString_Resize(&string, s - PyString_AS_STRING(string)))
+        return NULL;
+    return string;
+}
+
+PyObject *
+PyString_FromFormat(const char *format, ...)
+{
+    PyObject* ret;
+    va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+    va_start(vargs, format);
+#else
+    va_start(vargs);
+#endif
+    ret = PyString_FromFormatV(format, vargs);
+    va_end(vargs);
+    return ret;
+}
+
+
+PyObject *PyString_Decode(const char *s,
+                          Py_ssize_t size,
+                          const char *encoding,
+                          const char *errors)
+{
+    PyObject *v, *str;
+
+    str = PyString_FromStringAndSize(s, size);
+    if (str == NULL)
+        return NULL;
+    v = PyString_AsDecodedString(str, encoding, errors);
+    Py_DECREF(str);
+    return v;
+}
+
+PyObject *PyString_AsDecodedObject(PyObject *str,
+                                   const char *encoding,
+                                   const char *errors)
+{
+    PyObject *v;
+
+    if (!PyString_Check(str)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+        encoding = PyUnicode_GetDefaultEncoding();
+#else
+        PyErr_SetString(PyExc_ValueError, "no encoding specified");
+        goto onError;
+#endif
+    }
+
+    /* Decode via the codec registry */
+    v = PyCodec_Decode(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyString_AsDecodedString(PyObject *str,
+                                   const char *encoding,
+                                   const char *errors)
+{
+    PyObject *v;
+
+    v = PyString_AsDecodedObject(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+#ifdef Py_USING_UNICODE
+    /* Convert Unicode to a string using the default encoding */
+    if (PyUnicode_Check(v)) {
+        PyObject *temp = v;
+        v = PyUnicode_AsEncodedString(v, NULL, NULL);
+        Py_DECREF(temp);
+        if (v == NULL)
+            goto onError;
+    }
+#endif
+    if (!PyString_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a string object (type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyString_Encode(const char *s,
+                          Py_ssize_t size,
+                          const char *encoding,
+                          const char *errors)
+{
+    PyObject *v, *str;
+
+    str = PyString_FromStringAndSize(s, size);
+    if (str == NULL)
+        return NULL;
+    v = PyString_AsEncodedString(str, encoding, errors);
+    Py_DECREF(str);
+    return v;
+}
+
+PyObject *PyString_AsEncodedObject(PyObject *str,
+                                   const char *encoding,
+                                   const char *errors)
+{
+    PyObject *v;
+
+    if (!PyString_Check(str)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+        encoding = PyUnicode_GetDefaultEncoding();
+#else
+        PyErr_SetString(PyExc_ValueError, "no encoding specified");
+        goto onError;
+#endif
+    }
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyString_AsEncodedString(PyObject *str,
+                                   const char *encoding,
+                                   const char *errors)
+{
+    PyObject *v;
+
+    v = PyString_AsEncodedObject(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+#ifdef Py_USING_UNICODE
+    /* Convert Unicode to a string using the default encoding */
+    if (PyUnicode_Check(v)) {
+        PyObject *temp = v;
+        v = PyUnicode_AsEncodedString(v, NULL, NULL);
+        Py_DECREF(temp);
+        if (v == NULL)
+            goto onError;
+    }
+#endif
+    if (!PyString_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string object (type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+
+    return v;
+
+ onError:
+    return NULL;
+}
+
+static void
+string_dealloc(PyObject *op)
+{
+    switch (PyString_CHECK_INTERNED(op)) {
+        case SSTATE_NOT_INTERNED:
+            break;
+
+        case SSTATE_INTERNED_MORTAL:
+            /* revive dead object temporarily for DelItem */
+            Py_REFCNT(op) = 3;
+            if (PyDict_DelItem(interned, op) != 0)
+                Py_FatalError(
+                    "deletion of interned string failed");
+            break;
+
+        case SSTATE_INTERNED_IMMORTAL:
+            Py_FatalError("Immortal interned string died.");
+
+        default:
+            Py_FatalError("Inconsistent interned string state.");
+    }
+    Py_TYPE(op)->tp_free(op);
+}
+
+/* Unescape a backslash-escaped string. If unicode is non-zero,
+   the string is a u-literal. If recode_encoding is non-zero,
+   the string is UTF-8 encoded and should be re-encoded in the
+   specified encoding.  */
+
+PyObject *PyString_DecodeEscape(const char *s,
+                                Py_ssize_t len,
+                                const char *errors,
+                                Py_ssize_t unicode,
+                                const char *recode_encoding)
+{
+    int c;
+    char *p, *buf;
+    const char *end;
+    PyObject *v;
+    Py_ssize_t newlen = recode_encoding ? 4*len:len;
+    v = PyString_FromStringAndSize((char *)NULL, newlen);
+    if (v == NULL)
+        return NULL;
+    p = buf = PyString_AsString(v);
+    end = s + len;
+    while (s < end) {
+        if (*s != '\\') {
+          non_esc:
+#ifdef Py_USING_UNICODE
+            if (recode_encoding && (*s & 0x80)) {
+                PyObject *u, *w;
+                char *r;
+                const char* t;
+                Py_ssize_t rn;
+                t = s;
+                /* Decode non-ASCII bytes as UTF-8. */
+                while (t < end && (*t & 0x80)) t++;
+                u = PyUnicode_DecodeUTF8(s, t - s, errors);
+                if(!u) goto failed;
+
+                /* Recode them in target encoding. */
+                w = PyUnicode_AsEncodedString(
+                    u, recode_encoding, errors);
+                Py_DECREF(u);
+                if (!w)                 goto failed;
+
+                /* Append bytes to output buffer. */
+                assert(PyString_Check(w));
+                r = PyString_AS_STRING(w);
+                rn = PyString_GET_SIZE(w);
+                Py_MEMCPY(p, r, rn);
+                p += rn;
+                Py_DECREF(w);
+                s = t;
+            } else {
+                *p++ = *s++;
+            }
+#else
+            *p++ = *s++;
+#endif
+            continue;
+        }
+        s++;
+        if (s==end) {
+            PyErr_SetString(PyExc_ValueError,
+                            "Trailing \\ in string");
+            goto failed;
+        }
+        switch (*s++) {
+        /* XXX This assumes ASCII! */
+        case '\n': break;
+        case '\\': *p++ = '\\'; break;
+        case '\'': *p++ = '\''; break;
+        case '\"': *p++ = '\"'; break;
+        case 'b': *p++ = '\b'; break;
+        case 'f': *p++ = '\014'; break; /* FF */
+        case 't': *p++ = '\t'; break;
+        case 'n': *p++ = '\n'; break;
+        case 'r': *p++ = '\r'; break;
+        case 'v': *p++ = '\013'; break; /* VT */
+        case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+        case '0': case '1': case '2': case '3':
+        case '4': case '5': case '6': case '7':
+            c = s[-1] - '0';
+            if (s < end && '0' <= *s && *s <= '7') {
+                c = (c<<3) + *s++ - '0';
+                if (s < end && '0' <= *s && *s <= '7')
+                    c = (c<<3) + *s++ - '0';
+            }
+            *p++ = c;
+            break;
+        case 'x':
+            if (s+1 < end &&
+                isxdigit(Py_CHARMASK(s[0])) &&
+                isxdigit(Py_CHARMASK(s[1])))
+            {
+                unsigned int x = 0;
+                c = Py_CHARMASK(*s);
+                s++;
+                if (isdigit(c))
+                    x = c - '0';
+                else if (islower(c))
+                    x = 10 + c - 'a';
+                else
+                    x = 10 + c - 'A';
+                x = x << 4;
+                c = Py_CHARMASK(*s);
+                s++;
+                if (isdigit(c))
+                    x += c - '0';
+                else if (islower(c))
+                    x += 10 + c - 'a';
+                else
+                    x += 10 + c - 'A';
+                *p++ = x;
+                break;
+            }
+            if (!errors || strcmp(errors, "strict") == 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "invalid \\x escape");
+                goto failed;
+            }
+            if (strcmp(errors, "replace") == 0) {
+                *p++ = '?';
+            } else if (strcmp(errors, "ignore") == 0)
+                /* do nothing */;
+            else {
+                PyErr_Format(PyExc_ValueError,
+                             "decoding error; "
+                             "unknown error handling code: %.400s",
+                             errors);
+                goto failed;
+            }
+            /* skip \x */
+            if (s < end && isxdigit(Py_CHARMASK(s[0])))
+                s++; /* and a hexdigit */
+            break;
+#ifndef Py_USING_UNICODE
+        case 'u':
+        case 'U':
+        case 'N':
+            if (unicode) {
+                PyErr_SetString(PyExc_ValueError,
+                          "Unicode escapes not legal "
+                          "when Unicode disabled");
+                goto failed;
+            }
+#endif
+        default:
+            *p++ = '\\';
+            s--;
+            goto non_esc; /* an arbitrary number of unescaped
+                             UTF-8 bytes may follow. */
+        }
+    }
+    if (p-buf < newlen && _PyString_Resize(&v, p - buf))
+        goto failed;
+    return v;
+  failed:
+    Py_DECREF(v);
+    return NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* object api */
+
+static Py_ssize_t
+string_getsize(register PyObject *op)
+{
+    char *s;
+    Py_ssize_t len;
+    if (PyString_AsStringAndSize(op, &s, &len))
+        return -1;
+    return len;
+}
+
+static /*const*/ char *
+string_getbuffer(register PyObject *op)
+{
+    char *s;
+    Py_ssize_t len;
+    if (PyString_AsStringAndSize(op, &s, &len))
+        return NULL;
+    return s;
+}
+
+Py_ssize_t
+PyString_Size(register PyObject *op)
+{
+    if (!PyString_Check(op))
+        return string_getsize(op);
+    return Py_SIZE(op);
+}
+
+/*const*/ char *
+PyString_AsString(register PyObject *op)
+{
+    if (!PyString_Check(op))
+        return string_getbuffer(op);
+    return ((PyStringObject *)op) -> ob_sval;
+}
+
+int
+PyString_AsStringAndSize(register PyObject *obj,
+                         register char **s,
+                         register Py_ssize_t *len)
+{
+    if (s == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+
+    if (!PyString_Check(obj)) {
+#ifdef Py_USING_UNICODE
+        if (PyUnicode_Check(obj)) {
+            obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
+            if (obj == NULL)
+                return -1;
+        }
+        else
+#endif
+        {
+            PyErr_Format(PyExc_TypeError,
+                         "expected string or Unicode object, "
+                         "%.200s found", Py_TYPE(obj)->tp_name);
+            return -1;
+        }
+    }
+
+    *s = PyString_AS_STRING(obj);
+    if (len != NULL)
+        *len = PyString_GET_SIZE(obj);
+    else if (strlen(*s) != (size_t)PyString_GET_SIZE(obj)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "expected string without null bytes");
+        return -1;
+    }
+    return 0;
+}
+
+/* -------------------------------------------------------------------- */
+/* Methods */
+
+#include "stringlib/stringdefs.h"
+#include "stringlib/fastsearch.h"
+
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+#include "stringlib/split.h"
+
+#define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
+#include "stringlib/localeutil.h"
+
+
+
+static int
+string_print(PyStringObject *op, FILE *fp, int flags)
+{
+    Py_ssize_t i, str_len;
+    char c;
+    int quote;
+
+    /* XXX Ought to check for interrupts when writing long strings */
+    if (! PyString_CheckExact(op)) {
+        int ret;
+        /* A str subclass may have its own __str__ method. */
+        op = (PyStringObject *) PyObject_Str((PyObject *)op);
+        if (op == NULL)
+            return -1;
+        ret = string_print(op, fp, flags);
+        Py_DECREF(op);
+        return ret;
+    }
+    if (flags & Py_PRINT_RAW) {
+        char *data = op->ob_sval;
+        Py_ssize_t size = Py_SIZE(op);
+        Py_BEGIN_ALLOW_THREADS
+        while (size > INT_MAX) {
+            /* Very long strings cannot be written atomically.
+             * But don't write exactly INT_MAX bytes at a time
+             * to avoid memory aligment issues.
+             */
+            const int chunk_size = INT_MAX & ~0x3FFF;
+            fwrite(data, 1, chunk_size, fp);
+            data += chunk_size;
+            size -= chunk_size;
+        }
+#ifdef __VMS
+        if (size) fwrite(data, (int)size, 1, fp);
+#else
+        fwrite(data, 1, (int)size, fp);
+#endif
+        Py_END_ALLOW_THREADS
+        return 0;
+    }
+
+    /* figure out which quote to use; single is preferred */
+    quote = '\'';
+    if (memchr(op->ob_sval, '\'', Py_SIZE(op)) &&
+        !memchr(op->ob_sval, '"', Py_SIZE(op)))
+        quote = '"';
+
+    str_len = Py_SIZE(op);
+    Py_BEGIN_ALLOW_THREADS
+    fputc(quote, fp);
+    for (i = 0; i < str_len; i++) {
+        /* Since strings are immutable and the caller should have a
+        reference, accessing the interal buffer should not be an issue
+        with the GIL released. */
+        c = op->ob_sval[i];
+        if (c == quote || c == '\\')
+            fprintf(fp, "\\%c", c);
+        else if (c == '\t')
+            fprintf(fp, "\\t");
+        else if (c == '\n')
+            fprintf(fp, "\\n");
+        else if (c == '\r')
+            fprintf(fp, "\\r");
+        else if (c < ' ' || c >= 0x7f)
+            fprintf(fp, "\\x%02x", c & 0xff);
+        else
+            fputc(c, fp);
+    }
+    fputc(quote, fp);
+    Py_END_ALLOW_THREADS
+    return 0;
+}
+
+PyObject *
+PyString_Repr(PyObject *obj, int smartquotes)
+{
+    register PyStringObject* op = (PyStringObject*) obj;
+    size_t newsize = 2 + 4 * Py_SIZE(op);
+    PyObject *v;
+    if (newsize > PY_SSIZE_T_MAX || newsize / 4 != Py_SIZE(op)) {
+        PyErr_SetString(PyExc_OverflowError,
+            "string is too large to make repr");
+        return NULL;
+    }
+    v = PyString_FromStringAndSize((char *)NULL, newsize);
+    if (v == NULL) {
+        return NULL;
+    }
+    else {
+        register Py_ssize_t i;
+        register char c;
+        register char *p;
+        int quote;
+
+        /* figure out which quote to use; single is preferred */
+        quote = '\'';
+        if (smartquotes &&
+            memchr(op->ob_sval, '\'', Py_SIZE(op)) &&
+            !memchr(op->ob_sval, '"', Py_SIZE(op)))
+            quote = '"';
+
+        p = PyString_AS_STRING(v);
+        *p++ = quote;
+        for (i = 0; i < Py_SIZE(op); i++) {
+            /* There's at least enough room for a hex escape
+               and a closing quote. */
+            assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+            c = op->ob_sval[i];
+            if (c == quote || c == '\\')
+                *p++ = '\\', *p++ = c;
+            else if (c == '\t')
+                *p++ = '\\', *p++ = 't';
+            else if (c == '\n')
+                *p++ = '\\', *p++ = 'n';
+            else if (c == '\r')
+                *p++ = '\\', *p++ = 'r';
+            else if (c < ' ' || c >= 0x7f) {
+                /* For performance, we don't want to call
+                   PyOS_snprintf here (extra layers of
+                   function call). */
+                sprintf(p, "\\x%02x", c & 0xff);
+                p += 4;
+            }
+            else
+                *p++ = c;
+        }
+        assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+        *p++ = quote;
+        *p = '\0';
+        if (_PyString_Resize(&v, (p - PyString_AS_STRING(v))))
+            return NULL;
+        return v;
+    }
+}
+
+static PyObject *
+string_repr(PyObject *op)
+{
+    return PyString_Repr(op, 1);
+}
+
+static PyObject *
+string_str(PyObject *s)
+{
+    assert(PyString_Check(s));
+    if (PyString_CheckExact(s)) {
+        Py_INCREF(s);
+        return s;
+    }
+    else {
+        /* Subtype -- return genuine string with the same value. */
+        PyStringObject *t = (PyStringObject *) s;
+        return PyString_FromStringAndSize(t->ob_sval, Py_SIZE(t));
+    }
+}
+
+static Py_ssize_t
+string_length(PyStringObject *a)
+{
+    return Py_SIZE(a);
+}
+
+static PyObject *
+string_concat(register PyStringObject *a, register PyObject *bb)
+{
+    register Py_ssize_t size;
+    register PyStringObject *op;
+    if (!PyString_Check(bb)) {
+#ifdef Py_USING_UNICODE
+        if (PyUnicode_Check(bb))
+            return PyUnicode_Concat((PyObject *)a, bb);
+#endif
+        if (PyByteArray_Check(bb))
+            return PyByteArray_Concat((PyObject *)a, bb);
+        PyErr_Format(PyExc_TypeError,
+                     "cannot concatenate 'str' and '%.200s' objects",
+                     Py_TYPE(bb)->tp_name);
+        return NULL;
+    }
+#define b ((PyStringObject *)bb)
+    /* Optimize cases with empty left or right operand */
+    if ((Py_SIZE(a) == 0 || Py_SIZE(b) == 0) &&
+        PyString_CheckExact(a) && PyString_CheckExact(b)) {
+        if (Py_SIZE(a) == 0) {
+            Py_INCREF(bb);
+            return bb;
+        }
+        Py_INCREF(a);
+        return (PyObject *)a;
+    }
+    size = Py_SIZE(a) + Py_SIZE(b);
+    /* Check that string sizes are not negative, to prevent an
+       overflow in cases where we are passed incorrectly-created
+       strings with negative lengths (due to a bug in other code).
+    */
+    if (Py_SIZE(a) < 0 || Py_SIZE(b) < 0 ||
+        Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "strings are too large to concat");
+        return NULL;
+    }
+
+    /* Inline PyObject_NewVar */
+    if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "strings are too large to concat");
+        return NULL;
+    }
+    op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
+    if (op == NULL)
+        return PyErr_NoMemory();
+    PyObject_INIT_VAR(op, &PyString_Type, size);
+    op->ob_shash = -1;
+    op->ob_sstate = SSTATE_NOT_INTERNED;
+    Py_MEMCPY(op->ob_sval, a->ob_sval, Py_SIZE(a));
+    Py_MEMCPY(op->ob_sval + Py_SIZE(a), b->ob_sval, Py_SIZE(b));
+    op->ob_sval[size] = '\0';
+    return (PyObject *) op;
+#undef b
+}
+
+static PyObject *
+string_repeat(register PyStringObject *a, register Py_ssize_t n)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    register Py_ssize_t size;
+    register PyStringObject *op;
+    size_t nbytes;
+    if (n < 0)
+        n = 0;
+    /* watch out for overflows:  the size can overflow int,
+     * and the # of bytes needed can overflow size_t
+     */
+    size = Py_SIZE(a) * n;
+    if (n && size / n != Py_SIZE(a)) {
+        PyErr_SetString(PyExc_OverflowError,
+            "repeated string is too long");
+        return NULL;
+    }
+    if (size == Py_SIZE(a) && PyString_CheckExact(a)) {
+        Py_INCREF(a);
+        return (PyObject *)a;
+    }
+    nbytes = (size_t)size;
+    if (nbytes + PyStringObject_SIZE <= nbytes) {
+        PyErr_SetString(PyExc_OverflowError,
+            "repeated string is too long");
+        return NULL;
+    }
+    op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + nbytes);
+    if (op == NULL)
+        return PyErr_NoMemory();
+    PyObject_INIT_VAR(op, &PyString_Type, size);
+    op->ob_shash = -1;
+    op->ob_sstate = SSTATE_NOT_INTERNED;
+    op->ob_sval[size] = '\0';
+    if (Py_SIZE(a) == 1 && n > 0) {
+        memset(op->ob_sval, a->ob_sval[0] , n);
+        return (PyObject *) op;
+    }
+    i = 0;
+    if (i < size) {
+        Py_MEMCPY(op->ob_sval, a->ob_sval, Py_SIZE(a));
+        i = Py_SIZE(a);
+    }
+    while (i < size) {
+        j = (i <= size-i)  ?  i  :  size-i;
+        Py_MEMCPY(op->ob_sval+i, op->ob_sval, j);
+        i += j;
+    }
+    return (PyObject *) op;
+}
+
+/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
+
+static PyObject *
+string_slice(register PyStringObject *a, register Py_ssize_t i,
+             register Py_ssize_t j)
+     /* j -- may be negative! */
+{
+    if (i < 0)
+        i = 0;
+    if (j < 0)
+        j = 0; /* Avoid signed/unsigned bug in next line */
+    if (j > Py_SIZE(a))
+        j = Py_SIZE(a);
+    if (i == 0 && j == Py_SIZE(a) && PyString_CheckExact(a)) {
+        /* It's the same as a */
+        Py_INCREF(a);
+        return (PyObject *)a;
+    }
+    if (j < i)
+        j = i;
+    return PyString_FromStringAndSize(a->ob_sval + i, j-i);
+}
+
+static int
+string_contains(PyObject *str_obj, PyObject *sub_obj)
+{
+    if (!PyString_CheckExact(sub_obj)) {
+#ifdef Py_USING_UNICODE
+        if (PyUnicode_Check(sub_obj))
+            return PyUnicode_Contains(str_obj, sub_obj);
+#endif
+        if (!PyString_Check(sub_obj)) {
+            PyErr_Format(PyExc_TypeError,
+                "'in <string>' requires string as left operand, "
+                "not %.200s", Py_TYPE(sub_obj)->tp_name);
+            return -1;
+        }
+    }
+
+    return stringlib_contains_obj(str_obj, sub_obj);
+}
+
+static PyObject *
+string_item(PyStringObject *a, register Py_ssize_t i)
+{
+    char pchar;
+    PyObject *v;
+    if (i < 0 || i >= Py_SIZE(a)) {
+        PyErr_SetString(PyExc_IndexError, "string index out of range");
+        return NULL;
+    }
+    pchar = a->ob_sval[i];
+    v = (PyObject *)characters[pchar & UCHAR_MAX];
+    if (v == NULL)
+        v = PyString_FromStringAndSize(&pchar, 1);
+    else {
+#ifdef COUNT_ALLOCS
+        one_strings++;
+#endif
+        Py_INCREF(v);
+    }
+    return v;
+}
+
+static PyObject*
+string_richcompare(PyStringObject *a, PyStringObject *b, int op)
+{
+    int c;
+    Py_ssize_t len_a, len_b;
+    Py_ssize_t min_len;
+    PyObject *result;
+
+    /* Make sure both arguments are strings. */
+    if (!(PyString_Check(a) && PyString_Check(b))) {
+        result = Py_NotImplemented;
+        goto out;
+    }
+    if (a == b) {
+        switch (op) {
+        case Py_EQ:case Py_LE:case Py_GE:
+            result = Py_True;
+            goto out;
+        case Py_NE:case Py_LT:case Py_GT:
+            result = Py_False;
+            goto out;
+        }
+    }
+    if (op == Py_EQ) {
+        /* Supporting Py_NE here as well does not save
+           much time, since Py_NE is rarely used.  */
+        if (Py_SIZE(a) == Py_SIZE(b)
+            && (a->ob_sval[0] == b->ob_sval[0]
+            && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) {
+            result = Py_True;
+        } else {
+            result = Py_False;
+        }
+        goto out;
+    }
+    len_a = Py_SIZE(a); len_b = Py_SIZE(b);
+    min_len = (len_a < len_b) ? len_a : len_b;
+    if (min_len > 0) {
+        c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
+        if (c==0)
+            c = memcmp(a->ob_sval, b->ob_sval, min_len);
+    } else
+        c = 0;
+    if (c == 0)
+        c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
+    switch (op) {
+    case Py_LT: c = c <  0; break;
+    case Py_LE: c = c <= 0; break;
+    case Py_EQ: assert(0);  break; /* unreachable */
+    case Py_NE: c = c != 0; break;
+    case Py_GT: c = c >  0; break;
+    case Py_GE: c = c >= 0; break;
+    default:
+        result = Py_NotImplemented;
+        goto out;
+    }
+    result = c ? Py_True : Py_False;
+  out:
+    Py_INCREF(result);
+    return result;
+}
+
+int
+_PyString_Eq(PyObject *o1, PyObject *o2)
+{
+    PyStringObject *a = (PyStringObject*) o1;
+    PyStringObject *b = (PyStringObject*) o2;
+    return Py_SIZE(a) == Py_SIZE(b)
+      && *a->ob_sval == *b->ob_sval
+      && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0;
+}
+
+static long
+string_hash(PyStringObject *a)
+{
+    register Py_ssize_t len;
+    register unsigned char *p;
+    register long x;
+
+#ifdef Py_DEBUG
+    assert(_Py_HashSecret_Initialized);
+#endif
+    if (a->ob_shash != -1)
+        return a->ob_shash;
+    len = Py_SIZE(a);
+    /*
+      We make the hash of the empty string be 0, rather than using
+      (prefix ^ suffix), since this slightly obfuscates the hash secret
+    */
+    if (len == 0) {
+        a->ob_shash = 0;
+        return 0;
+    }
+    p = (unsigned char *) a->ob_sval;
+    x = _Py_HashSecret.prefix;
+    x ^= *p << 7;
+    while (--len >= 0)
+        x = (1000003*x) ^ *p++;
+    x ^= Py_SIZE(a);
+    x ^= _Py_HashSecret.suffix;
+    if (x == -1)
+        x = -2;
+    a->ob_shash = x;
+    return x;
+}
+
+static PyObject*
+string_subscript(PyStringObject* self, PyObject* item)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += PyString_GET_SIZE(self);
+        return string_item(self, i);
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+        char* source_buf;
+        char* result_buf;
+        PyObject* result;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item,
+                         PyString_GET_SIZE(self),
+                         &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0) {
+            return PyString_FromStringAndSize("", 0);
+        }
+        else if (start == 0 && step == 1 &&
+                 slicelength == PyString_GET_SIZE(self) &&
+                 PyString_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject *)self;
+        }
+        else if (step == 1) {
+            return PyString_FromStringAndSize(
+                PyString_AS_STRING(self) + start,
+                slicelength);
+        }
+        else {
+            source_buf = PyString_AsString((PyObject*)self);
+            result_buf = (char *)PyMem_Malloc(slicelength);
+            if (result_buf == NULL)
+                return PyErr_NoMemory();
+
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                result_buf[i] = source_buf[cur];
+            }
+
+            result = PyString_FromStringAndSize(result_buf,
+                                                slicelength);
+            PyMem_Free(result_buf);
+            return result;
+        }
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "string indices must be integers, not %.200s",
+                     Py_TYPE(item)->tp_name);
+        return NULL;
+    }
+}
+
+static Py_ssize_t
+string_buffer_getreadbuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
+{
+    if ( index != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent string segment");
+        return -1;
+    }
+    *ptr = (void *)self->ob_sval;
+    return Py_SIZE(self);
+}
+
+static Py_ssize_t
+string_buffer_getwritebuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "Cannot use string as modifiable buffer");
+    return -1;
+}
+
+static Py_ssize_t
+string_buffer_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
+{
+    if ( lenp )
+        *lenp = Py_SIZE(self);
+    return 1;
+}
+
+static Py_ssize_t
+string_buffer_getcharbuf(PyStringObject *self, Py_ssize_t index, const char **ptr)
+{
+    if ( index != 0 ) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent string segment");
+        return -1;
+    }
+    *ptr = self->ob_sval;
+    return Py_SIZE(self);
+}
+
+static int
+string_buffer_getbuffer(PyStringObject *self, Py_buffer *view, int flags)
+{
+    return PyBuffer_FillInfo(view, (PyObject*)self,
+                             (void *)self->ob_sval, Py_SIZE(self),
+                             1, flags);
+}
+
+static PySequenceMethods string_as_sequence = {
+    (lenfunc)string_length, /*sq_length*/
+    (binaryfunc)string_concat, /*sq_concat*/
+    (ssizeargfunc)string_repeat, /*sq_repeat*/
+    (ssizeargfunc)string_item, /*sq_item*/
+    (ssizessizeargfunc)string_slice, /*sq_slice*/
+    0,                  /*sq_ass_item*/
+    0,                  /*sq_ass_slice*/
+    (objobjproc)string_contains /*sq_contains*/
+};
+
+static PyMappingMethods string_as_mapping = {
+    (lenfunc)string_length,
+    (binaryfunc)string_subscript,
+    0,
+};
+
+static PyBufferProcs string_as_buffer = {
+    (readbufferproc)string_buffer_getreadbuf,
+    (writebufferproc)string_buffer_getwritebuf,
+    (segcountproc)string_buffer_getsegcount,
+    (charbufferproc)string_buffer_getcharbuf,
+    (getbufferproc)string_buffer_getbuffer,
+    0, /* XXX */
+};
+
+
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+/* Arrays indexed by above */
+static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+
+#define STRIPNAME(i) (stripformat[i]+3)
+
+PyDoc_STRVAR(split__doc__,
+"S.split([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in the string S, using sep as the\n\
+delimiter string.  If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified or is None, any\n\
+whitespace string is a separator and empty strings are removed\n\
+from the result.");
+
+static PyObject *
+string_split(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t len = PyString_GET_SIZE(self), n;
+    Py_ssize_t maxsplit = -1;
+    const char *s = PyString_AS_STRING(self), *sub;
+    PyObject *subobj = Py_None;
+
+    if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
+        return NULL;
+    if (maxsplit < 0)
+        maxsplit = PY_SSIZE_T_MAX;
+    if (subobj == Py_None)
+        return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
+    if (PyString_Check(subobj)) {
+        sub = PyString_AS_STRING(subobj);
+        n = PyString_GET_SIZE(subobj);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(subobj))
+        return PyUnicode_Split((PyObject *)self, subobj, maxsplit);
+#endif
+    else if (PyObject_AsCharBuffer(subobj, &sub, &n))
+        return NULL;
+
+    return stringlib_split((PyObject*) self, s, len, sub, n, maxsplit);
+}
+
+PyDoc_STRVAR(partition__doc__,
+"S.partition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, and return the part before it,\n\
+the separator itself, and the part after it.  If the separator is not\n\
+found, return S and two empty strings.");
+
+static PyObject *
+string_partition(PyStringObject *self, PyObject *sep_obj)
+{
+    const char *sep;
+    Py_ssize_t sep_len;
+
+    if (PyString_Check(sep_obj)) {
+        sep = PyString_AS_STRING(sep_obj);
+        sep_len = PyString_GET_SIZE(sep_obj);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(sep_obj))
+        return PyUnicode_Partition((PyObject *) self, sep_obj);
+#endif
+    else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+        return NULL;
+
+    return stringlib_partition(
+        (PyObject*) self,
+        PyString_AS_STRING(self), PyString_GET_SIZE(self),
+        sep_obj, sep, sep_len
+        );
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+"S.rpartition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, starting at the end of S, and return\n\
+the part before it, the separator itself, and the part after it.  If the\n\
+separator is not found, return two empty strings and S.");
+
+static PyObject *
+string_rpartition(PyStringObject *self, PyObject *sep_obj)
+{
+    const char *sep;
+    Py_ssize_t sep_len;
+
+    if (PyString_Check(sep_obj)) {
+        sep = PyString_AS_STRING(sep_obj);
+        sep_len = PyString_GET_SIZE(sep_obj);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(sep_obj))
+        return PyUnicode_RPartition((PyObject *) self, sep_obj);
+#endif
+    else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+        return NULL;
+
+    return stringlib_rpartition(
+        (PyObject*) self,
+        PyString_AS_STRING(self), PyString_GET_SIZE(self),
+        sep_obj, sep, sep_len
+        );
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+"S.rsplit([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in the string S, using sep as the\n\
+delimiter string, starting at the end of the string and working\n\
+to the front.  If maxsplit is given, at most maxsplit splits are\n\
+done. If sep is not specified or is None, any whitespace string\n\
+is a separator.");
+
+static PyObject *
+string_rsplit(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t len = PyString_GET_SIZE(self), n;
+    Py_ssize_t maxsplit = -1;
+    const char *s = PyString_AS_STRING(self), *sub;
+    PyObject *subobj = Py_None;
+
+    if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
+        return NULL;
+    if (maxsplit < 0)
+        maxsplit = PY_SSIZE_T_MAX;
+    if (subobj == Py_None)
+        return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
+    if (PyString_Check(subobj)) {
+        sub = PyString_AS_STRING(subobj);
+        n = PyString_GET_SIZE(subobj);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(subobj))
+        return PyUnicode_RSplit((PyObject *)self, subobj, maxsplit);
+#endif
+    else if (PyObject_AsCharBuffer(subobj, &sub, &n))
+        return NULL;
+
+    return stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit);
+}
+
+
+PyDoc_STRVAR(join__doc__,
+"S.join(iterable) -> string\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+iterable.  The separator between elements is S.");
+
+static PyObject *
+string_join(PyStringObject *self, PyObject *orig)
+{
+    char *sep = PyString_AS_STRING(self);
+    const Py_ssize_t seplen = PyString_GET_SIZE(self);
+    PyObject *res = NULL;
+    char *p;
+    Py_ssize_t seqlen = 0;
+    size_t sz = 0;
+    Py_ssize_t i;
+    PyObject *seq, *item;
+
+    seq = PySequence_Fast(orig, "");
+    if (seq == NULL) {
+        return NULL;
+    }
+
+    seqlen = PySequence_Size(seq);
+    if (seqlen == 0) {
+        Py_DECREF(seq);
+        return PyString_FromString("");
+    }
+    if (seqlen == 1) {
+        item = PySequence_Fast_GET_ITEM(seq, 0);
+        if (PyString_CheckExact(item) || PyUnicode_CheckExact(item)) {
+            Py_INCREF(item);
+            Py_DECREF(seq);
+            return item;
+        }
+    }
+
+    /* There are at least two things to join, or else we have a subclass
+     * of the builtin types in the sequence.
+     * Do a pre-pass to figure out the total amount of space we'll
+     * need (sz), see whether any argument is absurd, and defer to
+     * the Unicode join if appropriate.
+     */
+    for (i = 0; i < seqlen; i++) {
+        const size_t old_sz = sz;
+        item = PySequence_Fast_GET_ITEM(seq, i);
+        if (!PyString_Check(item)){
+#ifdef Py_USING_UNICODE
+            if (PyUnicode_Check(item)) {
+                /* Defer to Unicode join.
+                 * CAUTION:  There's no gurantee that the
+                 * original sequence can be iterated over
+                 * again, so we must pass seq here.
+                 */
+                PyObject *result;
+                result = PyUnicode_Join((PyObject *)self, seq);
+                Py_DECREF(seq);
+                return result;
+            }
+#endif
+            PyErr_Format(PyExc_TypeError,
+                         "sequence item %zd: expected string,"
+                         " %.80s found",
+                         i, Py_TYPE(item)->tp_name);
+            Py_DECREF(seq);
+            return NULL;
+        }
+        sz += PyString_GET_SIZE(item);
+        if (i != 0)
+            sz += seplen;
+        if (sz < old_sz || sz > PY_SSIZE_T_MAX) {
+            PyErr_SetString(PyExc_OverflowError,
+                "join() result is too long for a Python string");
+            Py_DECREF(seq);
+            return NULL;
+        }
+    }
+
+    /* Allocate result space. */
+    res = PyString_FromStringAndSize((char*)NULL, sz);
+    if (res == NULL) {
+        Py_DECREF(seq);
+        return NULL;
+    }
+
+    /* Catenate everything. */
+    p = PyString_AS_STRING(res);
+    for (i = 0; i < seqlen; ++i) {
+        size_t n;
+        item = PySequence_Fast_GET_ITEM(seq, i);
+        n = PyString_GET_SIZE(item);
+        Py_MEMCPY(p, PyString_AS_STRING(item), n);
+        p += n;
+        if (i < seqlen - 1) {
+            Py_MEMCPY(p, sep, seplen);
+            p += seplen;
+        }
+    }
+
+    Py_DECREF(seq);
+    return res;
+}
+
+PyObject *
+_PyString_Join(PyObject *sep, PyObject *x)
+{
+    assert(sep != NULL && PyString_Check(sep));
+    assert(x != NULL);
+    return string_join((PyStringObject *)sep, x);
+}
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len)         \
+    if (end > len)                          \
+        end = len;                          \
+    else if (end < 0) {                     \
+        end += len;                         \
+        if (end < 0)                        \
+        end = 0;                        \
+    }                                       \
+    if (start < 0) {                        \
+        start += len;                       \
+        if (start < 0)                      \
+        start = 0;                      \
+    }
+
+Py_LOCAL_INLINE(Py_ssize_t)
+string_find_internal(PyStringObject *self, PyObject *args, int dir)
+{
+    PyObject *subobj;
+    const char *sub;
+    Py_ssize_t sub_len;
+    Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+
+    if (!stringlib_parse_args_finds("find/rfind/index/rindex",
+                                    args, &subobj, &start, &end))
+        return -2;
+
+    if (PyString_Check(subobj)) {
+        sub = PyString_AS_STRING(subobj);
+        sub_len = PyString_GET_SIZE(subobj);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(subobj))
+        return PyUnicode_Find(
+            (PyObject *)self, subobj, start, end, dir);
+#endif
+    else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
+        /* XXX - the "expected a character buffer object" is pretty
+           confusing for a non-expert.  remap to something else ? */
+        return -2;
+
+    if (dir > 0)
+        return stringlib_find_slice(
+            PyString_AS_STRING(self), PyString_GET_SIZE(self),
+            sub, sub_len, start, end);
+    else
+        return stringlib_rfind_slice(
+            PyString_AS_STRING(self), PyString_GET_SIZE(self),
+            sub, sub_len, start, end);
+}
+
+
+PyDoc_STRVAR(find__doc__,
+"S.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+string_find(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t result = string_find_internal(self, args, +1);
+    if (result == -2)
+        return NULL;
+    return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(index__doc__,
+"S.index(sub [,start [,end]]) -> int\n\
+\n\
+Like S.find() but raise ValueError when the substring is not found.");
+
+static PyObject *
+string_index(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t result = string_find_internal(self, args, +1);
+    if (result == -2)
+        return NULL;
+    if (result == -1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "substring not found");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"S.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+string_rfind(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t result = string_find_internal(self, args, -1);
+    if (result == -2)
+        return NULL;
+    return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rindex__doc__,
+"S.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like S.rfind() but raise ValueError when the substring is not found.");
+
+static PyObject *
+string_rindex(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t result = string_find_internal(self, args, -1);
+    if (result == -2)
+        return NULL;
+    if (result == -1) {
+        PyErr_SetString(PyExc_ValueError,
+                        "substring not found");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(result);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj)
+{
+    char *s = PyString_AS_STRING(self);
+    Py_ssize_t len = PyString_GET_SIZE(self);
+    char *sep = PyString_AS_STRING(sepobj);
+    Py_ssize_t seplen = PyString_GET_SIZE(sepobj);
+    Py_ssize_t i, j;
+
+    i = 0;
+    if (striptype != RIGHTSTRIP) {
+        while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) {
+            i++;
+        }
+    }
+
+    j = len;
+    if (striptype != LEFTSTRIP) {
+        do {
+            j--;
+        } while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen));
+        j++;
+    }
+
+    if (i == 0 && j == len && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*)self;
+    }
+    else
+        return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_strip(PyStringObject *self, int striptype)
+{
+    char *s = PyString_AS_STRING(self);
+    Py_ssize_t len = PyString_GET_SIZE(self), i, j;
+
+    i = 0;
+    if (striptype != RIGHTSTRIP) {
+        while (i < len && isspace(Py_CHARMASK(s[i]))) {
+            i++;
+        }
+    }
+
+    j = len;
+    if (striptype != LEFTSTRIP) {
+        do {
+            j--;
+        } while (j >= i && isspace(Py_CHARMASK(s[j])));
+        j++;
+    }
+
+    if (i == 0 && j == len && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*)self;
+    }
+    else
+        return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_argstrip(PyStringObject *self, int striptype, PyObject *args)
+{
+    PyObject *sep = NULL;
+
+    if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+        return NULL;
+
+    if (sep != NULL && sep != Py_None) {
+        if (PyString_Check(sep))
+            return do_xstrip(self, striptype, sep);
+#ifdef Py_USING_UNICODE
+        else if (PyUnicode_Check(sep)) {
+            PyObject *uniself = PyUnicode_FromObject((PyObject *)self);
+            PyObject *res;
+            if (uniself==NULL)
+                return NULL;
+            res = _PyUnicode_XStrip((PyUnicodeObject *)uniself,
+                striptype, sep);
+            Py_DECREF(uniself);
+            return res;
+        }
+#endif
+        PyErr_Format(PyExc_TypeError,
+#ifdef Py_USING_UNICODE
+                     "%s arg must be None, str or unicode",
+#else
+                     "%s arg must be None or str",
+#endif
+                     STRIPNAME(striptype));
+        return NULL;
+    }
+
+    return do_strip(self, striptype);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+"S.strip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with leading and trailing\n\
+whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_strip(PyStringObject *self, PyObject *args)
+{
+    if (PyTuple_GET_SIZE(args) == 0)
+        return do_strip(self, BOTHSTRIP); /* Common case */
+    else
+        return do_argstrip(self, BOTHSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+"S.lstrip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with leading whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_lstrip(PyStringObject *self, PyObject *args)
+{
+    if (PyTuple_GET_SIZE(args) == 0)
+        return do_strip(self, LEFTSTRIP); /* Common case */
+    else
+        return do_argstrip(self, LEFTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+"S.rstrip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with trailing whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_rstrip(PyStringObject *self, PyObject *args)
+{
+    if (PyTuple_GET_SIZE(args) == 0)
+        return do_strip(self, RIGHTSTRIP); /* Common case */
+    else
+        return do_argstrip(self, RIGHTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lower__doc__,
+"S.lower() -> string\n\
+\n\
+Return a copy of the string S converted to lowercase.");
+
+/* _tolower and _toupper are defined by SUSv2, but they're not ISO C */
+#ifndef _tolower
+#define _tolower tolower
+#endif
+
+static PyObject *
+string_lower(PyStringObject *self)
+{
+    char *s;
+    Py_ssize_t i, n = PyString_GET_SIZE(self);
+    PyObject *newobj;
+
+    newobj = PyString_FromStringAndSize(NULL, n);
+    if (!newobj)
+        return NULL;
+
+    s = PyString_AS_STRING(newobj);
+
+    Py_MEMCPY(s, PyString_AS_STRING(self), n);
+
+    for (i = 0; i < n; i++) {
+        int c = Py_CHARMASK(s[i]);
+        if (isupper(c))
+            s[i] = _tolower(c);
+    }
+
+    return newobj;
+}
+
+PyDoc_STRVAR(upper__doc__,
+"S.upper() -> string\n\
+\n\
+Return a copy of the string S converted to uppercase.");
+
+#ifndef _toupper
+#define _toupper toupper
+#endif
+
+static PyObject *
+string_upper(PyStringObject *self)
+{
+    char *s;
+    Py_ssize_t i, n = PyString_GET_SIZE(self);
+    PyObject *newobj;
+
+    newobj = PyString_FromStringAndSize(NULL, n);
+    if (!newobj)
+        return NULL;
+
+    s = PyString_AS_STRING(newobj);
+
+    Py_MEMCPY(s, PyString_AS_STRING(self), n);
+
+    for (i = 0; i < n; i++) {
+        int c = Py_CHARMASK(s[i]);
+        if (islower(c))
+            s[i] = _toupper(c);
+    }
+
+    return newobj;
+}
+
+PyDoc_STRVAR(title__doc__,
+"S.title() -> string\n\
+\n\
+Return a titlecased version of S, i.e. words start with uppercase\n\
+characters, all remaining cased characters have lowercase.");
+
+static PyObject*
+string_title(PyStringObject *self)
+{
+    char *s = PyString_AS_STRING(self), *s_new;
+    Py_ssize_t i, n = PyString_GET_SIZE(self);
+    int previous_is_cased = 0;
+    PyObject *newobj;
+
+    newobj = PyString_FromStringAndSize(NULL, n);
+    if (newobj == NULL)
+        return NULL;
+    s_new = PyString_AsString(newobj);
+    for (i = 0; i < n; i++) {
+        int c = Py_CHARMASK(*s++);
+        if (islower(c)) {
+            if (!previous_is_cased)
+                c = toupper(c);
+            previous_is_cased = 1;
+        } else if (isupper(c)) {
+            if (previous_is_cased)
+                c = tolower(c);
+            previous_is_cased = 1;
+        } else
+            previous_is_cased = 0;
+        *s_new++ = c;
+    }
+    return newobj;
+}
+
+PyDoc_STRVAR(capitalize__doc__,
+"S.capitalize() -> string\n\
+\n\
+Return a copy of the string S with only its first character\n\
+capitalized.");
+
+static PyObject *
+string_capitalize(PyStringObject *self)
+{
+    char *s = PyString_AS_STRING(self), *s_new;
+    Py_ssize_t i, n = PyString_GET_SIZE(self);
+    PyObject *newobj;
+
+    newobj = PyString_FromStringAndSize(NULL, n);
+    if (newobj == NULL)
+        return NULL;
+    s_new = PyString_AsString(newobj);
+    if (0 < n) {
+        int c = Py_CHARMASK(*s++);
+        if (islower(c))
+            *s_new = toupper(c);
+        else
+            *s_new = c;
+        s_new++;
+    }
+    for (i = 1; i < n; i++) {
+        int c = Py_CHARMASK(*s++);
+        if (isupper(c))
+            *s_new = tolower(c);
+        else
+            *s_new = c;
+        s_new++;
+    }
+    return newobj;
+}
+
+
+PyDoc_STRVAR(count__doc__,
+"S.count(sub[, start[, end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of substring sub in\n\
+string S[start:end].  Optional arguments start and end are interpreted\n\
+as in slice notation.");
+
+static PyObject *
+string_count(PyStringObject *self, PyObject *args)
+{
+    PyObject *sub_obj;
+    const char *str = PyString_AS_STRING(self), *sub;
+    Py_ssize_t sub_len;
+    Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
+
+    if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
+        return NULL;
+
+    if (PyString_Check(sub_obj)) {
+        sub = PyString_AS_STRING(sub_obj);
+        sub_len = PyString_GET_SIZE(sub_obj);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(sub_obj)) {
+        Py_ssize_t count;
+        count = PyUnicode_Count((PyObject *)self, sub_obj, start, end);
+        if (count == -1)
+            return NULL;
+        else
+            return PyInt_FromSsize_t(count);
+    }
+#endif
+    else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
+        return NULL;
+
+    ADJUST_INDICES(start, end, PyString_GET_SIZE(self));
+
+    return PyInt_FromSsize_t(
+        stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
+        );
+}
+
+PyDoc_STRVAR(swapcase__doc__,
+"S.swapcase() -> string\n\
+\n\
+Return a copy of the string S with uppercase characters\n\
+converted to lowercase and vice versa.");
+
+static PyObject *
+string_swapcase(PyStringObject *self)
+{
+    char *s = PyString_AS_STRING(self), *s_new;
+    Py_ssize_t i, n = PyString_GET_SIZE(self);
+    PyObject *newobj;
+
+    newobj = PyString_FromStringAndSize(NULL, n);
+    if (newobj == NULL)
+        return NULL;
+    s_new = PyString_AsString(newobj);
+    for (i = 0; i < n; i++) {
+        int c = Py_CHARMASK(*s++);
+        if (islower(c)) {
+            *s_new = toupper(c);
+        }
+        else if (isupper(c)) {
+            *s_new = tolower(c);
+        }
+        else
+            *s_new = c;
+        s_new++;
+    }
+    return newobj;
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"S.translate(table [,deletechars]) -> string\n\
+\n\
+Return a copy of the string S, where all characters occurring\n\
+in the optional argument deletechars are removed, and the\n\
+remaining characters have been mapped through the given\n\
+translation table, which must be a string of length 256 or None.\n\
+If the table argument is None, no translation is applied and\n\
+the operation simply removes the characters in deletechars.");
+
+static PyObject *
+string_translate(PyStringObject *self, PyObject *args)
+{
+    register char *input, *output;
+    const char *table;
+    register Py_ssize_t i, c, changed = 0;
+    PyObject *input_obj = (PyObject*)self;
+    const char *output_start, *del_table=NULL;
+    Py_ssize_t inlen, tablen, dellen = 0;
+    PyObject *result;
+    int trans_table[256];
+    PyObject *tableobj, *delobj = NULL;
+
+    if (!PyArg_UnpackTuple(args, "translate", 1, 2,
+                          &tableobj, &delobj))
+        return NULL;
+
+    if (PyString_Check(tableobj)) {
+        table = PyString_AS_STRING(tableobj);
+        tablen = PyString_GET_SIZE(tableobj);
+    }
+    else if (tableobj == Py_None) {
+        table = NULL;
+        tablen = 256;
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(tableobj)) {
+        /* Unicode .translate() does not support the deletechars
+           parameter; instead a mapping to None will cause characters
+           to be deleted. */
+        if (delobj != NULL) {
+            PyErr_SetString(PyExc_TypeError,
+            "deletions are implemented differently for unicode");
+            return NULL;
+        }
+        return PyUnicode_Translate((PyObject *)self, tableobj, NULL);
+    }
+#endif
+    else if (PyObject_AsCharBuffer(tableobj, &table, &tablen))
+        return NULL;
+
+    if (tablen != 256) {
+        PyErr_SetString(PyExc_ValueError,
+          "translation table must be 256 characters long");
+        return NULL;
+    }
+
+    if (delobj != NULL) {
+        if (PyString_Check(delobj)) {
+            del_table = PyString_AS_STRING(delobj);
+            dellen = PyString_GET_SIZE(delobj);
+        }
+#ifdef Py_USING_UNICODE
+        else if (PyUnicode_Check(delobj)) {
+            PyErr_SetString(PyExc_TypeError,
+            "deletions are implemented differently for unicode");
+            return NULL;
+        }
+#endif
+        else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
+            return NULL;
+    }
+    else {
+        del_table = NULL;
+        dellen = 0;
+    }
+
+    inlen = PyString_GET_SIZE(input_obj);
+    result = PyString_FromStringAndSize((char *)NULL, inlen);
+    if (result == NULL)
+        return NULL;
+    output_start = output = PyString_AsString(result);
+    input = PyString_AS_STRING(input_obj);
+
+    if (dellen == 0 && table != NULL) {
+        /* If no deletions are required, use faster code */
+        for (i = inlen; --i >= 0; ) {
+            c = Py_CHARMASK(*input++);
+            if (Py_CHARMASK((*output++ = table[c])) != c)
+                changed = 1;
+        }
+        if (changed || !PyString_CheckExact(input_obj))
+            return result;
+        Py_DECREF(result);
+        Py_INCREF(input_obj);
+        return input_obj;
+    }
+
+    if (table == NULL) {
+        for (i = 0; i < 256; i++)
+            trans_table[i] = Py_CHARMASK(i);
+    } else {
+        for (i = 0; i < 256; i++)
+            trans_table[i] = Py_CHARMASK(table[i]);
+    }
+
+    for (i = 0; i < dellen; i++)
+        trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
+
+    for (i = inlen; --i >= 0; ) {
+        c = Py_CHARMASK(*input++);
+        if (trans_table[c] != -1)
+            if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+                continue;
+        changed = 1;
+    }
+    if (!changed && PyString_CheckExact(input_obj)) {
+        Py_DECREF(result);
+        Py_INCREF(input_obj);
+        return input_obj;
+    }
+    /* Fix the size of the resulting string */
+    if (inlen > 0 && _PyString_Resize(&result, output - output_start))
+        return NULL;
+    return result;
+}
+
+
+/* find and count characters and substrings */
+
+#define findchar(target, target_len, c)                         \
+  ((char *)memchr((const void *)(target), c, target_len))
+
+/* String ops must return a string.  */
+/* If the object is subclass of string, create a copy */
+Py_LOCAL(PyStringObject *)
+return_self(PyStringObject *self)
+{
+    if (PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return self;
+    }
+    return (PyStringObject *)PyString_FromStringAndSize(
+        PyString_AS_STRING(self),
+        PyString_GET_SIZE(self));
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countchar(const char *target, int target_len, char c, Py_ssize_t maxcount)
+{
+    Py_ssize_t count=0;
+    const char *start=target;
+    const char *end=target+target_len;
+
+    while ( (start=findchar(start, end-start, c)) != NULL ) {
+        count++;
+        if (count >= maxcount)
+            break;
+        start += 1;
+    }
+    return count;
+}
+
+
+/* Algorithms for different cases of string replacement */
+
+/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_interleave(PyStringObject *self,
+                   const char *to_s, Py_ssize_t to_len,
+                   Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, i, product;
+    PyStringObject *result;
+
+    self_len = PyString_GET_SIZE(self);
+
+    /* 1 at the end plus 1 after every character */
+    count = self_len+1;
+    if (maxcount < count)
+        count = maxcount;
+
+    /* Check for overflow */
+    /*   result_len = count * to_len + self_len; */
+    product = count * to_len;
+    if (product / to_len != count) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "replace string is too long");
+        return NULL;
+    }
+    result_len = product + self_len;
+    if (result_len < 0) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "replace string is too long");
+        return NULL;
+    }
+
+    if (! (result = (PyStringObject *)
+                     PyString_FromStringAndSize(NULL, result_len)) )
+        return NULL;
+
+    self_s = PyString_AS_STRING(self);
+    result_s = PyString_AS_STRING(result);
+
+    /* TODO: special case single character, which doesn't need memcpy */
+
+    /* Lay the first one down (guaranteed this will occur) */
+    Py_MEMCPY(result_s, to_s, to_len);
+    result_s += to_len;
+    count -= 1;
+
+    for (i=0; i<count; i++) {
+        *result_s++ = *self_s++;
+        Py_MEMCPY(result_s, to_s, to_len);
+        result_s += to_len;
+    }
+
+    /* Copy the rest of the original string */
+    Py_MEMCPY(result_s, self_s, self_len-i);
+
+    return result;
+}
+
+/* Special case for deleting a single character */
+/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_delete_single_character(PyStringObject *self,
+                                char from_c, Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count;
+    PyStringObject *result;
+
+    self_len = PyString_GET_SIZE(self);
+    self_s = PyString_AS_STRING(self);
+
+    count = countchar(self_s, self_len, from_c, maxcount);
+    if (count == 0) {
+        return return_self(self);
+    }
+
+    result_len = self_len - count;  /* from_len == 1 */
+    assert(result_len>=0);
+
+    if ( (result = (PyStringObject *)
+                    PyString_FromStringAndSize(NULL, result_len)) == NULL)
+        return NULL;
+    result_s = PyString_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        next = findchar(start, end-start, from_c);
+        if (next == NULL)
+            break;
+        Py_MEMCPY(result_s, start, next-start);
+        result_s += (next-start);
+        start = next+1;
+    }
+    Py_MEMCPY(result_s, start, end-start);
+
+    return result;
+}
+
+/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
+
+Py_LOCAL(PyStringObject *)
+replace_delete_substring(PyStringObject *self,
+                         const char *from_s, Py_ssize_t from_len,
+                         Py_ssize_t maxcount) {
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, offset;
+    PyStringObject *result;
+
+    self_len = PyString_GET_SIZE(self);
+    self_s = PyString_AS_STRING(self);
+
+    count = stringlib_count(self_s, self_len,
+                            from_s, from_len,
+                            maxcount);
+
+    if (count == 0) {
+        /* no matches */
+        return return_self(self);
+    }
+
+    result_len = self_len - (count * from_len);
+    assert (result_len>=0);
+
+    if ( (result = (PyStringObject *)
+          PyString_FromStringAndSize(NULL, result_len)) == NULL )
+        return NULL;
+
+    result_s = PyString_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        offset = stringlib_find(start, end-start,
+                                from_s, from_len,
+                                0);
+        if (offset == -1)
+            break;
+        next = start + offset;
+
+        Py_MEMCPY(result_s, start, next-start);
+
+        result_s += (next-start);
+        start = next+from_len;
+    }
+    Py_MEMCPY(result_s, start, end-start);
+    return result;
+}
+
+/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_single_character_in_place(PyStringObject *self,
+                                  char from_c, char to_c,
+                                  Py_ssize_t maxcount)
+{
+    char *self_s, *result_s, *start, *end, *next;
+    Py_ssize_t self_len;
+    PyStringObject *result;
+
+    /* The result string will be the same size */
+    self_s = PyString_AS_STRING(self);
+    self_len = PyString_GET_SIZE(self);
+
+    next = findchar(self_s, self_len, from_c);
+
+    if (next == NULL) {
+        /* No matches; return the original string */
+        return return_self(self);
+    }
+
+    /* Need to make a new string */
+    result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
+    if (result == NULL)
+        return NULL;
+    result_s = PyString_AS_STRING(result);
+    Py_MEMCPY(result_s, self_s, self_len);
+
+    /* change everything in-place, starting with this one */
+    start =  result_s + (next-self_s);
+    *start = to_c;
+    start++;
+    end = result_s + self_len;
+
+    while (--maxcount > 0) {
+        next = findchar(start, end-start, from_c);
+        if (next == NULL)
+            break;
+        *next = to_c;
+        start = next+1;
+    }
+
+    return result;
+}
+
+/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_substring_in_place(PyStringObject *self,
+                           const char *from_s, Py_ssize_t from_len,
+                           const char *to_s, Py_ssize_t to_len,
+                           Py_ssize_t maxcount)
+{
+    char *result_s, *start, *end;
+    char *self_s;
+    Py_ssize_t self_len, offset;
+    PyStringObject *result;
+
+    /* The result string will be the same size */
+
+    self_s = PyString_AS_STRING(self);
+    self_len = PyString_GET_SIZE(self);
+
+    offset = stringlib_find(self_s, self_len,
+                            from_s, from_len,
+                            0);
+    if (offset == -1) {
+        /* No matches; return the original string */
+        return return_self(self);
+    }
+
+    /* Need to make a new string */
+    result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
+    if (result == NULL)
+        return NULL;
+    result_s = PyString_AS_STRING(result);
+    Py_MEMCPY(result_s, self_s, self_len);
+
+    /* change everything in-place, starting with this one */
+    start =  result_s + offset;
+    Py_MEMCPY(start, to_s, from_len);
+    start += from_len;
+    end = result_s + self_len;
+
+    while ( --maxcount > 0) {
+        offset = stringlib_find(start, end-start,
+                                from_s, from_len,
+                                0);
+        if (offset==-1)
+            break;
+        Py_MEMCPY(start+offset, to_s, from_len);
+        start += offset+from_len;
+    }
+
+    return result;
+}
+
+/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_single_character(PyStringObject *self,
+                         char from_c,
+                         const char *to_s, Py_ssize_t to_len,
+                         Py_ssize_t maxcount)
+{
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, product;
+    PyStringObject *result;
+
+    self_s = PyString_AS_STRING(self);
+    self_len = PyString_GET_SIZE(self);
+
+    count = countchar(self_s, self_len, from_c, maxcount);
+    if (count == 0) {
+        /* no matches, return unchanged */
+        return return_self(self);
+    }
+
+    /* use the difference between current and new, hence the "-1" */
+    /*   result_len = self_len + count * (to_len-1)  */
+    product = count * (to_len-1);
+    if (product / (to_len-1) != count) {
+        PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+        return NULL;
+    }
+    result_len = self_len + product;
+    if (result_len < 0) {
+        PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+        return NULL;
+    }
+
+    if ( (result = (PyStringObject *)
+          PyString_FromStringAndSize(NULL, result_len)) == NULL)
+        return NULL;
+    result_s = PyString_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        next = findchar(start, end-start, from_c);
+        if (next == NULL)
+            break;
+
+        if (next == start) {
+            /* replace with the 'to' */
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start += 1;
+        } else {
+            /* copy the unchanged old then the 'to' */
+            Py_MEMCPY(result_s, start, next-start);
+            result_s += (next-start);
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start = next+1;
+        }
+    }
+    /* Copy the remainder of the remaining string */
+    Py_MEMCPY(result_s, start, end-start);
+
+    return result;
+}
+
+/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_substring(PyStringObject *self,
+                  const char *from_s, Py_ssize_t from_len,
+                  const char *to_s, Py_ssize_t to_len,
+                  Py_ssize_t maxcount) {
+    char *self_s, *result_s;
+    char *start, *next, *end;
+    Py_ssize_t self_len, result_len;
+    Py_ssize_t count, offset, product;
+    PyStringObject *result;
+
+    self_s = PyString_AS_STRING(self);
+    self_len = PyString_GET_SIZE(self);
+
+    count = stringlib_count(self_s, self_len,
+                            from_s, from_len,
+                            maxcount);
+
+    if (count == 0) {
+        /* no matches, return unchanged */
+        return return_self(self);
+    }
+
+    /* Check for overflow */
+    /*    result_len = self_len + count * (to_len-from_len) */
+    product = count * (to_len-from_len);
+    if (product / (to_len-from_len) != count) {
+        PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+        return NULL;
+    }
+    result_len = self_len + product;
+    if (result_len < 0) {
+        PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+        return NULL;
+    }
+
+    if ( (result = (PyStringObject *)
+          PyString_FromStringAndSize(NULL, result_len)) == NULL)
+        return NULL;
+    result_s = PyString_AS_STRING(result);
+
+    start = self_s;
+    end = self_s + self_len;
+    while (count-- > 0) {
+        offset = stringlib_find(start, end-start,
+                                from_s, from_len,
+                                0);
+        if (offset == -1)
+            break;
+        next = start+offset;
+        if (next == start) {
+            /* replace with the 'to' */
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start += from_len;
+        } else {
+            /* copy the unchanged old then the 'to' */
+            Py_MEMCPY(result_s, start, next-start);
+            result_s += (next-start);
+            Py_MEMCPY(result_s, to_s, to_len);
+            result_s += to_len;
+            start = next+from_len;
+        }
+    }
+    /* Copy the remainder of the remaining string */
+    Py_MEMCPY(result_s, start, end-start);
+
+    return result;
+}
+
+
+Py_LOCAL(PyStringObject *)
+replace(PyStringObject *self,
+    const char *from_s, Py_ssize_t from_len,
+    const char *to_s, Py_ssize_t to_len,
+    Py_ssize_t maxcount)
+{
+    if (maxcount < 0) {
+        maxcount = PY_SSIZE_T_MAX;
+    } else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) {
+        /* nothing to do; return the original string */
+        return return_self(self);
+    }
+
+    if (maxcount == 0 ||
+        (from_len == 0 && to_len == 0)) {
+        /* nothing to do; return the original string */
+        return return_self(self);
+    }
+
+    /* Handle zero-length special cases */
+
+    if (from_len == 0) {
+        /* insert the 'to' string everywhere.   */
+        /*    >>> "Python".replace("", ".")     */
+        /*    '.P.y.t.h.o.n.'                   */
+        return replace_interleave(self, to_s, to_len, maxcount);
+    }
+
+    /* Except for "".replace("", "A") == "A" there is no way beyond this */
+    /* point for an empty self string to generate a non-empty string */
+    /* Special case so the remaining code always gets a non-empty string */
+    if (PyString_GET_SIZE(self) == 0) {
+        return return_self(self);
+    }
+
+    if (to_len == 0) {
+        /* delete all occurances of 'from' string */
+        if (from_len == 1) {
+            return replace_delete_single_character(
+                self, from_s[0], maxcount);
+        } else {
+            return replace_delete_substring(self, from_s, from_len, maxcount);
+        }
+    }
+
+    /* Handle special case where both strings have the same length */
+
+    if (from_len == to_len) {
+        if (from_len == 1) {
+            return replace_single_character_in_place(
+                self,
+                from_s[0],
+                to_s[0],
+                maxcount);
+        } else {
+            return replace_substring_in_place(
+                self, from_s, from_len, to_s, to_len, maxcount);
+        }
+    }
+
+    /* Otherwise use the more generic algorithms */
+    if (from_len == 1) {
+        return replace_single_character(self, from_s[0],
+                                        to_s, to_len, maxcount);
+    } else {
+        /* len('from')>=2, len('to')>=1 */
+        return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
+    }
+}
+
+PyDoc_STRVAR(replace__doc__,
+"S.replace(old, new[, count]) -> string\n\
+\n\
+Return a copy of string S with all occurrences of substring\n\
+old replaced by new.  If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject *
+string_replace(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t count = -1;
+    PyObject *from, *to;
+    const char *from_s, *to_s;
+    Py_ssize_t from_len, to_len;
+
+    if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
+        return NULL;
+
+    if (PyString_Check(from)) {
+        from_s = PyString_AS_STRING(from);
+        from_len = PyString_GET_SIZE(from);
+    }
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(from))
+        return PyUnicode_Replace((PyObject *)self,
+                                 from, to, count);
+#endif
+    else if (PyObject_AsCharBuffer(from, &from_s, &from_len))
+        return NULL;
+
+    if (PyString_Check(to)) {
+        to_s = PyString_AS_STRING(to);
+        to_len = PyString_GET_SIZE(to);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(to))
+        return PyUnicode_Replace((PyObject *)self,
+                                 from, to, count);
+#endif
+    else if (PyObject_AsCharBuffer(to, &to_s, &to_len))
+        return NULL;
+
+    return (PyObject *)replace((PyStringObject *) self,
+                               from_s, from_len,
+                               to_s, to_len, count);
+}
+
+/** End DALKE **/
+
+/* Matches the end (direction >= 0) or start (direction < 0) of self
+ * against substr, using the start and end arguments. Returns
+ * -1 on error, 0 if not found and 1 if found.
+ */
+Py_LOCAL(int)
+_string_tailmatch(PyStringObject *self, PyObject *substr, Py_ssize_t start,
+                  Py_ssize_t end, int direction)
+{
+    Py_ssize_t len = PyString_GET_SIZE(self);
+    Py_ssize_t slen;
+    const char* sub;
+    const char* str;
+
+    if (PyString_Check(substr)) {
+        sub = PyString_AS_STRING(substr);
+        slen = PyString_GET_SIZE(substr);
+    }
+#ifdef Py_USING_UNICODE
+    else if (PyUnicode_Check(substr))
+        return PyUnicode_Tailmatch((PyObject *)self,
+                                   substr, start, end, direction);
+#endif
+    else if (PyObject_AsCharBuffer(substr, &sub, &slen))
+        return -1;
+    str = PyString_AS_STRING(self);
+
+    ADJUST_INDICES(start, end, len);
+
+    if (direction < 0) {
+        /* startswith */
+        if (start+slen > len)
+            return 0;
+    } else {
+        /* endswith */
+        if (end-start < slen || start > len)
+            return 0;
+
+        if (end-slen > start)
+            start = end - slen;
+    }
+    if (end-start >= slen)
+        return ! memcmp(str+start, sub, slen);
+    return 0;
+}
+
+
+PyDoc_STRVAR(startswith__doc__,
+"S.startswith(prefix[, start[, end]]) -> bool\n\
+\n\
+Return True if S starts with the specified prefix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+string_startswith(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    PyObject *subobj;
+    int result;
+
+    if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
+        return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            result = _string_tailmatch(self,
+                            PyTuple_GET_ITEM(subobj, i),
+                            start, end, -1);
+            if (result == -1)
+                return NULL;
+            else if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        Py_RETURN_FALSE;
+    }
+    result = _string_tailmatch(self, subobj, start, end, -1);
+    if (result == -1) {
+        if (PyErr_ExceptionMatches(PyExc_TypeError))
+            PyErr_Format(PyExc_TypeError, "startswith first arg must be str, "
+                         "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+        return NULL;
+    }
+    else
+        return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(endswith__doc__,
+"S.endswith(suffix[, start[, end]]) -> bool\n\
+\n\
+Return True if S ends with the specified suffix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+string_endswith(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    PyObject *subobj;
+    int result;
+
+    if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
+        return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            result = _string_tailmatch(self,
+                            PyTuple_GET_ITEM(subobj, i),
+                            start, end, +1);
+            if (result == -1)
+                return NULL;
+            else if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        Py_RETURN_FALSE;
+    }
+    result = _string_tailmatch(self, subobj, start, end, +1);
+    if (result == -1) {
+        if (PyErr_ExceptionMatches(PyExc_TypeError))
+            PyErr_Format(PyExc_TypeError, "endswith first arg must be str, "
+                         "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+        return NULL;
+    }
+    else
+        return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(encode__doc__,
+"S.encode([encoding[,errors]]) -> object\n\
+\n\
+Encodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that is able to handle UnicodeEncodeErrors.");
+
+static PyObject *
+string_encode(PyStringObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = {"encoding", "errors", 0};
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode",
+                                     kwlist, &encoding, &errors))
+        return NULL;
+    v = PyString_AsEncodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+
+PyDoc_STRVAR(decode__doc__,
+"S.decode([encoding[,errors]]) -> object\n\
+\n\
+Decodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registered with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+string_decode(PyStringObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = {"encoding", "errors", 0};
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode",
+                                     kwlist, &encoding, &errors))
+        return NULL;
+    v = PyString_AsDecodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+
+PyDoc_STRVAR(expandtabs__doc__,
+"S.expandtabs([tabsize]) -> string\n\
+\n\
+Return a copy of S where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+string_expandtabs(PyStringObject *self, PyObject *args)
+{
+    const char *e, *p, *qe;
+    char *q;
+    Py_ssize_t i, j, incr;
+    PyObject *u;
+    int tabsize = 8;
+
+    if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+        return NULL;
+
+    /* First pass: determine size of output string */
+    i = 0; /* chars up to and including most recent \n or \r */
+    j = 0; /* chars since most recent \n or \r (use in tab calculations) */
+    e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); /* end of input */
+    for (p = PyString_AS_STRING(self); p < e; p++)
+    if (*p == '\t') {
+        if (tabsize > 0) {
+            incr = tabsize - (j % tabsize);
+            if (j > PY_SSIZE_T_MAX - incr)
+                goto overflow1;
+            j += incr;
+        }
+    }
+    else {
+        if (j > PY_SSIZE_T_MAX - 1)
+            goto overflow1;
+        j++;
+        if (*p == '\n' || *p == '\r') {
+            if (i > PY_SSIZE_T_MAX - j)
+                goto overflow1;
+            i += j;
+            j = 0;
+        }
+    }
+
+    if (i > PY_SSIZE_T_MAX - j)
+        goto overflow1;
+
+    /* Second pass: create output string and fill it */
+    u = PyString_FromStringAndSize(NULL, i + j);
+    if (!u)
+        return NULL;
+
+    j = 0; /* same as in first pass */
+    q = PyString_AS_STRING(u); /* next output char */
+    qe = PyString_AS_STRING(u) + PyString_GET_SIZE(u); /* end of output */
+
+    for (p = PyString_AS_STRING(self); p < e; p++)
+    if (*p == '\t') {
+        if (tabsize > 0) {
+            i = tabsize - (j % tabsize);
+            j += i;
+            while (i--) {
+                if (q >= qe)
+                    goto overflow2;
+                *q++ = ' ';
+            }
+        }
+    }
+    else {
+        if (q >= qe)
+            goto overflow2;
+        *q++ = *p;
+        j++;
+        if (*p == '\n' || *p == '\r')
+            j = 0;
+    }
+
+    return u;
+
+  overflow2:
+    Py_DECREF(u);
+  overflow1:
+    PyErr_SetString(PyExc_OverflowError, "new string is too long");
+    return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+pad(PyStringObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
+{
+    PyObject *u;
+
+    if (left < 0)
+        left = 0;
+    if (right < 0)
+        right = 0;
+
+    if (left == 0 && right == 0 && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject *)self;
+    }
+
+    u = PyString_FromStringAndSize(NULL,
+                                   left + PyString_GET_SIZE(self) + right);
+    if (u) {
+        if (left)
+            memset(PyString_AS_STRING(u), fill, left);
+        Py_MEMCPY(PyString_AS_STRING(u) + left,
+               PyString_AS_STRING(self),
+               PyString_GET_SIZE(self));
+        if (right)
+            memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self),
+               fill, right);
+    }
+
+    return u;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+"S.ljust(width[, fillchar]) -> string\n"
+"\n"
+"Return S left-justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+string_ljust(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return pad(self, 0, width - PyString_GET_SIZE(self), fillchar);
+}
+
+
+PyDoc_STRVAR(rjust__doc__,
+"S.rjust(width[, fillchar]) -> string\n"
+"\n"
+"Return S right-justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+string_rjust(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return pad(self, width - PyString_GET_SIZE(self), 0, fillchar);
+}
+
+
+PyDoc_STRVAR(center__doc__,
+"S.center(width[, fillchar]) -> string\n"
+"\n"
+"Return S centered in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+string_center(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t marg, left;
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    marg = width - PyString_GET_SIZE(self);
+    left = marg / 2 + (marg & width & 1);
+
+    return pad(self, left, marg - left, fillchar);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+"S.zfill(width) -> string\n"
+"\n"
+"Pad a numeric string S with zeros on the left, to fill a field\n"
+"of the specified width.  The string S is never truncated.");
+
+static PyObject *
+string_zfill(PyStringObject *self, PyObject *args)
+{
+    Py_ssize_t fill;
+    PyObject *s;
+    char *p;
+    Py_ssize_t width;
+
+    if (!PyArg_ParseTuple(args, "n:zfill", &width))
+        return NULL;
+
+    if (PyString_GET_SIZE(self) >= width) {
+        if (PyString_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject*) self;
+        }
+        else
+            return PyString_FromStringAndSize(
+            PyString_AS_STRING(self),
+            PyString_GET_SIZE(self)
+            );
+    }
+
+    fill = width - PyString_GET_SIZE(self);
+
+    s = pad(self, fill, 0, '0');
+
+    if (s == NULL)
+        return NULL;
+
+    p = PyString_AS_STRING(s);
+    if (p[fill] == '+' || p[fill] == '-') {
+        /* move sign to beginning of string */
+        p[0] = p[fill];
+        p[fill] = '0';
+    }
+
+    return (PyObject*) s;
+}
+
+PyDoc_STRVAR(isspace__doc__,
+"S.isspace() -> bool\n\
+\n\
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isspace(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+        isspace(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!isspace(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isalpha__doc__,
+"S.isalpha() -> bool\n\
+\n\
+Return True if all characters in S are alphabetic\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isalpha(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+        isalpha(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!isalpha(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isalnum__doc__,
+"S.isalnum() -> bool\n\
+\n\
+Return True if all characters in S are alphanumeric\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isalnum(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+        isalnum(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!isalnum(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isdigit__doc__,
+"S.isdigit() -> bool\n\
+\n\
+Return True if all characters in S are digits\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isdigit(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1 &&
+        isdigit(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!isdigit(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(islower__doc__,
+"S.islower() -> bool\n\
+\n\
+Return True if all cased characters in S are lowercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+string_islower(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1)
+        return PyBool_FromLong(islower(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+        if (isupper(*p))
+            return PyBool_FromLong(0);
+        else if (!cased && islower(*p))
+            cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(isupper__doc__,
+"S.isupper() -> bool\n\
+\n\
+Return True if all cased characters in S are uppercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+string_isupper(PyStringObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1)
+        return PyBool_FromLong(isupper(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+        if (islower(*p))
+            return PyBool_FromLong(0);
+        else if (!cased && isupper(*p))
+            cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(istitle__doc__,
+"S.istitle() -> bool\n\
+\n\
+Return True if S is a titlecased string and there is at least one\n\
+character in S, i.e. uppercase characters may only follow uncased\n\
+characters and lowercase characters only cased ones. Return False\n\
+otherwise.");
+
+static PyObject*
+string_istitle(PyStringObject *self, PyObject *uncased)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyString_AS_STRING(self);
+    register const unsigned char *e;
+    int cased, previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyString_GET_SIZE(self) == 1)
+        return PyBool_FromLong(isupper(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyString_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyString_GET_SIZE(self);
+    cased = 0;
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+        register const unsigned char ch = *p;
+
+        if (isupper(ch)) {
+            if (previous_is_cased)
+                return PyBool_FromLong(0);
+            previous_is_cased = 1;
+            cased = 1;
+        }
+        else if (islower(ch)) {
+            if (!previous_is_cased)
+                return PyBool_FromLong(0);
+            previous_is_cased = 1;
+            cased = 1;
+        }
+        else
+            previous_is_cased = 0;
+    }
+    return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(splitlines__doc__,
+"S.splitlines(keepends=False) -> list of strings\n\
+\n\
+Return a list of the lines in S, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+string_splitlines(PyStringObject *self, PyObject *args)
+{
+    int keepends = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+        return NULL;
+
+    return stringlib_splitlines(
+        (PyObject*) self, PyString_AS_STRING(self), PyString_GET_SIZE(self),
+        keepends
+    );
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+"S.__sizeof__() -> size of S in memory, in bytes");
+
+static PyObject *
+string_sizeof(PyStringObject *v)
+{
+    Py_ssize_t res;
+    res = PyStringObject_SIZE + PyString_GET_SIZE(v) * Py_TYPE(v)->tp_itemsize;
+    return PyInt_FromSsize_t(res);
+}
+
+static PyObject *
+string_getnewargs(PyStringObject *v)
+{
+    return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v));
+}
+
+
+#include "stringlib/string_format.h"
+
+PyDoc_STRVAR(format__doc__,
+"S.format(*args, **kwargs) -> string\n\
+\n\
+Return a formatted version of S, using substitutions from args and kwargs.\n\
+The substitutions are identified by braces ('{' and '}').");
+
+static PyObject *
+string__format__(PyObject* self, PyObject* args)
+{
+    PyObject *format_spec;
+    PyObject *result = NULL;
+    PyObject *tmp = NULL;
+
+    /* If 2.x, convert format_spec to the same type as value */
+    /* This is to allow things like u''.format('') */
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+        goto done;
+    if (!(PyString_Check(format_spec) || PyUnicode_Check(format_spec))) {
+        PyErr_Format(PyExc_TypeError, "__format__ arg must be str "
+                     "or unicode, not %s", Py_TYPE(format_spec)->tp_name);
+        goto done;
+    }
+    tmp = PyObject_Str(format_spec);
+    if (tmp == NULL)
+        goto done;
+    format_spec = tmp;
+
+    result = _PyBytes_FormatAdvanced(self,
+                                     PyString_AS_STRING(format_spec),
+                                     PyString_GET_SIZE(format_spec));
+done:
+    Py_XDECREF(tmp);
+    return result;
+}
+
+PyDoc_STRVAR(p_format__doc__,
+"S.__format__(format_spec) -> string\n\
+\n\
+Return a formatted version of S as described by format_spec.");
+
+
+static PyMethodDef
+string_methods[] = {
+    /* Counterparts of the obsolete stropmodule functions; except
+       string.maketrans(). */
+    {"join", (PyCFunction)string_join, METH_O, join__doc__},
+    {"split", (PyCFunction)string_split, METH_VARARGS, split__doc__},
+    {"rsplit", (PyCFunction)string_rsplit, METH_VARARGS, rsplit__doc__},
+    {"lower", (PyCFunction)string_lower, METH_NOARGS, lower__doc__},
+    {"upper", (PyCFunction)string_upper, METH_NOARGS, upper__doc__},
+    {"islower", (PyCFunction)string_islower, METH_NOARGS, islower__doc__},
+    {"isupper", (PyCFunction)string_isupper, METH_NOARGS, isupper__doc__},
+    {"isspace", (PyCFunction)string_isspace, METH_NOARGS, isspace__doc__},
+    {"isdigit", (PyCFunction)string_isdigit, METH_NOARGS, isdigit__doc__},
+    {"istitle", (PyCFunction)string_istitle, METH_NOARGS, istitle__doc__},
+    {"isalpha", (PyCFunction)string_isalpha, METH_NOARGS, isalpha__doc__},
+    {"isalnum", (PyCFunction)string_isalnum, METH_NOARGS, isalnum__doc__},
+    {"capitalize", (PyCFunction)string_capitalize, METH_NOARGS,
+     capitalize__doc__},
+    {"count", (PyCFunction)string_count, METH_VARARGS, count__doc__},
+    {"endswith", (PyCFunction)string_endswith, METH_VARARGS,
+     endswith__doc__},
+    {"partition", (PyCFunction)string_partition, METH_O, partition__doc__},
+    {"find", (PyCFunction)string_find, METH_VARARGS, find__doc__},
+    {"index", (PyCFunction)string_index, METH_VARARGS, index__doc__},
+    {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__},
+    {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__},
+    {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__},
+    {"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__},
+    {"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__},
+    {"rpartition", (PyCFunction)string_rpartition, METH_O,
+     rpartition__doc__},
+    {"startswith", (PyCFunction)string_startswith, METH_VARARGS,
+     startswith__doc__},
+    {"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__},
+    {"swapcase", (PyCFunction)string_swapcase, METH_NOARGS,
+     swapcase__doc__},
+    {"translate", (PyCFunction)string_translate, METH_VARARGS,
+     translate__doc__},
+    {"title", (PyCFunction)string_title, METH_NOARGS, title__doc__},
+    {"ljust", (PyCFunction)string_ljust, METH_VARARGS, ljust__doc__},
+    {"rjust", (PyCFunction)string_rjust, METH_VARARGS, rjust__doc__},
+    {"center", (PyCFunction)string_center, METH_VARARGS, center__doc__},
+    {"zfill", (PyCFunction)string_zfill, METH_VARARGS, zfill__doc__},
+    {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
+    {"__format__", (PyCFunction) string__format__, METH_VARARGS, p_format__doc__},
+    {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
+    {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
+    {"encode", (PyCFunction)string_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
+    {"decode", (PyCFunction)string_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
+    {"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS,
+     expandtabs__doc__},
+    {"splitlines", (PyCFunction)string_splitlines, METH_VARARGS,
+     splitlines__doc__},
+    {"__sizeof__", (PyCFunction)string_sizeof, METH_NOARGS,
+     sizeof__doc__},
+    {"__getnewargs__",          (PyCFunction)string_getnewargs, METH_NOARGS},
+    {NULL,     NULL}                         /* sentinel */
+};
+
+static PyObject *
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *x = NULL;
+    static char *kwlist[] = {"object", 0};
+
+    if (type != &PyString_Type)
+        return str_subtype_new(type, args, kwds);
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
+        return NULL;
+    if (x == NULL)
+        return PyString_FromString("");
+    return PyObject_Str(x);
+}
+
+static PyObject *
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *tmp, *pnew;
+    Py_ssize_t n;
+
+    assert(PyType_IsSubtype(type, &PyString_Type));
+    tmp = string_new(&PyString_Type, args, kwds);
+    if (tmp == NULL)
+        return NULL;
+    assert(PyString_CheckExact(tmp));
+    n = PyString_GET_SIZE(tmp);
+    pnew = type->tp_alloc(type, n);
+    if (pnew != NULL) {
+        Py_MEMCPY(PyString_AS_STRING(pnew), PyString_AS_STRING(tmp), n+1);
+        ((PyStringObject *)pnew)->ob_shash =
+            ((PyStringObject *)tmp)->ob_shash;
+        ((PyStringObject *)pnew)->ob_sstate = SSTATE_NOT_INTERNED;
+    }
+    Py_DECREF(tmp);
+    return pnew;
+}
+
+static PyObject *
+basestring_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "The basestring type cannot be instantiated");
+    return NULL;
+}
+
+static PyObject *
+string_mod(PyObject *v, PyObject *w)
+{
+    if (!PyString_Check(v)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return PyString_Format(v, w);
+}
+
+PyDoc_STRVAR(basestring_doc,
+"Type basestring cannot be instantiated; it is the base for str and unicode.");
+
+static PyNumberMethods string_as_number = {
+    0,                          /*nb_add*/
+    0,                          /*nb_subtract*/
+    0,                          /*nb_multiply*/
+    0,                          /*nb_divide*/
+    string_mod,                 /*nb_remainder*/
+};
+
+
+PyTypeObject PyBaseString_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "basestring",
+    0,
+    0,
+    0,                                          /* 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 */
+    0,                                          /* tp_str */
+    0,                                          /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    basestring_doc,                             /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    &PyBaseObject_Type,                         /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    basestring_new,                             /* tp_new */
+    0,                                          /* tp_free */
+};
+
+PyDoc_STRVAR(string_doc,
+"str(object='') -> string\n\
+\n\
+Return a nice string representation of the object.\n\
+If the argument is a string, the return value is the same object.");
+
+PyTypeObject PyString_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "str",
+    PyStringObject_SIZE,
+    sizeof(char),
+    string_dealloc,                             /* tp_dealloc */
+    (printfunc)string_print,                    /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    string_repr,                                /* tp_repr */
+    &string_as_number,                          /* tp_as_number */
+    &string_as_sequence,                        /* tp_as_sequence */
+    &string_as_mapping,                         /* tp_as_mapping */
+    (hashfunc)string_hash,                      /* tp_hash */
+    0,                                          /* tp_call */
+    string_str,                                 /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    &string_as_buffer,                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_STRING_SUBCLASS |
+        Py_TPFLAGS_HAVE_NEWBUFFER,              /* tp_flags */
+    string_doc,                                 /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    (richcmpfunc)string_richcompare,            /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    string_methods,                             /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    &PyBaseString_Type,                         /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    string_new,                                 /* tp_new */
+    PyObject_Del,                               /* tp_free */
+};
+
+void
+PyString_Concat(register PyObject **pv, register PyObject *w)
+{
+    register PyObject *v;
+    if (*pv == NULL)
+        return;
+    if (w == NULL || !PyString_Check(*pv)) {
+        Py_CLEAR(*pv);
+        return;
+    }
+    v = string_concat((PyStringObject *) *pv, w);
+    Py_DECREF(*pv);
+    *pv = v;
+}
+
+void
+PyString_ConcatAndDel(register PyObject **pv, register PyObject *w)
+{
+    PyString_Concat(pv, w);
+    Py_XDECREF(w);
+}
+
+
+/* The following function breaks the notion that strings are immutable:
+   it changes the size of a string.  We get away with this only if there
+   is only one module referencing the object.  You can also think of it
+   as creating a new string object and destroying the old one, only
+   more efficiently.  In any case, don't use this if the string may
+   already be known to some other part of the code...
+   Note that if there's not enough memory to resize the string, the original
+   string object at *pv is deallocated, *pv is set to NULL, an "out of
+   memory" exception is set, and -1 is returned.  Else (on success) 0 is
+   returned, and the value in *pv may or may not be the same as on input.
+   As always, an extra byte is allocated for a trailing \0 byte (newsize
+   does *not* include that), and a trailing \0 byte is stored.
+*/
+
+int
+_PyString_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+    register PyObject *v;
+    register PyStringObject *sv;
+    v = *pv;
+    if (!PyString_Check(v) || Py_REFCNT(v) != 1 || newsize < 0 ||
+        PyString_CHECK_INTERNED(v)) {
+        *pv = 0;
+        Py_DECREF(v);
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    /* XXX UNREF/NEWREF interface should be more symmetrical */
+    _Py_DEC_REFTOTAL;
+    _Py_ForgetReference(v);
+    *pv = (PyObject *)
+        PyObject_REALLOC((char *)v, PyStringObject_SIZE + newsize);
+    if (*pv == NULL) {
+        PyObject_Del(v);
+        PyErr_NoMemory();
+        return -1;
+    }
+    _Py_NewReference(*pv);
+    sv = (PyStringObject *) *pv;
+    Py_SIZE(sv) = newsize;
+    sv->ob_sval[newsize] = '\0';
+    sv->ob_shash = -1;          /* invalidate cached hash value */
+    return 0;
+}
+
+/* Helpers for formatstring */
+
+Py_LOCAL_INLINE(PyObject *)
+getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
+{
+    Py_ssize_t argidx = *p_argidx;
+    if (argidx < arglen) {
+        (*p_argidx)++;
+        if (arglen < 0)
+            return args;
+        else
+            return PyTuple_GetItem(args, argidx);
+    }
+    PyErr_SetString(PyExc_TypeError,
+                    "not enough arguments for format string");
+    return NULL;
+}
+
+/* Format codes
+ * F_LJUST      '-'
+ * F_SIGN       '+'
+ * F_BLANK      ' '
+ * F_ALT        '#'
+ * F_ZERO       '0'
+ */
+#define F_LJUST (1<<0)
+#define F_SIGN  (1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT   (1<<3)
+#define F_ZERO  (1<<4)
+
+/* Returns a new reference to a PyString object, or NULL on failure. */
+
+static PyObject *
+formatfloat(PyObject *v, int flags, int prec, int type)
+{
+    char *p;
+    PyObject *result;
+    double x;
+
+    x = PyFloat_AsDouble(v);
+    if (x == -1.0 && PyErr_Occurred()) {
+        PyErr_Format(PyExc_TypeError, "float argument required, "
+                     "not %.200s", Py_TYPE(v)->tp_name);
+        return NULL;
+    }
+
+    if (prec < 0)
+        prec = 6;
+
+    p = PyOS_double_to_string(x, type, prec,
+                              (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL);
+
+    if (p == NULL)
+        return NULL;
+    result = PyString_FromStringAndSize(p, strlen(p));
+    PyMem_Free(p);
+    return result;
+}
+
+/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and
+ * the F_ALT flag, for Python's long (unbounded) ints.  It's not used for
+ * Python's regular ints.
+ * Return value:  a new PyString*, or NULL if error.
+ *  .  *pbuf is set to point into it,
+ *     *plen set to the # of chars following that.
+ *     Caller must decref it when done using pbuf.
+ *     The string starting at *pbuf is of the form
+ *         "-"? ("0x" | "0X")? digit+
+ *     "0x"/"0X" are present only for x and X conversions, with F_ALT
+ *         set in flags.  The case of hex digits will be correct,
+ *     There will be at least prec digits, zero-filled on the left if
+ *         necessary to get that many.
+ * val          object to be converted
+ * flags        bitmask of format flags; only F_ALT is looked at
+ * prec         minimum number of digits; 0-fill on left if needed
+ * type         a character in [duoxX]; u acts the same as d
+ *
+ * CAUTION:  o, x and X conversions on regular ints can never
+ * produce a '-' sign, but can for Python's unbounded ints.
+ */
+PyObject*
+_PyString_FormatLong(PyObject *val, int flags, int prec, int type,
+                     char **pbuf, int *plen)
+{
+    PyObject *result = NULL;
+    char *buf;
+    Py_ssize_t i;
+    int sign;           /* 1 if '-', else 0 */
+    int len;            /* number of characters */
+    Py_ssize_t llen;
+    int numdigits;      /* len == numnondigits + numdigits */
+    int numnondigits = 0;
+
+    switch (type) {
+    case 'd':
+    case 'u':
+        result = Py_TYPE(val)->tp_str(val);
+        break;
+    case 'o':
+        result = Py_TYPE(val)->tp_as_number->nb_oct(val);
+        break;
+    case 'x':
+    case 'X':
+        numnondigits = 2;
+        result = Py_TYPE(val)->tp_as_number->nb_hex(val);
+        break;
+    default:
+        assert(!"'type' not in [duoxX]");
+    }
+    if (!result)
+        return NULL;
+
+    buf = PyString_AsString(result);
+    if (!buf) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    /* To modify the string in-place, there can only be one reference. */
+    if (Py_REFCNT(result) != 1) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    llen = PyString_Size(result);
+    if (llen > INT_MAX) {
+        PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong");
+        return NULL;
+    }
+    len = (int)llen;
+    if (buf[len-1] == 'L') {
+        --len;
+        buf[len] = '\0';
+    }
+    sign = buf[0] == '-';
+    numnondigits += sign;
+    numdigits = len - numnondigits;
+    assert(numdigits > 0);
+
+    /* Get rid of base marker unless F_ALT */
+    if ((flags & F_ALT) == 0) {
+        /* Need to skip 0x, 0X or 0. */
+        int skipped = 0;
+        switch (type) {
+        case 'o':
+            assert(buf[sign] == '0');
+            /* If 0 is only digit, leave it alone. */
+            if (numdigits > 1) {
+                skipped = 1;
+                --numdigits;
+            }
+            break;
+        case 'x':
+        case 'X':
+            assert(buf[sign] == '0');
+            assert(buf[sign + 1] == 'x');
+            skipped = 2;
+            numnondigits -= 2;
+            break;
+        }
+        if (skipped) {
+            buf += skipped;
+            len -= skipped;
+            if (sign)
+                buf[0] = '-';
+        }
+        assert(len == numnondigits + numdigits);
+        assert(numdigits > 0);
+    }
+
+    /* Fill with leading zeroes to meet minimum width. */
+    if (prec > numdigits) {
+        PyObject *r1 = PyString_FromStringAndSize(NULL,
+                                numnondigits + prec);
+        char *b1;
+        if (!r1) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        b1 = PyString_AS_STRING(r1);
+        for (i = 0; i < numnondigits; ++i)
+            *b1++ = *buf++;
+        for (i = 0; i < prec - numdigits; i++)
+            *b1++ = '0';
+        for (i = 0; i < numdigits; i++)
+            *b1++ = *buf++;
+        *b1 = '\0';
+        Py_DECREF(result);
+        result = r1;
+        buf = PyString_AS_STRING(result);
+        len = numnondigits + prec;
+    }
+
+    /* Fix up case for hex conversions. */
+    if (type == 'X') {
+        /* Need to convert all lower case letters to upper case.
+           and need to convert 0x to 0X (and -0x to -0X). */
+        for (i = 0; i < len; i++)
+            if (buf[i] >= 'a' && buf[i] <= 'x')
+                buf[i] -= 'a'-'A';
+    }
+    *pbuf = buf;
+    *plen = len;
+    return result;
+}
+
+Py_LOCAL_INLINE(int)
+formatint(char *buf, size_t buflen, int flags,
+          int prec, int type, PyObject *v)
+{
+    /* fmt = '%#.' + `prec` + 'l' + `type`
+       worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+       + 1 + 1 = 24 */
+    char fmt[64];       /* plenty big enough! */
+    char *sign;
+    long x;
+
+    x = PyInt_AsLong(v);
+    if (x == -1 && PyErr_Occurred()) {
+        PyErr_Format(PyExc_TypeError, "int argument required, not %.200s",
+                     Py_TYPE(v)->tp_name);
+        return -1;
+    }
+    if (x < 0 && type == 'u') {
+        type = 'd';
+    }
+    if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
+        sign = "-";
+    else
+        sign = "";
+    if (prec < 0)
+        prec = 1;
+
+    if ((flags & F_ALT) &&
+        (type == 'x' || type == 'X')) {
+        /* When converting under %#x or %#X, there are a number
+         * of issues that cause pain:
+         * - when 0 is being converted, the C standard leaves off
+         *   the '0x' or '0X', which is inconsistent with other
+         *   %#x/%#X conversions and inconsistent with Python's
+         *   hex() function
+         * - there are platforms that violate the standard and
+         *   convert 0 with the '0x' or '0X'
+         *   (Metrowerks, Compaq Tru64)
+         * - there are platforms that give '0x' when converting
+         *   under %#X, but convert 0 in accordance with the
+         *   standard (OS/2 EMX)
+         *
+         * We can achieve the desired consistency by inserting our
+         * own '0x' or '0X' prefix, and substituting %x/%X in place
+         * of %#x/%#X.
+         *
+         * Note that this is the same approach as used in
+         * formatint() in unicodeobject.c
+         */
+        PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
+                      sign, type, prec, type);
+    }
+    else {
+        PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
+                      sign, (flags&F_ALT) ? "#" : "",
+                      prec, type);
+    }
+
+    /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
+     * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
+     */
+    if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
+        PyErr_SetString(PyExc_OverflowError,
+            "formatted integer is too long (precision too large?)");
+        return -1;
+    }
+    if (sign[0])
+        PyOS_snprintf(buf, buflen, fmt, -x);
+    else
+        PyOS_snprintf(buf, buflen, fmt, x);
+    return (int)strlen(buf);
+}
+
+Py_LOCAL_INLINE(int)
+formatchar(char *buf, size_t buflen, PyObject *v)
+{
+    /* presume that the buffer is at least 2 characters long */
+    if (PyString_Check(v)) {
+        if (!PyArg_Parse(v, "c;%c requires int or char", &buf[0]))
+            return -1;
+    }
+    else {
+        if (!PyArg_Parse(v, "b;%c requires int or char", &buf[0]))
+            return -1;
+    }
+    buf[1] = '\0';
+    return 1;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
+
+   FORMATBUFLEN is the length of the buffer in which the ints &
+   chars are formatted. XXX This is a magic number. Each formatting
+   routine does bounds checking to ensure no overflow, but a better
+   solution may be to malloc a buffer of appropriate size for each
+   format. For now, the current solution is sufficient.
+*/
+#define FORMATBUFLEN (size_t)120
+
+PyObject *
+PyString_Format(PyObject *format, PyObject *args)
+{
+    char *fmt, *res;
+    Py_ssize_t arglen, argidx;
+    Py_ssize_t reslen, rescnt, fmtcnt;
+    int args_owned = 0;
+    PyObject *result, *orig_args;
+#ifdef Py_USING_UNICODE
+    PyObject *v, *w;
+#endif
+    PyObject *dict = NULL;
+    if (format == NULL || !PyString_Check(format) || args == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    orig_args = args;
+    fmt = PyString_AS_STRING(format);
+    fmtcnt = PyString_GET_SIZE(format);
+    reslen = rescnt = fmtcnt + 100;
+    result = PyString_FromStringAndSize((char *)NULL, reslen);
+    if (result == NULL)
+        return NULL;
+    res = PyString_AsString(result);
+    if (PyTuple_Check(args)) {
+        arglen = PyTuple_GET_SIZE(args);
+        argidx = 0;
+    }
+    else {
+        arglen = -1;
+        argidx = -2;
+    }
+    if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript &&
+        !PyTuple_Check(args) && !PyObject_TypeCheck(args, &PyBaseString_Type))
+        dict = args;
+    while (--fmtcnt >= 0) {
+        if (*fmt != '%') {
+            if (--rescnt < 0) {
+                rescnt = fmtcnt + 100;
+                reslen += rescnt;
+                if (_PyString_Resize(&result, reslen))
+                    return NULL;
+                res = PyString_AS_STRING(result)
+                    + reslen - rescnt;
+                --rescnt;
+            }
+            *res++ = *fmt++;
+        }
+        else {
+            /* Got a format specifier */
+            int flags = 0;
+            Py_ssize_t width = -1;
+            int prec = -1;
+            int c = '\0';
+            int fill;
+            int isnumok;
+            PyObject *v = NULL;
+            PyObject *temp = NULL;
+            char *pbuf;
+            int sign;
+            Py_ssize_t len;
+            char formatbuf[FORMATBUFLEN];
+                 /* For format{int,char}() */
+#ifdef Py_USING_UNICODE
+            char *fmt_start = fmt;
+            Py_ssize_t argidx_start = argidx;
+#endif
+
+            fmt++;
+            if (*fmt == '(') {
+                char *keystart;
+                Py_ssize_t keylen;
+                PyObject *key;
+                int pcount = 1;
+
+                if (dict == NULL) {
+                    PyErr_SetString(PyExc_TypeError,
+                             "format requires a mapping");
+                    goto error;
+                }
+                ++fmt;
+                --fmtcnt;
+                keystart = fmt;
+                /* Skip over balanced parentheses */
+                while (pcount > 0 && --fmtcnt >= 0) {
+                    if (*fmt == ')')
+                        --pcount;
+                    else if (*fmt == '(')
+                        ++pcount;
+                    fmt++;
+                }
+                keylen = fmt - keystart - 1;
+                if (fmtcnt < 0 || pcount > 0) {
+                    PyErr_SetString(PyExc_ValueError,
+                               "incomplete format key");
+                    goto error;
+                }
+                key = PyString_FromStringAndSize(keystart,
+                                                 keylen);
+                if (key == NULL)
+                    goto error;
+                if (args_owned) {
+                    Py_DECREF(args);
+                    args_owned = 0;
+                }
+                args = PyObject_GetItem(dict, key);
+                Py_DECREF(key);
+                if (args == NULL) {
+                    goto error;
+                }
+                args_owned = 1;
+                arglen = -1;
+                argidx = -2;
+            }
+            while (--fmtcnt >= 0) {
+                switch (c = *fmt++) {
+                case '-': flags |= F_LJUST; continue;
+                case '+': flags |= F_SIGN; continue;
+                case ' ': flags |= F_BLANK; continue;
+                case '#': flags |= F_ALT; continue;
+                case '0': flags |= F_ZERO; continue;
+                }
+                break;
+            }
+            if (c == '*') {
+                v = getnextarg(args, arglen, &argidx);
+                if (v == NULL)
+                    goto error;
+                if (!PyInt_Check(v)) {
+                    PyErr_SetString(PyExc_TypeError,
+                                    "* wants int");
+                    goto error;
+                }
+                width = PyInt_AsSsize_t(v);
+                if (width == -1 && PyErr_Occurred())
+                    goto error;
+                if (width < 0) {
+                    flags |= F_LJUST;
+                    width = -width;
+                }
+                if (--fmtcnt >= 0)
+                    c = *fmt++;
+            }
+            else if (c >= 0 && isdigit(c)) {
+                width = c - '0';
+                while (--fmtcnt >= 0) {
+                    c = Py_CHARMASK(*fmt++);
+                    if (!isdigit(c))
+                        break;
+                    if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) {
+                        PyErr_SetString(
+                            PyExc_ValueError,
+                            "width too big");
+                        goto error;
+                    }
+                    width = width*10 + (c - '0');
+                }
+            }
+            if (c == '.') {
+                prec = 0;
+                if (--fmtcnt >= 0)
+                    c = *fmt++;
+                if (c == '*') {
+                    v = getnextarg(args, arglen, &argidx);
+                    if (v == NULL)
+                        goto error;
+                    if (!PyInt_Check(v)) {
+                        PyErr_SetString(
+                            PyExc_TypeError,
+                            "* wants int");
+                        goto error;
+                    }
+                    prec = _PyInt_AsInt(v);
+                    if (prec == -1 && PyErr_Occurred())
+                        goto error;
+                    if (prec < 0)
+                        prec = 0;
+                    if (--fmtcnt >= 0)
+                        c = *fmt++;
+                }
+                else if (c >= 0 && isdigit(c)) {
+                    prec = c - '0';
+                    while (--fmtcnt >= 0) {
+                        c = Py_CHARMASK(*fmt++);
+                        if (!isdigit(c))
+                            break;
+                        if (prec > (INT_MAX - ((int)c - '0')) / 10) {
+                            PyErr_SetString(
+                                PyExc_ValueError,
+                                "prec too big");
+                            goto error;
+                        }
+                        prec = prec*10 + (c - '0');
+                    }
+                }
+            } /* prec */
+            if (fmtcnt >= 0) {
+                if (c == 'h' || c == 'l' || c == 'L') {
+                    if (--fmtcnt >= 0)
+                        c = *fmt++;
+                }
+            }
+            if (fmtcnt < 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "incomplete format");
+                goto error;
+            }
+            if (c != '%') {
+                v = getnextarg(args, arglen, &argidx);
+                if (v == NULL)
+                    goto error;
+            }
+            sign = 0;
+            fill = ' ';
+            switch (c) {
+            case '%':
+                pbuf = "%";
+                len = 1;
+                break;
+            case 's':
+#ifdef Py_USING_UNICODE
+                if (PyUnicode_Check(v)) {
+                    fmt = fmt_start;
+                    argidx = argidx_start;
+                    goto unicode;
+                }
+#endif
+                temp = _PyObject_Str(v);
+#ifdef Py_USING_UNICODE
+                if (temp != NULL && PyUnicode_Check(temp)) {
+                    Py_DECREF(temp);
+                    fmt = fmt_start;
+                    argidx = argidx_start;
+                    goto unicode;
+                }
+#endif
+                /* Fall through */
+            case 'r':
+                if (c == 'r')
+                    temp = PyObject_Repr(v);
+                if (temp == NULL)
+                    goto error;
+                if (!PyString_Check(temp)) {
+                    PyErr_SetString(PyExc_TypeError,
+                      "%s argument has non-string str()");
+                    Py_DECREF(temp);
+                    goto error;
+                }
+                pbuf = PyString_AS_STRING(temp);
+                len = PyString_GET_SIZE(temp);
+                if (prec >= 0 && len > prec)
+                    len = prec;
+                break;
+            case 'i':
+            case 'd':
+            case 'u':
+            case 'o':
+            case 'x':
+            case 'X':
+                if (c == 'i')
+                    c = 'd';
+                isnumok = 0;
+                if (PyNumber_Check(v)) {
+                    PyObject *iobj=NULL;
+
+                    if (PyInt_Check(v) || (PyLong_Check(v))) {
+                        iobj = v;
+                        Py_INCREF(iobj);
+                    }
+                    else {
+                        iobj = PyNumber_Int(v);
+                        if (iobj==NULL) {
+                            PyErr_Clear();
+                            iobj = PyNumber_Long(v);
+                        }
+                    }
+                    if (iobj!=NULL) {
+                        if (PyInt_Check(iobj)) {
+                            isnumok = 1;
+                            pbuf = formatbuf;
+                            len = formatint(pbuf,
+                                            sizeof(formatbuf),
+                                            flags, prec, c, iobj);
+                            Py_DECREF(iobj);
+                            if (len < 0)
+                                goto error;
+                            sign = 1;
+                        }
+                        else if (PyLong_Check(iobj)) {
+                            int ilen;
+
+                            isnumok = 1;
+                            temp = _PyString_FormatLong(iobj, flags,
+                                prec, c, &pbuf, &ilen);
+                            Py_DECREF(iobj);
+                            len = ilen;
+                            if (!temp)
+                                goto error;
+                            sign = 1;
+                        }
+                        else {
+                            Py_DECREF(iobj);
+                        }
+                    }
+                }
+                if (!isnumok) {
+                    PyErr_Format(PyExc_TypeError,
+                        "%%%c format: a number is required, "
+                        "not %.200s", c, Py_TYPE(v)->tp_name);
+                    goto error;
+                }
+                if (flags & F_ZERO)
+                    fill = '0';
+                break;
+            case 'e':
+            case 'E':
+            case 'f':
+            case 'F':
+            case 'g':
+            case 'G':
+                temp = formatfloat(v, flags, prec, c);
+                if (temp == NULL)
+                    goto error;
+                pbuf = PyString_AS_STRING(temp);
+                len = PyString_GET_SIZE(temp);
+                sign = 1;
+                if (flags & F_ZERO)
+                    fill = '0';
+                break;
+            case 'c':
+#ifdef Py_USING_UNICODE
+                if (PyUnicode_Check(v)) {
+                    fmt = fmt_start;
+                    argidx = argidx_start;
+                    goto unicode;
+                }
+#endif
+                pbuf = formatbuf;
+                len = formatchar(pbuf, sizeof(formatbuf), v);
+                if (len < 0)
+                    goto error;
+                break;
+            default:
+                PyErr_Format(PyExc_ValueError,
+                  "unsupported format character '%c' (0x%x) "
+                  "at index %zd",
+                  c, c,
+                  (Py_ssize_t)(fmt - 1 -
+                               PyString_AsString(format)));
+                goto error;
+            }
+            if (sign) {
+                if (*pbuf == '-' || *pbuf == '+') {
+                    sign = *pbuf++;
+                    len--;
+                }
+                else if (flags & F_SIGN)
+                    sign = '+';
+                else if (flags & F_BLANK)
+                    sign = ' ';
+                else
+                    sign = 0;
+            }
+            if (width < len)
+                width = len;
+            if (rescnt - (sign != 0) < width) {
+                reslen -= rescnt;
+                rescnt = width + fmtcnt + 100;
+                reslen += rescnt;
+                if (reslen < 0) {
+                    Py_DECREF(result);
+                    Py_XDECREF(temp);
+                    return PyErr_NoMemory();
+                }
+                if (_PyString_Resize(&result, reslen)) {
+                    Py_XDECREF(temp);
+                    return NULL;
+                }
+                res = PyString_AS_STRING(result)
+                    + reslen - rescnt;
+            }
+            if (sign) {
+                if (fill != ' ')
+                    *res++ = sign;
+                rescnt--;
+                if (width > len)
+                    width--;
+            }
+            if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+                assert(pbuf[0] == '0');
+                assert(pbuf[1] == c);
+                if (fill != ' ') {
+                    *res++ = *pbuf++;
+                    *res++ = *pbuf++;
+                }
+                rescnt -= 2;
+                width -= 2;
+                if (width < 0)
+                    width = 0;
+                len -= 2;
+            }
+            if (width > len && !(flags & F_LJUST)) {
+                do {
+                    --rescnt;
+                    *res++ = fill;
+                } while (--width > len);
+            }
+            if (fill == ' ') {
+                if (sign)
+                    *res++ = sign;
+                if ((flags & F_ALT) &&
+                    (c == 'x' || c == 'X')) {
+                    assert(pbuf[0] == '0');
+                    assert(pbuf[1] == c);
+                    *res++ = *pbuf++;
+                    *res++ = *pbuf++;
+                }
+            }
+            Py_MEMCPY(res, pbuf, len);
+            res += len;
+            rescnt -= len;
+            while (--width >= len) {
+                --rescnt;
+                *res++ = ' ';
+            }
+            if (dict && (argidx < arglen) && c != '%') {
+                PyErr_SetString(PyExc_TypeError,
+                           "not all arguments converted during string formatting");
+                Py_XDECREF(temp);
+                goto error;
+            }
+            Py_XDECREF(temp);
+        } /* '%' */
+    } /* until end */
+    if (argidx < arglen && !dict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "not all arguments converted during string formatting");
+        goto error;
+    }
+    if (args_owned) {
+        Py_DECREF(args);
+    }
+    if (_PyString_Resize(&result, reslen - rescnt))
+        return NULL;
+    return result;
+
+#ifdef Py_USING_UNICODE
+ unicode:
+    if (args_owned) {
+        Py_DECREF(args);
+        args_owned = 0;
+    }
+    /* Fiddle args right (remove the first argidx arguments) */
+    if (PyTuple_Check(orig_args) && argidx > 0) {
+        PyObject *v;
+        Py_ssize_t n = PyTuple_GET_SIZE(orig_args) - argidx;
+        v = PyTuple_New(n);
+        if (v == NULL)
+            goto error;
+        while (--n >= 0) {
+            PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx);
+            Py_INCREF(w);
+            PyTuple_SET_ITEM(v, n, w);
+        }
+        args = v;
+    } else {
+        Py_INCREF(orig_args);
+        args = orig_args;
+    }
+    args_owned = 1;
+    /* Take what we have of the result and let the Unicode formatting
+       function format the rest of the input. */
+    rescnt = res - PyString_AS_STRING(result);
+    if (_PyString_Resize(&result, rescnt))
+        goto error;
+    fmtcnt = PyString_GET_SIZE(format) - \
+             (fmt - PyString_AS_STRING(format));
+    format = PyUnicode_Decode(fmt, fmtcnt, NULL, NULL);
+    if (format == NULL)
+        goto error;
+    v = PyUnicode_Format(format, args);
+    Py_DECREF(format);
+    if (v == NULL)
+        goto error;
+    /* Paste what we have (result) to what the Unicode formatting
+       function returned (v) and return the result (or error) */
+    w = PyUnicode_Concat(result, v);
+    Py_DECREF(result);
+    Py_DECREF(v);
+    Py_DECREF(args);
+    return w;
+#endif /* Py_USING_UNICODE */
+
+ error:
+    Py_DECREF(result);
+    if (args_owned) {
+        Py_DECREF(args);
+    }
+    return NULL;
+}
+
+void
+PyString_InternInPlace(PyObject **p)
+{
+    register PyStringObject *s = (PyStringObject *)(*p);
+    PyObject *t;
+    if (s == NULL || !PyString_Check(s))
+        Py_FatalError("PyString_InternInPlace: strings only please!");
+    /* If it's a string subclass, we don't really know what putting
+       it in the interned dict might do. */
+    if (!PyString_CheckExact(s))
+        return;
+    if (PyString_CHECK_INTERNED(s))
+        return;
+    if (interned == NULL) {
+        interned = PyDict_New();
+        if (interned == NULL) {
+            PyErr_Clear(); /* Don't leave an exception */
+            return;
+        }
+    }
+    t = PyDict_GetItem(interned, (PyObject *)s);
+    if (t) {
+        Py_INCREF(t);
+        Py_DECREF(*p);
+        *p = t;
+        return;
+    }
+
+    if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0) {
+        PyErr_Clear();
+        return;
+    }
+    /* The two references in interned are not counted by refcnt.
+       The string deallocator will take care of this */
+    Py_REFCNT(s) -= 2;
+    PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL;
+}
+
+void
+PyString_InternImmortal(PyObject **p)
+{
+    PyString_InternInPlace(p);
+    if (PyString_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) {
+        PyString_CHECK_INTERNED(*p) = SSTATE_INTERNED_IMMORTAL;
+        Py_INCREF(*p);
+    }
+}
+
+
+PyObject *
+PyString_InternFromString(const char *cp)
+{
+    PyObject *s = PyString_FromString(cp);
+    if (s == NULL)
+        return NULL;
+    PyString_InternInPlace(&s);
+    return s;
+}
+
+void
+PyString_Fini(void)
+{
+    int i;
+    for (i = 0; i < UCHAR_MAX + 1; i++)
+        Py_CLEAR(characters[i]);
+    Py_CLEAR(nullstring);
+}
+
+void _Py_ReleaseInternedStrings(void)
+{
+    PyObject *keys;
+    PyStringObject *s;
+    Py_ssize_t i, n;
+    Py_ssize_t immortal_size = 0, mortal_size = 0;
+
+    if (interned == NULL || !PyDict_Check(interned))
+        return;
+    keys = PyDict_Keys(interned);
+    if (keys == NULL || !PyList_Check(keys)) {
+        PyErr_Clear();
+        return;
+    }
+
+    /* Since _Py_ReleaseInternedStrings() is intended to help a leak
+       detector, interned strings are not forcibly deallocated; rather, we
+       give them their stolen references back, and then clear and DECREF
+       the interned dict. */
+
+    n = PyList_GET_SIZE(keys);
+    fprintf(stderr, "releasing %" PY_FORMAT_SIZE_T "d interned strings\n",
+        n);
+    for (i = 0; i < n; i++) {
+        s = (PyStringObject *) PyList_GET_ITEM(keys, i);
+        switch (s->ob_sstate) {
+        case SSTATE_NOT_INTERNED:
+            /* XXX Shouldn't happen */
+            break;
+        case SSTATE_INTERNED_IMMORTAL:
+            Py_REFCNT(s) += 1;
+            immortal_size += Py_SIZE(s);
+            break;
+        case SSTATE_INTERNED_MORTAL:
+            Py_REFCNT(s) += 2;
+            mortal_size += Py_SIZE(s);
+            break;
+        default:
+            Py_FatalError("Inconsistent interned string state.");
+        }
+        s->ob_sstate = SSTATE_NOT_INTERNED;
+    }
+    fprintf(stderr, "total size of all interned strings: "
+                    "%" PY_FORMAT_SIZE_T "d/%" PY_FORMAT_SIZE_T "d "
+                    "mortal/immortal\n", mortal_size, immortal_size);
+    Py_DECREF(keys);
+    PyDict_Clear(interned);
+    Py_CLEAR(interned);
+}
diff --git a/Python-2.7.5/Objects/structseq.c b/Python-2.7.5/Objects/structseq.c
new file mode 100644
index 0000000..75c1ffb
--- /dev/null
+++ b/Python-2.7.5/Objects/structseq.c
@@ -0,0 +1,540 @@
+/* Implementation helper: a struct that looks like a tuple.  See timemodule
+   and posixmodule for example uses. */
+
+#include "Python.h"
+#include "structmember.h"
+#include "structseq.h"
+
+static char visible_length_key[] = "n_sequence_fields";
+static char real_length_key[] = "n_fields";
+static char unnamed_fields_key[] = "n_unnamed_fields";
+
+/* Fields with this name have only a field index, not a field name.
+   They are only allowed for indices < n_visible_fields. */
+char *PyStructSequence_UnnamedField = "unnamed field";
+
+#define VISIBLE_SIZE(op) Py_SIZE(op)
+#define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
+                      PyDict_GetItemString((tp)->tp_dict, visible_length_key))
+
+#define REAL_SIZE_TP(tp) PyInt_AsLong( \
+                      PyDict_GetItemString((tp)->tp_dict, real_length_key))
+#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
+
+#define UNNAMED_FIELDS_TP(tp) PyInt_AsLong( \
+                      PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
+#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
+
+
+PyObject *
+PyStructSequence_New(PyTypeObject *type)
+{
+    PyStructSequence *obj;
+
+    obj = PyObject_New(PyStructSequence, type);
+    if (obj == NULL)
+        return NULL;
+    Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
+
+    return (PyObject*) obj;
+}
+
+static void
+structseq_dealloc(PyStructSequence *obj)
+{
+    Py_ssize_t i, size;
+
+    size = REAL_SIZE(obj);
+    for (i = 0; i < size; ++i) {
+        Py_XDECREF(obj->ob_item[i]);
+    }
+    PyObject_Del(obj);
+}
+
+static Py_ssize_t
+structseq_length(PyStructSequence *obj)
+{
+    return VISIBLE_SIZE(obj);
+}
+
+static PyObject*
+structseq_item(PyStructSequence *obj, Py_ssize_t i)
+{
+    if (i < 0 || i >= VISIBLE_SIZE(obj)) {
+        PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+        return NULL;
+    }
+    Py_INCREF(obj->ob_item[i]);
+    return obj->ob_item[i];
+}
+
+static PyObject*
+structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
+{
+    PyTupleObject *np;
+    Py_ssize_t i;
+
+    if (low < 0)
+        low = 0;
+    if (high > VISIBLE_SIZE(obj))
+        high = VISIBLE_SIZE(obj);
+    if (high < low)
+        high = low;
+    np = (PyTupleObject *)PyTuple_New(high-low);
+    if (np == NULL)
+        return NULL;
+    for(i = low; i < high; ++i) {
+        PyObject *v = obj->ob_item[i];
+        Py_INCREF(v);
+        PyTuple_SET_ITEM(np, i-low, v);
+    }
+    return (PyObject *) np;
+}
+
+static PyObject *
+structseq_subscript(PyStructSequence *self, PyObject *item)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+
+        if (i < 0)
+            i += VISIBLE_SIZE(self);
+
+        if (i < 0 || i >= VISIBLE_SIZE(self)) {
+            PyErr_SetString(PyExc_IndexError,
+                "tuple index out of range");
+            return NULL;
+        }
+        Py_INCREF(self->ob_item[i]);
+        return self->ob_item[i];
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelen, cur, i;
+        PyObject *result;
+
+        if (PySlice_GetIndicesEx((PySliceObject *)item,
+                                 VISIBLE_SIZE(self), &start, &stop,
+                                 &step, &slicelen) < 0) {
+            return NULL;
+        }
+        if (slicelen <= 0)
+            return PyTuple_New(0);
+        result = PyTuple_New(slicelen);
+        if (result == NULL)
+            return NULL;
+        for (cur = start, i = 0; i < slicelen;
+             cur += step, i++) {
+            PyObject *v = self->ob_item[cur];
+            Py_INCREF(v);
+            PyTuple_SET_ITEM(result, i, v);
+        }
+        return result;
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "structseq index must be integer");
+        return NULL;
+    }
+}
+
+static PyObject *
+structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *arg = NULL;
+    PyObject *dict = NULL;
+    PyObject *ob;
+    PyStructSequence *res = NULL;
+    Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
+    static char *kwlist[] = {"sequence", "dict", 0};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
+                                     kwlist, &arg, &dict))
+        return NULL;
+
+    arg = PySequence_Fast(arg, "constructor requires a sequence");
+
+    if (!arg) {
+        return NULL;
+    }
+
+    if (dict && !PyDict_Check(dict)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%.500s() takes a dict as second arg, if any",
+                     type->tp_name);
+        Py_DECREF(arg);
+        return NULL;
+    }
+
+    len = PySequence_Fast_GET_SIZE(arg);
+    min_len = VISIBLE_SIZE_TP(type);
+    max_len = REAL_SIZE_TP(type);
+    n_unnamed_fields = UNNAMED_FIELDS_TP(type);
+
+    if (min_len != max_len) {
+        if (len < min_len) {
+            PyErr_Format(PyExc_TypeError,
+                "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
+                type->tp_name, min_len, len);
+            Py_DECREF(arg);
+            return NULL;
+        }
+
+        if (len > max_len) {
+            PyErr_Format(PyExc_TypeError,
+                         "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
+                         type->tp_name, max_len, len);
+            Py_DECREF(arg);
+            return NULL;
+        }
+    }
+    else {
+        if (len != min_len) {
+            PyErr_Format(PyExc_TypeError,
+                         "%.500s() takes a %zd-sequence (%zd-sequence given)",
+                         type->tp_name, min_len, len);
+            Py_DECREF(arg);
+            return NULL;
+        }
+    }
+
+    res = (PyStructSequence*) PyStructSequence_New(type);
+    if (res == NULL) {
+        Py_DECREF(arg);
+        return NULL;
+    }
+    for (i = 0; i < len; ++i) {
+        PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
+        Py_INCREF(v);
+        res->ob_item[i] = v;
+    }
+    for (; i < max_len; ++i) {
+        if (dict && (ob = PyDict_GetItemString(
+            dict, type->tp_members[i-n_unnamed_fields].name))) {
+        }
+        else {
+            ob = Py_None;
+        }
+        Py_INCREF(ob);
+        res->ob_item[i] = ob;
+    }
+
+    Py_DECREF(arg);
+    return (PyObject*) res;
+}
+
+static PyObject *
+make_tuple(PyStructSequence *obj)
+{
+    return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
+}
+
+static PyObject *
+structseq_repr(PyStructSequence *obj)
+{
+    /* buffer and type size were chosen well considered. */
+#define REPR_BUFFER_SIZE 512
+#define TYPE_MAXSIZE 100
+
+    PyObject *tup;
+    PyTypeObject *typ = Py_TYPE(obj);
+    int i, removelast = 0;
+    Py_ssize_t len;
+    char buf[REPR_BUFFER_SIZE];
+    char *endofbuf, *pbuf = buf;
+
+    /* pointer to end of writeable buffer; safes space for "...)\0" */
+    endofbuf= &buf[REPR_BUFFER_SIZE-5];
+
+    if ((tup = make_tuple(obj)) == NULL) {
+        return NULL;
+    }
+
+    /* "typename(", limited to  TYPE_MAXSIZE */
+    len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
+                            strlen(typ->tp_name);
+    strncpy(pbuf, typ->tp_name, len);
+    pbuf += len;
+    *pbuf++ = '(';
+
+    for (i=0; i < VISIBLE_SIZE(obj); i++) {
+        PyObject *val, *repr;
+        char *cname, *crepr;
+
+        cname = typ->tp_members[i].name;
+
+        val = PyTuple_GetItem(tup, i);
+        if (cname == NULL || val == NULL) {
+            return NULL;
+        }
+        repr = PyObject_Repr(val);
+        if (repr == NULL) {
+            Py_DECREF(tup);
+            return NULL;
+        }
+        crepr = PyString_AsString(repr);
+        if (crepr == NULL) {
+            Py_DECREF(tup);
+            Py_DECREF(repr);
+            return NULL;
+        }
+
+        /* + 3: keep space for "=" and ", " */
+        len = strlen(cname) + strlen(crepr) + 3;
+        if ((pbuf+len) <= endofbuf) {
+            strcpy(pbuf, cname);
+            pbuf += strlen(cname);
+            *pbuf++ = '=';
+            strcpy(pbuf, crepr);
+            pbuf += strlen(crepr);
+            *pbuf++ = ',';
+            *pbuf++ = ' ';
+            removelast = 1;
+            Py_DECREF(repr);
+        }
+        else {
+            strcpy(pbuf, "...");
+            pbuf += 3;
+            removelast = 0;
+            Py_DECREF(repr);
+            break;
+        }
+    }
+    Py_DECREF(tup);
+    if (removelast) {
+        /* overwrite last ", " */
+        pbuf-=2;
+    }
+    *pbuf++ = ')';
+    *pbuf = '\0';
+
+    return PyString_FromString(buf);
+}
+
+static PyObject *
+structseq_concat(PyStructSequence *obj, PyObject *b)
+{
+    PyObject *tup, *result;
+    tup = make_tuple(obj);
+    result = PySequence_Concat(tup, b);
+    Py_DECREF(tup);
+    return result;
+}
+
+static PyObject *
+structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
+{
+    PyObject *tup, *result;
+    tup = make_tuple(obj);
+    result = PySequence_Repeat(tup, n);
+    Py_DECREF(tup);
+    return result;
+}
+
+static int
+structseq_contains(PyStructSequence *obj, PyObject *o)
+{
+    PyObject *tup;
+    int result;
+    tup = make_tuple(obj);
+    if (!tup)
+        return -1;
+    result = PySequence_Contains(tup, o);
+    Py_DECREF(tup);
+    return result;
+}
+
+static long
+structseq_hash(PyObject *obj)
+{
+    PyObject *tup;
+    long result;
+    tup = make_tuple((PyStructSequence*) obj);
+    if (!tup)
+        return -1;
+    result = PyObject_Hash(tup);
+    Py_DECREF(tup);
+    return result;
+}
+
+static PyObject *
+structseq_richcompare(PyObject *obj, PyObject *o2, int op)
+{
+    PyObject *tup, *result;
+    tup = make_tuple((PyStructSequence*) obj);
+    result = PyObject_RichCompare(tup, o2, op);
+    Py_DECREF(tup);
+    return result;
+}
+
+static PyObject *
+structseq_reduce(PyStructSequence* self)
+{
+    PyObject* tup;
+    PyObject* dict;
+    PyObject* result;
+    Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
+    int i;
+
+    n_fields = REAL_SIZE(self);
+    n_visible_fields = VISIBLE_SIZE(self);
+    n_unnamed_fields = UNNAMED_FIELDS(self);
+    tup = PyTuple_New(n_visible_fields);
+    if (!tup) {
+        return NULL;
+    }
+
+    dict = PyDict_New();
+    if (!dict) {
+        Py_DECREF(tup);
+        return NULL;
+    }
+
+    for (i = 0; i < n_visible_fields; i++) {
+        Py_INCREF(self->ob_item[i]);
+        PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
+    }
+
+    for (; i < n_fields; i++) {
+        char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
+        PyDict_SetItemString(dict, n,
+                             self->ob_item[i]);
+    }
+
+    result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
+
+    Py_DECREF(tup);
+    Py_DECREF(dict);
+
+    return result;
+}
+
+static PySequenceMethods structseq_as_sequence = {
+    (lenfunc)structseq_length,
+    (binaryfunc)structseq_concat,           /* sq_concat */
+    (ssizeargfunc)structseq_repeat,         /* sq_repeat */
+    (ssizeargfunc)structseq_item,               /* sq_item */
+    (ssizessizeargfunc)structseq_slice,         /* sq_slice */
+    0,                                          /* sq_ass_item */
+    0,                                          /* sq_ass_slice */
+    (objobjproc)structseq_contains,             /* sq_contains */
+};
+
+static PyMappingMethods structseq_as_mapping = {
+    (lenfunc)structseq_length,
+    (binaryfunc)structseq_subscript,
+};
+
+static PyMethodDef structseq_methods[] = {
+    {"__reduce__", (PyCFunction)structseq_reduce,
+     METH_NOARGS, NULL},
+    {NULL, NULL}
+};
+
+static PyTypeObject _struct_sequence_template = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    NULL,                                       /* tp_name */
+    0,                                          /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    (destructor)structseq_dealloc,              /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)structseq_repr,                   /* tp_repr */
+    0,                                          /* tp_as_number */
+    &structseq_as_sequence,                     /* tp_as_sequence */
+    &structseq_as_mapping,                      /* tp_as_mapping */
+    structseq_hash,                             /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    0,                                          /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+    NULL,                                       /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    structseq_richcompare,                      /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    structseq_methods,                          /* tp_methods */
+    NULL,                                       /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    structseq_new,                              /* tp_new */
+};
+
+void
+PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
+{
+    PyObject *dict;
+    PyMemberDef* members;
+    int n_members, n_unnamed_members, i, k;
+
+#ifdef Py_TRACE_REFS
+    /* if the type object was chained, unchain it first
+       before overwriting its storage */
+    if (type->_ob_next) {
+        _Py_ForgetReference((PyObject*)type);
+    }
+#endif
+
+    n_unnamed_members = 0;
+    for (i = 0; desc->fields[i].name != NULL; ++i)
+        if (desc->fields[i].name == PyStructSequence_UnnamedField)
+            n_unnamed_members++;
+    n_members = i;
+
+    memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
+    type->tp_name = desc->name;
+    type->tp_doc = desc->doc;
+    type->tp_basicsize = sizeof(PyStructSequence)+
+        sizeof(PyObject*)*(n_members-1);
+    type->tp_itemsize = 0;
+
+    members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
+    if (members == NULL)
+        return;
+
+    for (i = k = 0; i < n_members; ++i) {
+        if (desc->fields[i].name == PyStructSequence_UnnamedField)
+            continue;
+        members[k].name = desc->fields[i].name;
+        members[k].type = T_OBJECT;
+        members[k].offset = offsetof(PyStructSequence, ob_item)
+          + i * sizeof(PyObject*);
+        members[k].flags = READONLY;
+        members[k].doc = desc->fields[i].doc;
+        k++;
+    }
+    members[k].name = NULL;
+
+    type->tp_members = members;
+
+    if (PyType_Ready(type) < 0)
+        return;
+    Py_INCREF(type);
+
+    dict = type->tp_dict;
+#define SET_DICT_FROM_INT(key, value)                           \
+    do {                                                        \
+        PyObject *v = PyInt_FromLong((long) value);             \
+        if (v != NULL) {                                        \
+            PyDict_SetItemString(dict, key, v);                 \
+            Py_DECREF(v);                                       \
+        }                                                       \
+    } while (0)
+
+    SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
+    SET_DICT_FROM_INT(real_length_key, n_members);
+    SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
+}
diff --git a/Python-2.7.5/Objects/tupleobject.c b/Python-2.7.5/Objects/tupleobject.c
new file mode 100644
index 0000000..00f2e47
--- /dev/null
+++ b/Python-2.7.5/Objects/tupleobject.c
@@ -0,0 +1,1054 @@
+
+/* Tuple object implementation */
+
+#include "Python.h"
+
+/* Speed optimization to avoid frequent malloc/free of small tuples */
+#ifndef PyTuple_MAXSAVESIZE
+#define PyTuple_MAXSAVESIZE     20  /* Largest tuple to save on free list */
+#endif
+#ifndef PyTuple_MAXFREELIST
+#define PyTuple_MAXFREELIST  2000  /* Maximum number of tuples of each size to save */
+#endif
+
+#if PyTuple_MAXSAVESIZE > 0
+/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
+   tuple () of which at most one instance will be allocated.
+*/
+static PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
+static int numfree[PyTuple_MAXSAVESIZE];
+#endif
+#ifdef COUNT_ALLOCS
+Py_ssize_t fast_tuple_allocs;
+Py_ssize_t tuple_zero_allocs;
+#endif
+
+/* Debug statistic to count GC tracking of tuples.
+   Please note that tuples are only untracked when considered by the GC, and
+   many of them will be dead before. Therefore, a tracking rate close to 100%
+   does not necessarily prove that the heuristic is inefficient.
+*/
+#ifdef SHOW_TRACK_COUNT
+static Py_ssize_t count_untracked = 0;
+static Py_ssize_t count_tracked = 0;
+
+static void
+show_track(void)
+{
+    fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n",
+        count_tracked + count_untracked);
+    fprintf(stderr, "Tuples tracked by the GC: %" PY_FORMAT_SIZE_T
+        "d\n", count_tracked);
+    fprintf(stderr, "%.2f%% tuple tracking rate\n\n",
+        (100.0*count_tracked/(count_untracked+count_tracked)));
+}
+#endif
+
+
+PyObject *
+PyTuple_New(register Py_ssize_t size)
+{
+    register PyTupleObject *op;
+    Py_ssize_t i;
+    if (size < 0) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+#if PyTuple_MAXSAVESIZE > 0
+    if (size == 0 && free_list[0]) {
+        op = free_list[0];
+        Py_INCREF(op);
+#ifdef COUNT_ALLOCS
+        tuple_zero_allocs++;
+#endif
+        return (PyObject *) op;
+    }
+    if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) {
+        free_list[size] = (PyTupleObject *) op->ob_item[0];
+        numfree[size]--;
+#ifdef COUNT_ALLOCS
+        fast_tuple_allocs++;
+#endif
+        /* Inline PyObject_InitVar */
+#ifdef Py_TRACE_REFS
+        Py_SIZE(op) = size;
+        Py_TYPE(op) = &PyTuple_Type;
+#endif
+        _Py_NewReference((PyObject *)op);
+    }
+    else
+#endif
+    {
+        Py_ssize_t nbytes = size * sizeof(PyObject *);
+        /* Check for overflow */
+        if (nbytes / sizeof(PyObject *) != (size_t)size ||
+            (nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)))
+        {
+            return PyErr_NoMemory();
+        }
+
+        op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
+        if (op == NULL)
+            return NULL;
+    }
+    for (i=0; i < size; i++)
+        op->ob_item[i] = NULL;
+#if PyTuple_MAXSAVESIZE > 0
+    if (size == 0) {
+        free_list[0] = op;
+        ++numfree[0];
+        Py_INCREF(op);          /* extra INCREF so that this is never freed */
+    }
+#endif
+#ifdef SHOW_TRACK_COUNT
+    count_tracked++;
+#endif
+    _PyObject_GC_TRACK(op);
+    return (PyObject *) op;
+}
+
+Py_ssize_t
+PyTuple_Size(register PyObject *op)
+{
+    if (!PyTuple_Check(op)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    else
+        return Py_SIZE(op);
+}
+
+PyObject *
+PyTuple_GetItem(register PyObject *op, register Py_ssize_t i)
+{
+    if (!PyTuple_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    if (i < 0 || i >= Py_SIZE(op)) {
+        PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+        return NULL;
+    }
+    return ((PyTupleObject *)op) -> ob_item[i];
+}
+
+int
+PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
+{
+    register PyObject *olditem;
+    register PyObject **p;
+    if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
+        Py_XDECREF(newitem);
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (i < 0 || i >= Py_SIZE(op)) {
+        Py_XDECREF(newitem);
+        PyErr_SetString(PyExc_IndexError,
+                        "tuple assignment index out of range");
+        return -1;
+    }
+    p = ((PyTupleObject *)op) -> ob_item + i;
+    olditem = *p;
+    *p = newitem;
+    Py_XDECREF(olditem);
+    return 0;
+}
+
+void
+_PyTuple_MaybeUntrack(PyObject *op)
+{
+    PyTupleObject *t;
+    Py_ssize_t i, n;
+
+    if (!PyTuple_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
+        return;
+    t = (PyTupleObject *) op;
+    n = Py_SIZE(t);
+    for (i = 0; i < n; i++) {
+        PyObject *elt = PyTuple_GET_ITEM(t, i);
+        /* Tuple with NULL elements aren't
+           fully constructed, don't untrack
+           them yet. */
+        if (!elt ||
+            _PyObject_GC_MAY_BE_TRACKED(elt))
+            return;
+    }
+#ifdef SHOW_TRACK_COUNT
+    count_tracked--;
+    count_untracked++;
+#endif
+    _PyObject_GC_UNTRACK(op);
+}
+
+PyObject *
+PyTuple_Pack(Py_ssize_t n, ...)
+{
+    Py_ssize_t i;
+    PyObject *o;
+    PyObject *result;
+    PyObject **items;
+    va_list vargs;
+
+    va_start(vargs, n);
+    result = PyTuple_New(n);
+    if (result == NULL) {
+        va_end(vargs);
+        return NULL;
+    }
+    items = ((PyTupleObject *)result)->ob_item;
+    for (i = 0; i < n; i++) {
+        o = va_arg(vargs, PyObject *);
+        Py_INCREF(o);
+        items[i] = o;
+    }
+    va_end(vargs);
+    return result;
+}
+
+
+/* Methods */
+
+static void
+tupledealloc(register PyTupleObject *op)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t len =  Py_SIZE(op);
+    PyObject_GC_UnTrack(op);
+    Py_TRASHCAN_SAFE_BEGIN(op)
+    if (len > 0) {
+        i = len;
+        while (--i >= 0)
+            Py_XDECREF(op->ob_item[i]);
+#if PyTuple_MAXSAVESIZE > 0
+        if (len < PyTuple_MAXSAVESIZE &&
+            numfree[len] < PyTuple_MAXFREELIST &&
+            Py_TYPE(op) == &PyTuple_Type)
+        {
+            op->ob_item[0] = (PyObject *) free_list[len];
+            numfree[len]++;
+            free_list[len] = op;
+            goto done; /* return */
+        }
+#endif
+    }
+    Py_TYPE(op)->tp_free((PyObject *)op);
+done:
+    Py_TRASHCAN_SAFE_END(op)
+}
+
+static int
+tupleprint(PyTupleObject *op, FILE *fp, int flags)
+{
+    Py_ssize_t i;
+    Py_BEGIN_ALLOW_THREADS
+    fprintf(fp, "(");
+    Py_END_ALLOW_THREADS
+    for (i = 0; i < Py_SIZE(op); i++) {
+        if (i > 0) {
+            Py_BEGIN_ALLOW_THREADS
+            fprintf(fp, ", ");
+            Py_END_ALLOW_THREADS
+        }
+        if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
+            return -1;
+    }
+    i = Py_SIZE(op);
+    Py_BEGIN_ALLOW_THREADS
+    if (i == 1)
+        fprintf(fp, ",");
+    fprintf(fp, ")");
+    Py_END_ALLOW_THREADS
+    return 0;
+}
+
+static PyObject *
+tuplerepr(PyTupleObject *v)
+{
+    Py_ssize_t i, n;
+    PyObject *s, *temp;
+    PyObject *pieces, *result = NULL;
+
+    n = Py_SIZE(v);
+    if (n == 0)
+        return PyString_FromString("()");
+
+    /* While not mutable, it is still possible to end up with a cycle in a
+       tuple through an object that stores itself within a tuple (and thus
+       infinitely asks for the repr of itself). This should only be
+       possible within a type. */
+    i = Py_ReprEnter((PyObject *)v);
+    if (i != 0) {
+        return i > 0 ? PyString_FromString("(...)") : NULL;
+    }
+
+    pieces = PyTuple_New(n);
+    if (pieces == NULL)
+        return NULL;
+
+    /* Do repr() on each element. */
+    for (i = 0; i < n; ++i) {
+        if (Py_EnterRecursiveCall(" while getting the repr of a tuple"))
+            goto Done;
+        s = PyObject_Repr(v->ob_item[i]);
+        Py_LeaveRecursiveCall();
+        if (s == NULL)
+            goto Done;
+        PyTuple_SET_ITEM(pieces, i, s);
+    }
+
+    /* Add "()" decorations to the first and last items. */
+    assert(n > 0);
+    s = PyString_FromString("(");
+    if (s == NULL)
+        goto Done;
+    temp = PyTuple_GET_ITEM(pieces, 0);
+    PyString_ConcatAndDel(&s, temp);
+    PyTuple_SET_ITEM(pieces, 0, s);
+    if (s == NULL)
+        goto Done;
+
+    s = PyString_FromString(n == 1 ? ",)" : ")");
+    if (s == NULL)
+        goto Done;
+    temp = PyTuple_GET_ITEM(pieces, n-1);
+    PyString_ConcatAndDel(&temp, s);
+    PyTuple_SET_ITEM(pieces, n-1, temp);
+    if (temp == NULL)
+        goto Done;
+
+    /* Paste them all together with ", " between. */
+    s = PyString_FromString(", ");
+    if (s == NULL)
+        goto Done;
+    result = _PyString_Join(s, pieces);
+    Py_DECREF(s);
+
+Done:
+    Py_DECREF(pieces);
+    Py_ReprLeave((PyObject *)v);
+    return result;
+}
+
+/* The addend 82520, was selected from the range(0, 1000000) for
+   generating the greatest number of prime multipliers for tuples
+   upto length eight:
+
+     1082527, 1165049, 1082531, 1165057, 1247581, 1330103, 1082533,
+     1330111, 1412633, 1165069, 1247599, 1495177, 1577699
+*/
+
+static long
+tuplehash(PyTupleObject *v)
+{
+    register long x, y;
+    register Py_ssize_t len = Py_SIZE(v);
+    register PyObject **p;
+    long mult = 1000003L;
+    x = 0x345678L;
+    p = v->ob_item;
+    while (--len >= 0) {
+        y = PyObject_Hash(*p++);
+        if (y == -1)
+            return -1;
+        x = (x ^ y) * mult;
+        /* the cast might truncate len; that doesn't change hash stability */
+        mult += (long)(82520L + len + len);
+    }
+    x += 97531L;
+    if (x == -1)
+        x = -2;
+    return x;
+}
+
+static Py_ssize_t
+tuplelength(PyTupleObject *a)
+{
+    return Py_SIZE(a);
+}
+
+static int
+tuplecontains(PyTupleObject *a, PyObject *el)
+{
+    Py_ssize_t i;
+    int cmp;
+
+    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
+        cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
+                                           Py_EQ);
+    return cmp;
+}
+
+static PyObject *
+tupleitem(register PyTupleObject *a, register Py_ssize_t i)
+{
+    if (i < 0 || i >= Py_SIZE(a)) {
+        PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+        return NULL;
+    }
+    Py_INCREF(a->ob_item[i]);
+    return a->ob_item[i];
+}
+
+static PyObject *
+tupleslice(register PyTupleObject *a, register Py_ssize_t ilow,
+           register Py_ssize_t ihigh)
+{
+    register PyTupleObject *np;
+    PyObject **src, **dest;
+    register Py_ssize_t i;
+    Py_ssize_t len;
+    if (ilow < 0)
+        ilow = 0;
+    if (ihigh > Py_SIZE(a))
+        ihigh = Py_SIZE(a);
+    if (ihigh < ilow)
+        ihigh = ilow;
+    if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) {
+        Py_INCREF(a);
+        return (PyObject *)a;
+    }
+    len = ihigh - ilow;
+    np = (PyTupleObject *)PyTuple_New(len);
+    if (np == NULL)
+        return NULL;
+    src = a->ob_item + ilow;
+    dest = np->ob_item;
+    for (i = 0; i < len; i++) {
+        PyObject *v = src[i];
+        Py_INCREF(v);
+        dest[i] = v;
+    }
+    return (PyObject *)np;
+}
+
+PyObject *
+PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
+{
+    if (op == NULL || !PyTuple_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return tupleslice((PyTupleObject *)op, i, j);
+}
+
+static PyObject *
+tupleconcat(register PyTupleObject *a, register PyObject *bb)
+{
+    register Py_ssize_t size;
+    register Py_ssize_t i;
+    PyObject **src, **dest;
+    PyTupleObject *np;
+    if (!PyTuple_Check(bb)) {
+        PyErr_Format(PyExc_TypeError,
+             "can only concatenate tuple (not \"%.200s\") to tuple",
+                 Py_TYPE(bb)->tp_name);
+        return NULL;
+    }
+#define b ((PyTupleObject *)bb)
+    size = Py_SIZE(a) + Py_SIZE(b);
+    if (size < 0)
+        return PyErr_NoMemory();
+    np = (PyTupleObject *) PyTuple_New(size);
+    if (np == NULL) {
+        return NULL;
+    }
+    src = a->ob_item;
+    dest = np->ob_item;
+    for (i = 0; i < Py_SIZE(a); i++) {
+        PyObject *v = src[i];
+        Py_INCREF(v);
+        dest[i] = v;
+    }
+    src = b->ob_item;
+    dest = np->ob_item + Py_SIZE(a);
+    for (i = 0; i < Py_SIZE(b); i++) {
+        PyObject *v = src[i];
+        Py_INCREF(v);
+        dest[i] = v;
+    }
+    return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+tuplerepeat(PyTupleObject *a, Py_ssize_t n)
+{
+    Py_ssize_t i, j;
+    Py_ssize_t size;
+    PyTupleObject *np;
+    PyObject **p, **items;
+    if (n < 0)
+        n = 0;
+    if (Py_SIZE(a) == 0 || n == 1) {
+        if (PyTuple_CheckExact(a)) {
+            /* Since tuples are immutable, we can return a shared
+               copy in this case */
+            Py_INCREF(a);
+            return (PyObject *)a;
+        }
+        if (Py_SIZE(a) == 0)
+            return PyTuple_New(0);
+    }
+    size = Py_SIZE(a) * n;
+    if (size/Py_SIZE(a) != n)
+        return PyErr_NoMemory();
+    np = (PyTupleObject *) PyTuple_New(size);
+    if (np == NULL)
+        return NULL;
+    p = np->ob_item;
+    items = a->ob_item;
+    for (i = 0; i < n; i++) {
+        for (j = 0; j < Py_SIZE(a); j++) {
+            *p = items[j];
+            Py_INCREF(*p);
+            p++;
+        }
+    }
+    return (PyObject *) np;
+}
+
+static PyObject *
+tupleindex(PyTupleObject *self, PyObject *args)
+{
+    Py_ssize_t i, start=0, stop=Py_SIZE(self);
+    PyObject *v;
+
+    if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
+                                _PyEval_SliceIndex, &start,
+                                _PyEval_SliceIndex, &stop))
+        return NULL;
+    if (start < 0) {
+        start += Py_SIZE(self);
+        if (start < 0)
+            start = 0;
+    }
+    if (stop < 0) {
+        stop += Py_SIZE(self);
+        if (stop < 0)
+            stop = 0;
+    }
+    for (i = start; i < stop && i < Py_SIZE(self); i++) {
+        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+        if (cmp > 0)
+            return PyInt_FromSsize_t(i);
+        else if (cmp < 0)
+            return NULL;
+    }
+    PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in tuple");
+    return NULL;
+}
+
+static PyObject *
+tuplecount(PyTupleObject *self, PyObject *v)
+{
+    Py_ssize_t count = 0;
+    Py_ssize_t i;
+
+    for (i = 0; i < Py_SIZE(self); i++) {
+        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+        if (cmp > 0)
+            count++;
+        else if (cmp < 0)
+            return NULL;
+    }
+    return PyInt_FromSsize_t(count);
+}
+
+static int
+tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
+{
+    Py_ssize_t i;
+
+    for (i = Py_SIZE(o); --i >= 0; )
+        Py_VISIT(o->ob_item[i]);
+    return 0;
+}
+
+static PyObject *
+tuplerichcompare(PyObject *v, PyObject *w, int op)
+{
+    PyTupleObject *vt, *wt;
+    Py_ssize_t i;
+    Py_ssize_t vlen, wlen;
+
+    if (!PyTuple_Check(v) || !PyTuple_Check(w)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+
+    vt = (PyTupleObject *)v;
+    wt = (PyTupleObject *)w;
+
+    vlen = Py_SIZE(vt);
+    wlen = Py_SIZE(wt);
+
+    /* Note:  the corresponding code for lists has an "early out" test
+     * here when op is EQ or NE and the lengths differ.  That pays there,
+     * but Tim was unable to find any real code where EQ/NE tuple
+     * compares don't have the same length, so testing for it here would
+     * have cost without benefit.
+     */
+
+    /* Search for the first index where items are different.
+     * Note that because tuples are immutable, it's safe to reuse
+     * vlen and wlen across the comparison calls.
+     */
+    for (i = 0; i < vlen && i < wlen; i++) {
+        int k = PyObject_RichCompareBool(vt->ob_item[i],
+                                         wt->ob_item[i], Py_EQ);
+        if (k < 0)
+            return NULL;
+        if (!k)
+            break;
+    }
+
+    if (i >= vlen || i >= wlen) {
+        /* No more items to compare -- compare sizes */
+        int cmp;
+        PyObject *res;
+        switch (op) {
+        case Py_LT: cmp = vlen <  wlen; break;
+        case Py_LE: cmp = vlen <= wlen; break;
+        case Py_EQ: cmp = vlen == wlen; break;
+        case Py_NE: cmp = vlen != wlen; break;
+        case Py_GT: cmp = vlen >  wlen; break;
+        case Py_GE: cmp = vlen >= wlen; break;
+        default: return NULL; /* cannot happen */
+        }
+        if (cmp)
+            res = Py_True;
+        else
+            res = Py_False;
+        Py_INCREF(res);
+        return res;
+    }
+
+    /* We have an item that differs -- shortcuts for EQ/NE */
+    if (op == Py_EQ) {
+        Py_INCREF(Py_False);
+        return Py_False;
+    }
+    if (op == Py_NE) {
+        Py_INCREF(Py_True);
+        return Py_True;
+    }
+
+    /* Compare the final item again using the proper operator */
+    return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
+}
+
+static PyObject *
+tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *arg = NULL;
+    static char *kwlist[] = {"sequence", 0};
+
+    if (type != &PyTuple_Type)
+        return tuple_subtype_new(type, args, kwds);
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
+        return NULL;
+
+    if (arg == NULL)
+        return PyTuple_New(0);
+    else
+        return PySequence_Tuple(arg);
+}
+
+static PyObject *
+tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *tmp, *newobj, *item;
+    Py_ssize_t i, n;
+
+    assert(PyType_IsSubtype(type, &PyTuple_Type));
+    tmp = tuple_new(&PyTuple_Type, args, kwds);
+    if (tmp == NULL)
+        return NULL;
+    assert(PyTuple_Check(tmp));
+    newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp));
+    if (newobj == NULL)
+        return NULL;
+    for (i = 0; i < n; i++) {
+        item = PyTuple_GET_ITEM(tmp, i);
+        Py_INCREF(item);
+        PyTuple_SET_ITEM(newobj, i, item);
+    }
+    Py_DECREF(tmp);
+    return newobj;
+}
+
+PyDoc_STRVAR(tuple_doc,
+"tuple() -> empty tuple\n\
+tuple(iterable) -> tuple initialized from iterable's items\n\
+\n\
+If the argument is a tuple, the return value is the same object.");
+
+static PySequenceMethods tuple_as_sequence = {
+    (lenfunc)tuplelength,                       /* sq_length */
+    (binaryfunc)tupleconcat,                    /* sq_concat */
+    (ssizeargfunc)tuplerepeat,                  /* sq_repeat */
+    (ssizeargfunc)tupleitem,                    /* sq_item */
+    (ssizessizeargfunc)tupleslice,              /* sq_slice */
+    0,                                          /* sq_ass_item */
+    0,                                          /* sq_ass_slice */
+    (objobjproc)tuplecontains,                  /* sq_contains */
+};
+
+static PyObject*
+tuplesubscript(PyTupleObject* self, PyObject* item)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += PyTuple_GET_SIZE(self);
+        return tupleitem(self, i);
+    }
+    else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+        PyObject* result;
+        PyObject* it;
+        PyObject **src, **dest;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item,
+                         PyTuple_GET_SIZE(self),
+                         &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0) {
+            return PyTuple_New(0);
+        }
+        else if (start == 0 && step == 1 &&
+                 slicelength == PyTuple_GET_SIZE(self) &&
+                 PyTuple_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject *)self;
+        }
+        else {
+            result = PyTuple_New(slicelength);
+            if (!result) return NULL;
+
+            src = self->ob_item;
+            dest = ((PyTupleObject *)result)->ob_item;
+            for (cur = start, i = 0; i < slicelength;
+                 cur += step, i++) {
+                it = src[cur];
+                Py_INCREF(it);
+                dest[i] = it;
+            }
+
+            return result;
+        }
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "tuple indices must be integers, not %.200s",
+                     Py_TYPE(item)->tp_name);
+        return NULL;
+    }
+}
+
+static PyObject *
+tuple_getnewargs(PyTupleObject *v)
+{
+    return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
+
+}
+
+static PyObject *
+tuple_sizeof(PyTupleObject *self)
+{
+    Py_ssize_t res;
+
+    res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *);
+    return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(index_doc,
+"T.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
+"Raises ValueError if the value is not present."
+);
+PyDoc_STRVAR(count_doc,
+"T.count(value) -> integer -- return number of occurrences of value");
+PyDoc_STRVAR(sizeof_doc,
+"T.__sizeof__() -- size of T in memory, in bytes");
+
+static PyMethodDef tuple_methods[] = {
+    {"__getnewargs__",          (PyCFunction)tuple_getnewargs,  METH_NOARGS},
+    {"__sizeof__",      (PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc},
+    {"index",           (PyCFunction)tupleindex,  METH_VARARGS, index_doc},
+    {"count",           (PyCFunction)tuplecount,  METH_O, count_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static PyMappingMethods tuple_as_mapping = {
+    (lenfunc)tuplelength,
+    (binaryfunc)tuplesubscript,
+    0
+};
+
+static PyObject *tuple_iter(PyObject *seq);
+
+PyTypeObject PyTuple_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "tuple",
+    sizeof(PyTupleObject) - sizeof(PyObject *),
+    sizeof(PyObject *),
+    (destructor)tupledealloc,                   /* tp_dealloc */
+    (printfunc)tupleprint,                      /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    (reprfunc)tuplerepr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    &tuple_as_sequence,                         /* tp_as_sequence */
+    &tuple_as_mapping,                          /* tp_as_mapping */
+    (hashfunc)tuplehash,                        /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
+    tuple_doc,                                  /* tp_doc */
+    (traverseproc)tupletraverse,                /* tp_traverse */
+    0,                                          /* tp_clear */
+    tuplerichcompare,                           /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    tuple_iter,                                 /* tp_iter */
+    0,                                          /* tp_iternext */
+    tuple_methods,                              /* tp_methods */
+    0,                                          /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    tuple_new,                                  /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
+
+/* The following function breaks the notion that tuples are immutable:
+   it changes the size of a tuple.  We get away with this only if there
+   is only one module referencing the object.  You can also think of it
+   as creating a new tuple object and destroying the old one, only more
+   efficiently.  In any case, don't use this if the tuple may already be
+   known to some other part of the code. */
+
+int
+_PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+    register PyTupleObject *v;
+    register PyTupleObject *sv;
+    Py_ssize_t i;
+    Py_ssize_t oldsize;
+
+    v = (PyTupleObject *) *pv;
+    if (v == NULL || Py_TYPE(v) != &PyTuple_Type ||
+        (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) {
+        *pv = 0;
+        Py_XDECREF(v);
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    oldsize = Py_SIZE(v);
+    if (oldsize == newsize)
+        return 0;
+
+    if (oldsize == 0) {
+        /* Empty tuples are often shared, so we should never
+           resize them in-place even if we do own the only
+           (current) reference */
+        Py_DECREF(v);
+        *pv = PyTuple_New(newsize);
+        return *pv == NULL ? -1 : 0;
+    }
+
+    /* XXX UNREF/NEWREF interface should be more symmetrical */
+    _Py_DEC_REFTOTAL;
+    if (_PyObject_GC_IS_TRACKED(v))
+        _PyObject_GC_UNTRACK(v);
+    _Py_ForgetReference((PyObject *) v);
+    /* DECREF items deleted by shrinkage */
+    for (i = newsize; i < oldsize; i++) {
+        Py_XDECREF(v->ob_item[i]);
+        v->ob_item[i] = NULL;
+    }
+    sv = PyObject_GC_Resize(PyTupleObject, v, newsize);
+    if (sv == NULL) {
+        *pv = NULL;
+        PyObject_GC_Del(v);
+        return -1;
+    }
+    _Py_NewReference((PyObject *) sv);
+    /* Zero out items added by growing */
+    if (newsize > oldsize)
+        memset(&sv->ob_item[oldsize], 0,
+               sizeof(*sv->ob_item) * (newsize - oldsize));
+    *pv = (PyObject *) sv;
+    _PyObject_GC_TRACK(sv);
+    return 0;
+}
+
+int
+PyTuple_ClearFreeList(void)
+{
+    int freelist_size = 0;
+#if PyTuple_MAXSAVESIZE > 0
+    int i;
+    for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
+        PyTupleObject *p, *q;
+        p = free_list[i];
+        freelist_size += numfree[i];
+        free_list[i] = NULL;
+        numfree[i] = 0;
+        while (p) {
+            q = p;
+            p = (PyTupleObject *)(p->ob_item[0]);
+            PyObject_GC_Del(q);
+        }
+    }
+#endif
+    return freelist_size;
+}
+
+void
+PyTuple_Fini(void)
+{
+#if PyTuple_MAXSAVESIZE > 0
+    /* empty tuples are used all over the place and applications may
+     * rely on the fact that an empty tuple is a singleton. */
+    Py_XDECREF(free_list[0]);
+    free_list[0] = NULL;
+
+    (void)PyTuple_ClearFreeList();
+#endif
+#ifdef SHOW_TRACK_COUNT
+    show_track();
+#endif
+}
+
+/*********************** Tuple Iterator **************************/
+
+typedef struct {
+    PyObject_HEAD
+    long it_index;
+    PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */
+} tupleiterobject;
+
+static void
+tupleiter_dealloc(tupleiterobject *it)
+{
+    _PyObject_GC_UNTRACK(it);
+    Py_XDECREF(it->it_seq);
+    PyObject_GC_Del(it);
+}
+
+static int
+tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
+{
+    Py_VISIT(it->it_seq);
+    return 0;
+}
+
+static PyObject *
+tupleiter_next(tupleiterobject *it)
+{
+    PyTupleObject *seq;
+    PyObject *item;
+
+    assert(it != NULL);
+    seq = it->it_seq;
+    if (seq == NULL)
+        return NULL;
+    assert(PyTuple_Check(seq));
+
+    if (it->it_index < PyTuple_GET_SIZE(seq)) {
+        item = PyTuple_GET_ITEM(seq, it->it_index);
+        ++it->it_index;
+        Py_INCREF(item);
+        return item;
+    }
+
+    Py_DECREF(seq);
+    it->it_seq = NULL;
+    return NULL;
+}
+
+static PyObject *
+tupleiter_len(tupleiterobject *it)
+{
+    Py_ssize_t len = 0;
+    if (it->it_seq)
+        len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
+    return PyInt_FromSsize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef tupleiter_methods[] = {
+    {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+PyTypeObject PyTupleIter_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "tupleiterator",                            /* tp_name */
+    sizeof(tupleiterobject),                    /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    (destructor)tupleiter_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 */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)tupleiter_traverse,           /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)tupleiter_next,               /* tp_iternext */
+    tupleiter_methods,                          /* tp_methods */
+    0,
+};
+
+static PyObject *
+tuple_iter(PyObject *seq)
+{
+    tupleiterobject *it;
+
+    if (!PyTuple_Check(seq)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type);
+    if (it == NULL)
+        return NULL;
+    it->it_index = 0;
+    Py_INCREF(seq);
+    it->it_seq = (PyTupleObject *)seq;
+    _PyObject_GC_TRACK(it);
+    return (PyObject *)it;
+}
diff --git a/Python-2.7.5/Objects/typeobject.c b/Python-2.7.5/Objects/typeobject.c
new file mode 100644
index 0000000..be04c9e
--- /dev/null
+++ b/Python-2.7.5/Objects/typeobject.c
@@ -0,0 +1,6731 @@
+/* Type object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+#include <ctype.h>
+
+
+/* Support type attribute cache */
+
+/* The cache can keep references to the names alive for longer than
+   they normally would.  This is why the maximum size is limited to
+   MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large
+   strings are used as attribute names. */
+#define MCACHE_MAX_ATTR_SIZE    100
+#define MCACHE_SIZE_EXP         10
+#define MCACHE_HASH(version, name_hash)                                 \
+        (((unsigned int)(version) * (unsigned int)(name_hash))          \
+         >> (8*sizeof(unsigned int) - MCACHE_SIZE_EXP))
+#define MCACHE_HASH_METHOD(type, name)                                  \
+        MCACHE_HASH((type)->tp_version_tag,                     \
+                    ((PyStringObject *)(name))->ob_shash)
+#define MCACHE_CACHEABLE_NAME(name)                                     \
+        PyString_CheckExact(name) &&                            \
+        PyString_GET_SIZE(name) <= MCACHE_MAX_ATTR_SIZE
+
+struct method_cache_entry {
+    unsigned int version;
+    PyObject *name;             /* reference to exactly a str or None */
+    PyObject *value;            /* borrowed */
+};
+
+static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
+static unsigned int next_version_tag = 0;
+
+unsigned int
+PyType_ClearCache(void)
+{
+    Py_ssize_t i;
+    unsigned int cur_version_tag = next_version_tag - 1;
+
+    for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
+        method_cache[i].version = 0;
+        Py_CLEAR(method_cache[i].name);
+        method_cache[i].value = NULL;
+    }
+    next_version_tag = 0;
+    /* mark all version tags as invalid */
+    PyType_Modified(&PyBaseObject_Type);
+    return cur_version_tag;
+}
+
+void
+PyType_Modified(PyTypeObject *type)
+{
+    /* Invalidate any cached data for the specified type and all
+       subclasses.  This function is called after the base
+       classes, mro, or attributes of the type are altered.
+
+       Invariants:
+
+       - Py_TPFLAGS_VALID_VERSION_TAG is never set if
+         Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type
+         objects coming from non-recompiled extension modules)
+
+       - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type,
+         it must first be set on all super types.
+
+       This function clears the Py_TPFLAGS_VALID_VERSION_TAG of a
+       type (so it must first clear it on all subclasses).  The
+       tp_version_tag value is meaningless unless this flag is set.
+       We don't assign new version tags eagerly, but only as
+       needed.
+     */
+    PyObject *raw, *ref;
+    Py_ssize_t i, n;
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
+        return;
+
+    raw = type->tp_subclasses;
+    if (raw != NULL) {
+        n = PyList_GET_SIZE(raw);
+        for (i = 0; i < n; i++) {
+            ref = PyList_GET_ITEM(raw, i);
+            ref = PyWeakref_GET_OBJECT(ref);
+            if (ref != Py_None) {
+                PyType_Modified((PyTypeObject *)ref);
+            }
+        }
+    }
+    type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+}
+
+static void
+type_mro_modified(PyTypeObject *type, PyObject *bases) {
+    /*
+       Check that all base classes or elements of the mro of type are
+       able to be cached.  This function is called after the base
+       classes or mro of the type are altered.
+
+       Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type
+       inherits from an old-style class, either directly or if it
+       appears in the MRO of a new-style class.  No support either for
+       custom MROs that include types that are not officially super
+       types.
+
+       Called from mro_internal, which will subsequently be called on
+       each subclass when their mro is recursively updated.
+     */
+    Py_ssize_t i, n;
+    int clear = 0;
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
+        return;
+
+    n = PyTuple_GET_SIZE(bases);
+    for (i = 0; i < n; i++) {
+        PyObject *b = PyTuple_GET_ITEM(bases, i);
+        PyTypeObject *cls;
+
+        if (!PyType_Check(b) ) {
+            clear = 1;
+            break;
+        }
+
+        cls = (PyTypeObject *)b;
+
+        if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
+            !PyType_IsSubtype(type, cls)) {
+            clear = 1;
+            break;
+        }
+    }
+
+    if (clear)
+        type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
+                            Py_TPFLAGS_VALID_VERSION_TAG);
+}
+
+static int
+assign_version_tag(PyTypeObject *type)
+{
+    /* Ensure that the tp_version_tag is valid and set
+       Py_TPFLAGS_VALID_VERSION_TAG.  To respect the invariant, this
+       must first be done on all super classes.  Return 0 if this
+       cannot be done, 1 if Py_TPFLAGS_VALID_VERSION_TAG.
+    */
+    Py_ssize_t i, n;
+    PyObject *bases;
+
+    if (PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
+        return 1;
+    if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
+        return 0;
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+        return 0;
+
+    type->tp_version_tag = next_version_tag++;
+    /* for stress-testing: next_version_tag &= 0xFF; */
+
+    if (type->tp_version_tag == 0) {
+        /* wrap-around or just starting Python - clear the whole
+           cache by filling names with references to Py_None.
+           Values are also set to NULL for added protection, as they
+           are borrowed reference */
+        for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
+            method_cache[i].value = NULL;
+            Py_XDECREF(method_cache[i].name);
+            method_cache[i].name = Py_None;
+            Py_INCREF(Py_None);
+        }
+        /* mark all version tags as invalid */
+        PyType_Modified(&PyBaseObject_Type);
+        return 1;
+    }
+    bases = type->tp_bases;
+    n = PyTuple_GET_SIZE(bases);
+    for (i = 0; i < n; i++) {
+        PyObject *b = PyTuple_GET_ITEM(bases, i);
+        assert(PyType_Check(b));
+        if (!assign_version_tag((PyTypeObject *)b))
+            return 0;
+    }
+    type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
+    return 1;
+}
+
+
+static PyMemberDef type_members[] = {
+    {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY},
+    {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY},
+    {"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
+    {"__weakrefoffset__", T_LONG,
+     offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
+    {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY},
+    {"__dictoffset__", T_LONG,
+     offsetof(PyTypeObject, tp_dictoffset), READONLY},
+    {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY},
+    {0}
+};
+
+static PyObject *
+type_name(PyTypeObject *type, void *context)
+{
+    const char *s;
+
+    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+        PyHeapTypeObject* et = (PyHeapTypeObject*)type;
+
+        Py_INCREF(et->ht_name);
+        return et->ht_name;
+    }
+    else {
+        s = strrchr(type->tp_name, '.');
+        if (s == NULL)
+            s = type->tp_name;
+        else
+            s++;
+        return PyString_FromString(s);
+    }
+}
+
+static int
+type_set_name(PyTypeObject *type, PyObject *value, void *context)
+{
+    PyHeapTypeObject* et;
+    PyObject *tmp;
+
+    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't set %s.__name__", type->tp_name);
+        return -1;
+    }
+    if (!value) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't delete %s.__name__", type->tp_name);
+        return -1;
+    }
+    if (!PyString_Check(value)) {
+        PyErr_Format(PyExc_TypeError,
+                     "can only assign string to %s.__name__, not '%s'",
+                     type->tp_name, Py_TYPE(value)->tp_name);
+        return -1;
+    }
+    if (strlen(PyString_AS_STRING(value))
+        != (size_t)PyString_GET_SIZE(value)) {
+        PyErr_Format(PyExc_ValueError,
+                     "__name__ must not contain null bytes");
+        return -1;
+    }
+
+    et = (PyHeapTypeObject*)type;
+
+    Py_INCREF(value);
+
+    /* Wait until et is a sane state before Py_DECREF'ing the old et->ht_name
+       value.  (Bug #16447.)  */
+    tmp = et->ht_name;
+    et->ht_name = value;
+
+    type->tp_name = PyString_AS_STRING(value);
+    Py_DECREF(tmp);
+
+    return 0;
+}
+
+static PyObject *
+type_module(PyTypeObject *type, void *context)
+{
+    PyObject *mod;
+    char *s;
+
+    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+        mod = PyDict_GetItemString(type->tp_dict, "__module__");
+        if (!mod) {
+            PyErr_Format(PyExc_AttributeError, "__module__");
+            return 0;
+        }
+        Py_XINCREF(mod);
+        return mod;
+    }
+    else {
+        s = strrchr(type->tp_name, '.');
+        if (s != NULL)
+            return PyString_FromStringAndSize(
+                type->tp_name, (Py_ssize_t)(s - type->tp_name));
+        return PyString_FromString("__builtin__");
+    }
+}
+
+static int
+type_set_module(PyTypeObject *type, PyObject *value, void *context)
+{
+    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't set %s.__module__", type->tp_name);
+        return -1;
+    }
+    if (!value) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't delete %s.__module__", type->tp_name);
+        return -1;
+    }
+
+    PyType_Modified(type);
+
+    return PyDict_SetItemString(type->tp_dict, "__module__", value);
+}
+
+static PyObject *
+type_abstractmethods(PyTypeObject *type, void *context)
+{
+    PyObject *mod = NULL;
+    /* type itself has an __abstractmethods__ descriptor (this). Don't return
+       that. */
+    if (type != &PyType_Type)
+        mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__");
+    if (!mod) {
+        PyErr_SetString(PyExc_AttributeError, "__abstractmethods__");
+        return NULL;
+    }
+    Py_XINCREF(mod);
+    return mod;
+}
+
+static int
+type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context)
+{
+    /* __abstractmethods__ should only be set once on a type, in
+       abc.ABCMeta.__new__, so this function doesn't do anything
+       special to update subclasses.
+    */
+    int abstract, res;
+    if (value != NULL) {
+        abstract = PyObject_IsTrue(value);
+        if (abstract < 0)
+            return -1;
+        res = PyDict_SetItemString(type->tp_dict, "__abstractmethods__", value);
+    }
+    else {
+        abstract = 0;
+        res = PyDict_DelItemString(type->tp_dict, "__abstractmethods__");
+        if (res && PyErr_ExceptionMatches(PyExc_KeyError)) {
+            PyErr_SetString(PyExc_AttributeError, "__abstractmethods__");
+            return -1;
+        }
+    }
+    if (res == 0) {
+        PyType_Modified(type);
+        if (abstract)
+            type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
+        else
+            type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT;
+    }
+    return res;
+}
+
+static PyObject *
+type_get_bases(PyTypeObject *type, void *context)
+{
+    Py_INCREF(type->tp_bases);
+    return type->tp_bases;
+}
+
+static PyTypeObject *best_base(PyObject *);
+static int mro_internal(PyTypeObject *);
+static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, char *);
+static int add_subclass(PyTypeObject*, PyTypeObject*);
+static void remove_subclass(PyTypeObject *, PyTypeObject *);
+static void update_all_slots(PyTypeObject *);
+
+typedef int (*update_callback)(PyTypeObject *, void *);
+static int update_subclasses(PyTypeObject *type, PyObject *name,
+                             update_callback callback, void *data);
+static int recurse_down_subclasses(PyTypeObject *type, PyObject *name,
+                                   update_callback callback, void *data);
+
+static int
+mro_subclasses(PyTypeObject *type, PyObject* temp)
+{
+    PyTypeObject *subclass;
+    PyObject *ref, *subclasses, *old_mro;
+    Py_ssize_t i, n;
+
+    subclasses = type->tp_subclasses;
+    if (subclasses == NULL)
+        return 0;
+    assert(PyList_Check(subclasses));
+    n = PyList_GET_SIZE(subclasses);
+    for (i = 0; i < n; i++) {
+        ref = PyList_GET_ITEM(subclasses, i);
+        assert(PyWeakref_CheckRef(ref));
+        subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref);
+        assert(subclass != NULL);
+        if ((PyObject *)subclass == Py_None)
+            continue;
+        assert(PyType_Check(subclass));
+        old_mro = subclass->tp_mro;
+        if (mro_internal(subclass) < 0) {
+            subclass->tp_mro = old_mro;
+            return -1;
+        }
+        else {
+            PyObject* tuple;
+            tuple = PyTuple_Pack(2, subclass, old_mro);
+            Py_DECREF(old_mro);
+            if (!tuple)
+                return -1;
+            if (PyList_Append(temp, tuple) < 0)
+                return -1;
+            Py_DECREF(tuple);
+        }
+        if (mro_subclasses(subclass, temp) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+static int
+type_set_bases(PyTypeObject *type, PyObject *value, void *context)
+{
+    Py_ssize_t i;
+    int r = 0;
+    PyObject *ob, *temp;
+    PyTypeObject *new_base, *old_base;
+    PyObject *old_bases, *old_mro;
+
+    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't set %s.__bases__", type->tp_name);
+        return -1;
+    }
+    if (!value) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't delete %s.__bases__", type->tp_name);
+        return -1;
+    }
+    if (!PyTuple_Check(value)) {
+        PyErr_Format(PyExc_TypeError,
+             "can only assign tuple to %s.__bases__, not %s",
+                 type->tp_name, Py_TYPE(value)->tp_name);
+        return -1;
+    }
+    if (PyTuple_GET_SIZE(value) == 0) {
+        PyErr_Format(PyExc_TypeError,
+             "can only assign non-empty tuple to %s.__bases__, not ()",
+                 type->tp_name);
+        return -1;
+    }
+    for (i = 0; i < PyTuple_GET_SIZE(value); i++) {
+        ob = PyTuple_GET_ITEM(value, i);
+        if (!PyClass_Check(ob) && !PyType_Check(ob)) {
+            PyErr_Format(
+                PyExc_TypeError,
+    "%s.__bases__ must be tuple of old- or new-style classes, not '%s'",
+                            type->tp_name, Py_TYPE(ob)->tp_name);
+                    return -1;
+        }
+        if (PyType_Check(ob)) {
+            if (PyType_IsSubtype((PyTypeObject*)ob, type)) {
+                PyErr_SetString(PyExc_TypeError,
+            "a __bases__ item causes an inheritance cycle");
+                return -1;
+            }
+        }
+    }
+
+    new_base = best_base(value);
+
+    if (!new_base) {
+        return -1;
+    }
+
+    if (!compatible_for_assignment(type->tp_base, new_base, "__bases__"))
+        return -1;
+
+    Py_INCREF(new_base);
+    Py_INCREF(value);
+
+    old_bases = type->tp_bases;
+    old_base = type->tp_base;
+    old_mro = type->tp_mro;
+
+    type->tp_bases = value;
+    type->tp_base = new_base;
+
+    if (mro_internal(type) < 0) {
+        goto bail;
+    }
+
+    temp = PyList_New(0);
+    if (!temp)
+        goto bail;
+
+    r = mro_subclasses(type, temp);
+
+    if (r < 0) {
+        for (i = 0; i < PyList_Size(temp); i++) {
+            PyTypeObject* cls;
+            PyObject* mro;
+            PyArg_UnpackTuple(PyList_GET_ITEM(temp, i),
+                             "", 2, 2, &cls, &mro);
+            Py_INCREF(mro);
+            ob = cls->tp_mro;
+            cls->tp_mro = mro;
+            Py_DECREF(ob);
+        }
+        Py_DECREF(temp);
+        goto bail;
+    }
+
+    Py_DECREF(temp);
+
+    /* any base that was in __bases__ but now isn't, we
+       need to remove |type| from its tp_subclasses.
+       conversely, any class now in __bases__ that wasn't
+       needs to have |type| added to its subclasses. */
+
+    /* for now, sod that: just remove from all old_bases,
+       add to all new_bases */
+
+    for (i = PyTuple_GET_SIZE(old_bases) - 1; i >= 0; i--) {
+        ob = PyTuple_GET_ITEM(old_bases, i);
+        if (PyType_Check(ob)) {
+            remove_subclass(
+                (PyTypeObject*)ob, type);
+        }
+    }
+
+    for (i = PyTuple_GET_SIZE(value) - 1; i >= 0; i--) {
+        ob = PyTuple_GET_ITEM(value, i);
+        if (PyType_Check(ob)) {
+            if (add_subclass((PyTypeObject*)ob, type) < 0)
+                r = -1;
+        }
+    }
+
+    update_all_slots(type);
+
+    Py_DECREF(old_bases);
+    Py_DECREF(old_base);
+    Py_DECREF(old_mro);
+
+    return r;
+
+  bail:
+    Py_DECREF(type->tp_bases);
+    Py_DECREF(type->tp_base);
+    if (type->tp_mro != old_mro) {
+        Py_DECREF(type->tp_mro);
+    }
+
+    type->tp_bases = old_bases;
+    type->tp_base = old_base;
+    type->tp_mro = old_mro;
+
+    return -1;
+}
+
+static PyObject *
+type_dict(PyTypeObject *type, void *context)
+{
+    if (type->tp_dict == NULL) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return PyDictProxy_New(type->tp_dict);
+}
+
+static PyObject *
+type_get_doc(PyTypeObject *type, void *context)
+{
+    PyObject *result;
+    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL)
+        return PyString_FromString(type->tp_doc);
+    result = PyDict_GetItemString(type->tp_dict, "__doc__");
+    if (result == NULL) {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+    else if (Py_TYPE(result)->tp_descr_get) {
+        result = Py_TYPE(result)->tp_descr_get(result, NULL,
+                                               (PyObject *)type);
+    }
+    else {
+        Py_INCREF(result);
+    }
+    return result;
+}
+
+static PyObject *
+type___instancecheck__(PyObject *type, PyObject *inst)
+{
+    switch (_PyObject_RealIsInstance(inst, type)) {
+    case -1:
+        return NULL;
+    case 0:
+        Py_RETURN_FALSE;
+    default:
+        Py_RETURN_TRUE;
+    }
+}
+
+
+static PyObject *
+type___subclasscheck__(PyObject *type, PyObject *inst)
+{
+    switch (_PyObject_RealIsSubclass(inst, type)) {
+    case -1:
+        return NULL;
+    case 0:
+        Py_RETURN_FALSE;
+    default:
+        Py_RETURN_TRUE;
+    }
+}
+
+
+static PyGetSetDef type_getsets[] = {
+    {"__name__", (getter)type_name, (setter)type_set_name, NULL},
+    {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},
+    {"__module__", (getter)type_module, (setter)type_set_module, NULL},
+    {"__abstractmethods__", (getter)type_abstractmethods,
+     (setter)type_set_abstractmethods, NULL},
+    {"__dict__",  (getter)type_dict,  NULL, NULL},
+    {"__doc__", (getter)type_get_doc, NULL, NULL},
+    {0}
+};
+
+
+static PyObject*
+type_richcompare(PyObject *v, PyObject *w, int op)
+{
+    PyObject *result;
+    Py_uintptr_t vv, ww;
+    int c;
+
+    /* Make sure both arguments are types. */
+    if (!PyType_Check(v) || !PyType_Check(w) ||
+        /* If there is a __cmp__ method defined, let it be called instead
+           of our dumb function designed merely to warn.  See bug
+           #7491. */
+        Py_TYPE(v)->tp_compare || Py_TYPE(w)->tp_compare) {
+        result = Py_NotImplemented;
+        goto out;
+    }
+
+    /* Py3K warning if comparison isn't == or !=  */
+    if (Py_Py3kWarningFlag && op != Py_EQ && op != Py_NE &&
+        PyErr_WarnEx(PyExc_DeprecationWarning,
+                   "type inequality comparisons not supported "
+                   "in 3.x", 1) < 0) {
+        return NULL;
+    }
+
+    /* Compare addresses */
+    vv = (Py_uintptr_t)v;
+    ww = (Py_uintptr_t)w;
+    switch (op) {
+    case Py_LT: c = vv <  ww; break;
+    case Py_LE: c = vv <= ww; break;
+    case Py_EQ: c = vv == ww; break;
+    case Py_NE: c = vv != ww; break;
+    case Py_GT: c = vv >  ww; break;
+    case Py_GE: c = vv >= ww; break;
+    default:
+        result = Py_NotImplemented;
+        goto out;
+    }
+    result = c ? Py_True : Py_False;
+
+  /* incref and return */
+  out:
+    Py_INCREF(result);
+    return result;
+}
+
+static PyObject *
+type_repr(PyTypeObject *type)
+{
+    PyObject *mod, *name, *rtn;
+    char *kind;
+
+    mod = type_module(type, NULL);
+    if (mod == NULL)
+        PyErr_Clear();
+    else if (!PyString_Check(mod)) {
+        Py_DECREF(mod);
+        mod = NULL;
+    }
+    name = type_name(type, NULL);
+    if (name == NULL) {
+        Py_XDECREF(mod);
+        return NULL;
+    }
+
+    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+        kind = "class";
+    else
+        kind = "type";
+
+    if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) {
+        rtn = PyString_FromFormat("<%s '%s.%s'>",
+                                  kind,
+                                  PyString_AS_STRING(mod),
+                                  PyString_AS_STRING(name));
+    }
+    else
+        rtn = PyString_FromFormat("<%s '%s'>", kind, type->tp_name);
+
+    Py_XDECREF(mod);
+    Py_DECREF(name);
+    return rtn;
+}
+
+static PyObject *
+type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *obj;
+
+    if (type->tp_new == NULL) {
+        PyErr_Format(PyExc_TypeError,
+                     "cannot create '%.100s' instances",
+                     type->tp_name);
+        return NULL;
+    }
+
+    obj = type->tp_new(type, args, kwds);
+    if (obj != NULL) {
+        /* Ugly exception: when the call was type(something),
+           don't call tp_init on the result. */
+        if (type == &PyType_Type &&
+            PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+            (kwds == NULL ||
+             (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
+            return obj;
+        /* If the returned object is not an instance of type,
+           it won't be initialized. */
+        if (!PyType_IsSubtype(obj->ob_type, type))
+            return obj;
+        type = obj->ob_type;
+        if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) &&
+            type->tp_init != NULL &&
+            type->tp_init(obj, args, kwds) < 0) {
+            Py_DECREF(obj);
+            obj = NULL;
+        }
+    }
+    return obj;
+}
+
+PyObject *
+PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
+{
+    PyObject *obj;
+    const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
+    /* note that we need to add one, for the sentinel */
+
+    if (PyType_IS_GC(type))
+        obj = _PyObject_GC_Malloc(size);
+    else
+        obj = (PyObject *)PyObject_MALLOC(size);
+
+    if (obj == NULL)
+        return PyErr_NoMemory();
+
+    memset(obj, '\0', size);
+
+    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+        Py_INCREF(type);
+
+    if (type->tp_itemsize == 0)
+        PyObject_INIT(obj, type);
+    else
+        (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
+
+    if (PyType_IS_GC(type))
+        _PyObject_GC_TRACK(obj);
+    return obj;
+}
+
+PyObject *
+PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    return type->tp_alloc(type, 0);
+}
+
+/* Helpers for subtyping */
+
+static int
+traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg)
+{
+    Py_ssize_t i, n;
+    PyMemberDef *mp;
+
+    n = Py_SIZE(type);
+    mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
+    for (i = 0; i < n; i++, mp++) {
+        if (mp->type == T_OBJECT_EX) {
+            char *addr = (char *)self + mp->offset;
+            PyObject *obj = *(PyObject **)addr;
+            if (obj != NULL) {
+                int err = visit(obj, arg);
+                if (err)
+                    return err;
+            }
+        }
+    }
+    return 0;
+}
+
+static int
+subtype_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    PyTypeObject *type, *base;
+    traverseproc basetraverse;
+
+    /* Find the nearest base with a different tp_traverse,
+       and traverse slots while we're at it */
+    type = Py_TYPE(self);
+    base = type;
+    while ((basetraverse = base->tp_traverse) == subtype_traverse) {
+        if (Py_SIZE(base)) {
+            int err = traverse_slots(base, self, visit, arg);
+            if (err)
+                return err;
+        }
+        base = base->tp_base;
+        assert(base);
+    }
+
+    if (type->tp_dictoffset != base->tp_dictoffset) {
+        PyObject **dictptr = _PyObject_GetDictPtr(self);
+        if (dictptr && *dictptr)
+            Py_VISIT(*dictptr);
+    }
+
+    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+        /* For a heaptype, the instances count as references
+           to the type.          Traverse the type so the collector
+           can find cycles involving this link. */
+        Py_VISIT(type);
+
+    if (basetraverse)
+        return basetraverse(self, visit, arg);
+    return 0;
+}
+
+static void
+clear_slots(PyTypeObject *type, PyObject *self)
+{
+    Py_ssize_t i, n;
+    PyMemberDef *mp;
+
+    n = Py_SIZE(type);
+    mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
+    for (i = 0; i < n; i++, mp++) {
+        if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
+            char *addr = (char *)self + mp->offset;
+            PyObject *obj = *(PyObject **)addr;
+            if (obj != NULL) {
+                *(PyObject **)addr = NULL;
+                Py_DECREF(obj);
+            }
+        }
+    }
+}
+
+static int
+subtype_clear(PyObject *self)
+{
+    PyTypeObject *type, *base;
+    inquiry baseclear;
+
+    /* Find the nearest base with a different tp_clear
+       and clear slots while we're at it */
+    type = Py_TYPE(self);
+    base = type;
+    while ((baseclear = base->tp_clear) == subtype_clear) {
+        if (Py_SIZE(base))
+            clear_slots(base, self);
+        base = base->tp_base;
+        assert(base);
+    }
+
+    /* Clear the instance dict (if any), to break cycles involving only
+       __dict__ slots (as in the case 'self.__dict__ is self'). */
+    if (type->tp_dictoffset != base->tp_dictoffset) {
+        PyObject **dictptr = _PyObject_GetDictPtr(self);
+        if (dictptr && *dictptr)
+            Py_CLEAR(*dictptr);
+    }
+
+    if (baseclear)
+        return baseclear(self);
+    return 0;
+}
+
+static void
+subtype_dealloc(PyObject *self)
+{
+    PyTypeObject *type, *base;
+    destructor basedealloc;
+    PyThreadState *tstate = PyThreadState_GET();
+
+    /* Extract the type; we expect it to be a heap type */
+    type = Py_TYPE(self);
+    assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+    /* Test whether the type has GC exactly once */
+
+    if (!PyType_IS_GC(type)) {
+        /* It's really rare to find a dynamic type that doesn't have
+           GC; it can only happen when deriving from 'object' and not
+           adding any slots or instance variables.  This allows
+           certain simplifications: there's no need to call
+           clear_slots(), or DECREF the dict, or clear weakrefs. */
+
+        /* Maybe call finalizer; exit early if resurrected */
+        if (type->tp_del) {
+            type->tp_del(self);
+            if (self->ob_refcnt > 0)
+                return;
+        }
+
+        /* Find the nearest base with a different tp_dealloc */
+        base = type;
+        while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+            assert(Py_SIZE(base) == 0);
+            base = base->tp_base;
+            assert(base);
+        }
+
+        /* Extract the type again; tp_del may have changed it */
+        type = Py_TYPE(self);
+
+        /* Call the base tp_dealloc() */
+        assert(basedealloc);
+        basedealloc(self);
+
+        /* Can't reference self beyond this point */
+        Py_DECREF(type);
+
+        /* Done */
+        return;
+    }
+
+    /* We get here only if the type has GC */
+
+    /* UnTrack and re-Track around the trashcan macro, alas */
+    /* See explanation at end of function for full disclosure */
+    PyObject_GC_UnTrack(self);
+    ++_PyTrash_delete_nesting;
+    ++ tstate->trash_delete_nesting;
+    Py_TRASHCAN_SAFE_BEGIN(self);
+    --_PyTrash_delete_nesting;
+    -- tstate->trash_delete_nesting;
+    /* DO NOT restore GC tracking at this point.  weakref callbacks
+     * (if any, and whether directly here or indirectly in something we
+     * call) may trigger GC, and if self is tracked at that point, it
+     * will look like trash to GC and GC will try to delete self again.
+     */
+
+    /* Find the nearest base with a different tp_dealloc */
+    base = type;
+    while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+        base = base->tp_base;
+        assert(base);
+    }
+
+    /* If we added a weaklist, we clear it.      Do this *before* calling
+       the finalizer (__del__), clearing slots, or clearing the instance
+       dict. */
+
+    if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
+        PyObject_ClearWeakRefs(self);
+
+    /* Maybe call finalizer; exit early if resurrected */
+    if (type->tp_del) {
+        _PyObject_GC_TRACK(self);
+        type->tp_del(self);
+        if (self->ob_refcnt > 0)
+            goto endlabel;              /* resurrected */
+        else
+            _PyObject_GC_UNTRACK(self);
+        /* New weakrefs could be created during the finalizer call.
+            If this occurs, clear them out without calling their
+            finalizers since they might rely on part of the object
+            being finalized that has already been destroyed. */
+        if (type->tp_weaklistoffset && !base->tp_weaklistoffset) {
+            /* Modeled after GET_WEAKREFS_LISTPTR() */
+            PyWeakReference **list = (PyWeakReference **) \
+                PyObject_GET_WEAKREFS_LISTPTR(self);
+            while (*list)
+                _PyWeakref_ClearRef(*list);
+        }
+    }
+
+    /*  Clear slots up to the nearest base with a different tp_dealloc */
+    base = type;
+    while (base->tp_dealloc == subtype_dealloc) {
+        if (Py_SIZE(base))
+            clear_slots(base, self);
+        base = base->tp_base;
+        assert(base);
+    }
+
+    /* If we added a dict, DECREF it */
+    if (type->tp_dictoffset && !base->tp_dictoffset) {
+        PyObject **dictptr = _PyObject_GetDictPtr(self);
+        if (dictptr != NULL) {
+            PyObject *dict = *dictptr;
+            if (dict != NULL) {
+                Py_DECREF(dict);
+                *dictptr = NULL;
+            }
+        }
+    }
+
+    /* Extract the type again; tp_del may have changed it */
+    type = Py_TYPE(self);
+
+    /* Call the base tp_dealloc(); first retrack self if
+     * basedealloc knows about gc.
+     */
+    if (PyType_IS_GC(base))
+        _PyObject_GC_TRACK(self);
+    assert(basedealloc);
+    basedealloc(self);
+
+    /* Can't reference self beyond this point */
+    Py_DECREF(type);
+
+  endlabel:
+    ++_PyTrash_delete_nesting;
+    ++ tstate->trash_delete_nesting;
+    Py_TRASHCAN_SAFE_END(self);
+    --_PyTrash_delete_nesting;
+    -- tstate->trash_delete_nesting;
+
+    /* Explanation of the weirdness around the trashcan macros:
+
+       Q. What do the trashcan macros do?
+
+       A. Read the comment titled "Trashcan mechanism" in object.h.
+          For one, this explains why there must be a call to GC-untrack
+          before the trashcan begin macro.      Without understanding the
+          trashcan code, the answers to the following questions don't make
+          sense.
+
+       Q. Why do we GC-untrack before the trashcan and then immediately
+          GC-track again afterward?
+
+       A. In the case that the base class is GC-aware, the base class
+          probably GC-untracks the object.      If it does that using the
+          UNTRACK macro, this will crash when the object is already
+          untracked.  Because we don't know what the base class does, the
+          only safe thing is to make sure the object is tracked when we
+          call the base class dealloc.  But...  The trashcan begin macro
+          requires that the object is *untracked* before it is called.  So
+          the dance becomes:
+
+         GC untrack
+         trashcan begin
+         GC track
+
+       Q. Why did the last question say "immediately GC-track again"?
+          It's nowhere near immediately.
+
+       A. Because the code *used* to re-track immediately.      Bad Idea.
+          self has a refcount of 0, and if gc ever gets its hands on it
+          (which can happen if any weakref callback gets invoked), it
+          looks like trash to gc too, and gc also tries to delete self
+          then.  But we're already deleting self.  Double deallocation is
+          a subtle disaster.
+
+       Q. Why the bizarre (net-zero) manipulation of
+          _PyTrash_delete_nesting around the trashcan macros?
+
+       A. Some base classes (e.g. list) also use the trashcan mechanism.
+          The following scenario used to be possible:
+
+          - suppose the trashcan level is one below the trashcan limit
+
+          - subtype_dealloc() is called
+
+          - the trashcan limit is not yet reached, so the trashcan level
+        is incremented and the code between trashcan begin and end is
+        executed
+
+          - this destroys much of the object's contents, including its
+        slots and __dict__
+
+          - basedealloc() is called; this is really list_dealloc(), or
+        some other type which also uses the trashcan macros
+
+          - the trashcan limit is now reached, so the object is put on the
+        trashcan's to-be-deleted-later list
+
+          - basedealloc() returns
+
+          - subtype_dealloc() decrefs the object's type
+
+          - subtype_dealloc() returns
+
+          - later, the trashcan code starts deleting the objects from its
+        to-be-deleted-later list
+
+          - subtype_dealloc() is called *AGAIN* for the same object
+
+          - at the very least (if the destroyed slots and __dict__ don't
+        cause problems) the object's type gets decref'ed a second
+        time, which is *BAD*!!!
+
+          The remedy is to make sure that if the code between trashcan
+          begin and end in subtype_dealloc() is called, the code between
+          trashcan begin and end in basedealloc() will also be called.
+          This is done by decrementing the level after passing into the
+          trashcan block, and incrementing it just before leaving the
+          block.
+
+          But now it's possible that a chain of objects consisting solely
+          of objects whose deallocator is subtype_dealloc() will defeat
+          the trashcan mechanism completely: the decremented level means
+          that the effective level never reaches the limit.      Therefore, we
+          *increment* the level *before* entering the trashcan block, and
+          matchingly decrement it after leaving.  This means the trashcan
+          code will trigger a little early, but that's no big deal.
+
+       Q. Are there any live examples of code in need of all this
+          complexity?
+
+       A. Yes.  See SF bug 668433 for code that crashed (when Python was
+          compiled in debug mode) before the trashcan level manipulations
+          were added.  For more discussion, see SF patches 581742, 575073
+          and bug 574207.
+    */
+}
+
+static PyTypeObject *solid_base(PyTypeObject *type);
+
+/* type test with subclassing support */
+
+int
+PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
+{
+    PyObject *mro;
+
+    if (!(a->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+        return b == a || b == &PyBaseObject_Type;
+
+    mro = a->tp_mro;
+    if (mro != NULL) {
+        /* Deal with multiple inheritance without recursion
+           by walking the MRO tuple */
+        Py_ssize_t i, n;
+        assert(PyTuple_Check(mro));
+        n = PyTuple_GET_SIZE(mro);
+        for (i = 0; i < n; i++) {
+            if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
+                return 1;
+        }
+        return 0;
+    }
+    else {
+        /* a is not completely initilized yet; follow tp_base */
+        do {
+            if (a == b)
+                return 1;
+            a = a->tp_base;
+        } while (a != NULL);
+        return b == &PyBaseObject_Type;
+    }
+}
+
+/* Internal routines to do a method lookup in the type
+   without looking in the instance dictionary
+   (so we can't use PyObject_GetAttr) but still binding
+   it to the instance.  The arguments are the object,
+   the method name as a C string, and the address of a
+   static variable used to cache the interned Python string.
+
+   Two variants:
+
+   - lookup_maybe() returns NULL without raising an exception
+     when the _PyType_Lookup() call fails;
+
+   - lookup_method() always raises an exception upon errors.
+
+   - _PyObject_LookupSpecial() exported for the benefit of other places.
+*/
+
+static PyObject *
+lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+    PyObject *res;
+
+    if (*attrobj == NULL) {
+        *attrobj = PyString_InternFromString(attrstr);
+        if (*attrobj == NULL)
+            return NULL;
+    }
+    res = _PyType_Lookup(Py_TYPE(self), *attrobj);
+    if (res != NULL) {
+        descrgetfunc f;
+        if ((f = Py_TYPE(res)->tp_descr_get) == NULL)
+            Py_INCREF(res);
+        else
+            res = f(res, self, (PyObject *)(Py_TYPE(self)));
+    }
+    return res;
+}
+
+static PyObject *
+lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+    PyObject *res = lookup_maybe(self, attrstr, attrobj);
+    if (res == NULL && !PyErr_Occurred())
+        PyErr_SetObject(PyExc_AttributeError, *attrobj);
+    return res;
+}
+
+PyObject *
+_PyObject_LookupSpecial(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+    assert(!PyInstance_Check(self));
+    return lookup_maybe(self, attrstr, attrobj);
+}
+
+/* A variation of PyObject_CallMethod that uses lookup_method()
+   instead of PyObject_GetAttrString().  This uses the same convention
+   as lookup_method to cache the interned name string object. */
+
+static PyObject *
+call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
+{
+    va_list va;
+    PyObject *args, *func = 0, *retval;
+    va_start(va, format);
+
+    func = lookup_maybe(o, name, nameobj);
+    if (func == NULL) {
+        va_end(va);
+        if (!PyErr_Occurred())
+            PyErr_SetObject(PyExc_AttributeError, *nameobj);
+        return NULL;
+    }
+
+    if (format && *format)
+        args = Py_VaBuildValue(format, va);
+    else
+        args = PyTuple_New(0);
+
+    va_end(va);
+
+    if (args == NULL)
+        return NULL;
+
+    assert(PyTuple_Check(args));
+    retval = PyObject_Call(func, args, NULL);
+
+    Py_DECREF(args);
+    Py_DECREF(func);
+
+    return retval;
+}
+
+/* Clone of call_method() that returns NotImplemented when the lookup fails. */
+
+static PyObject *
+call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
+{
+    va_list va;
+    PyObject *args, *func = 0, *retval;
+    va_start(va, format);
+
+    func = lookup_maybe(o, name, nameobj);
+    if (func == NULL) {
+        va_end(va);
+        if (!PyErr_Occurred()) {
+            Py_INCREF(Py_NotImplemented);
+            return Py_NotImplemented;
+        }
+        return NULL;
+    }
+
+    if (format && *format)
+        args = Py_VaBuildValue(format, va);
+    else
+        args = PyTuple_New(0);
+
+    va_end(va);
+
+    if (args == NULL)
+        return NULL;
+
+    assert(PyTuple_Check(args));
+    retval = PyObject_Call(func, args, NULL);
+
+    Py_DECREF(args);
+    Py_DECREF(func);
+
+    return retval;
+}
+
+static int
+fill_classic_mro(PyObject *mro, PyObject *cls)
+{
+    PyObject *bases, *base;
+    Py_ssize_t i, n;
+
+    assert(PyList_Check(mro));
+    assert(PyClass_Check(cls));
+    i = PySequence_Contains(mro, cls);
+    if (i < 0)
+        return -1;
+    if (!i) {
+        if (PyList_Append(mro, cls) < 0)
+            return -1;
+    }
+    bases = ((PyClassObject *)cls)->cl_bases;
+    assert(bases && PyTuple_Check(bases));
+    n = PyTuple_GET_SIZE(bases);
+    for (i = 0; i < n; i++) {
+        base = PyTuple_GET_ITEM(bases, i);
+        if (fill_classic_mro(mro, base) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+static PyObject *
+classic_mro(PyObject *cls)
+{
+    PyObject *mro;
+
+    assert(PyClass_Check(cls));
+    mro = PyList_New(0);
+    if (mro != NULL) {
+        if (fill_classic_mro(mro, cls) == 0)
+            return mro;
+        Py_DECREF(mro);
+    }
+    return NULL;
+}
+
+/*
+    Method resolution order algorithm C3 described in
+    "A Monotonic Superclass Linearization for Dylan",
+    by Kim Barrett, Bob Cassel, Paul Haahr,
+    David A. Moon, Keith Playford, and P. Tucker Withington.
+    (OOPSLA 1996)
+
+    Some notes about the rules implied by C3:
+
+    No duplicate bases.
+    It isn't legal to repeat a class in a list of base classes.
+
+    The next three properties are the 3 constraints in "C3".
+
+    Local precendece order.
+    If A precedes B in C's MRO, then A will precede B in the MRO of all
+    subclasses of C.
+
+    Monotonicity.
+    The MRO of a class must be an extension without reordering of the
+    MRO of each of its superclasses.
+
+    Extended Precedence Graph (EPG).
+    Linearization is consistent if there is a path in the EPG from
+    each class to all its successors in the linearization.  See
+    the paper for definition of EPG.
+ */
+
+static int
+tail_contains(PyObject *list, int whence, PyObject *o) {
+    Py_ssize_t j, size;
+    size = PyList_GET_SIZE(list);
+
+    for (j = whence+1; j < size; j++) {
+        if (PyList_GET_ITEM(list, j) == o)
+            return 1;
+    }
+    return 0;
+}
+
+static PyObject *
+class_name(PyObject *cls)
+{
+    PyObject *name = PyObject_GetAttrString(cls, "__name__");
+    if (name == NULL) {
+        PyErr_Clear();
+        Py_XDECREF(name);
+        name = PyObject_Repr(cls);
+    }
+    if (name == NULL)
+        return NULL;
+    if (!PyString_Check(name)) {
+        Py_DECREF(name);
+        return NULL;
+    }
+    return name;
+}
+
+static int
+check_duplicates(PyObject *list)
+{
+    Py_ssize_t i, j, n;
+    /* Let's use a quadratic time algorithm,
+       assuming that the bases lists is short.
+    */
+    n = PyList_GET_SIZE(list);
+    for (i = 0; i < n; i++) {
+        PyObject *o = PyList_GET_ITEM(list, i);
+        for (j = i + 1; j < n; j++) {
+            if (PyList_GET_ITEM(list, j) == o) {
+                o = class_name(o);
+                PyErr_Format(PyExc_TypeError,
+                             "duplicate base class %s",
+                             o ? PyString_AS_STRING(o) : "?");
+                Py_XDECREF(o);
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+/* Raise a TypeError for an MRO order disagreement.
+
+   It's hard to produce a good error message.  In the absence of better
+   insight into error reporting, report the classes that were candidates
+   to be put next into the MRO.  There is some conflict between the
+   order in which they should be put in the MRO, but it's hard to
+   diagnose what constraint can't be satisfied.
+*/
+
+static void
+set_mro_error(PyObject *to_merge, int *remain)
+{
+    Py_ssize_t i, n, off, to_merge_size;
+    char buf[1000];
+    PyObject *k, *v;
+    PyObject *set = PyDict_New();
+    if (!set) return;
+
+    to_merge_size = PyList_GET_SIZE(to_merge);
+    for (i = 0; i < to_merge_size; i++) {
+        PyObject *L = PyList_GET_ITEM(to_merge, i);
+        if (remain[i] < PyList_GET_SIZE(L)) {
+            PyObject *c = PyList_GET_ITEM(L, remain[i]);
+            if (PyDict_SetItem(set, c, Py_None) < 0) {
+                Py_DECREF(set);
+                return;
+            }
+        }
+    }
+    n = PyDict_Size(set);
+
+    off = PyOS_snprintf(buf, sizeof(buf), "Cannot create a \
+consistent method resolution\norder (MRO) for bases");
+    i = 0;
+    while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) {
+        PyObject *name = class_name(k);
+        off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s",
+                             name ? PyString_AS_STRING(name) : "?");
+        Py_XDECREF(name);
+        if (--n && (size_t)(off+1) < sizeof(buf)) {
+            buf[off++] = ',';
+            buf[off] = '\0';
+        }
+    }
+    PyErr_SetString(PyExc_TypeError, buf);
+    Py_DECREF(set);
+}
+
+static int
+pmerge(PyObject *acc, PyObject* to_merge) {
+    Py_ssize_t i, j, to_merge_size, empty_cnt;
+    int *remain;
+    int ok;
+
+    to_merge_size = PyList_GET_SIZE(to_merge);
+
+    /* remain stores an index into each sublist of to_merge.
+       remain[i] is the index of the next base in to_merge[i]
+       that is not included in acc.
+    */
+    remain = (int *)PyMem_MALLOC(SIZEOF_INT*to_merge_size);
+    if (remain == NULL)
+        return -1;
+    for (i = 0; i < to_merge_size; i++)
+        remain[i] = 0;
+
+  again:
+    empty_cnt = 0;
+    for (i = 0; i < to_merge_size; i++) {
+        PyObject *candidate;
+
+        PyObject *cur_list = PyList_GET_ITEM(to_merge, i);
+
+        if (remain[i] >= PyList_GET_SIZE(cur_list)) {
+            empty_cnt++;
+            continue;
+        }
+
+        /* Choose next candidate for MRO.
+
+           The input sequences alone can determine the choice.
+           If not, choose the class which appears in the MRO
+           of the earliest direct superclass of the new class.
+        */
+
+        candidate = PyList_GET_ITEM(cur_list, remain[i]);
+        for (j = 0; j < to_merge_size; j++) {
+            PyObject *j_lst = PyList_GET_ITEM(to_merge, j);
+            if (tail_contains(j_lst, remain[j], candidate)) {
+                goto skip; /* continue outer loop */
+            }
+        }
+        ok = PyList_Append(acc, candidate);
+        if (ok < 0) {
+            PyMem_Free(remain);
+            return -1;
+        }
+        for (j = 0; j < to_merge_size; j++) {
+            PyObject *j_lst = PyList_GET_ITEM(to_merge, j);
+            if (remain[j] < PyList_GET_SIZE(j_lst) &&
+                PyList_GET_ITEM(j_lst, remain[j]) == candidate) {
+                remain[j]++;
+            }
+        }
+        goto again;
+      skip: ;
+    }
+
+    if (empty_cnt == to_merge_size) {
+        PyMem_FREE(remain);
+        return 0;
+    }
+    set_mro_error(to_merge, remain);
+    PyMem_FREE(remain);
+    return -1;
+}
+
+static PyObject *
+mro_implementation(PyTypeObject *type)
+{
+    Py_ssize_t i, n;
+    int ok;
+    PyObject *bases, *result;
+    PyObject *to_merge, *bases_aslist;
+
+    if (type->tp_dict == NULL) {
+        if (PyType_Ready(type) < 0)
+            return NULL;
+    }
+
+    /* Find a superclass linearization that honors the constraints
+       of the explicit lists of bases and the constraints implied by
+       each base class.
+
+       to_merge is a list of lists, where each list is a superclass
+       linearization implied by a base class.  The last element of
+       to_merge is the declared list of bases.
+    */
+
+    bases = type->tp_bases;
+    n = PyTuple_GET_SIZE(bases);
+
+    to_merge = PyList_New(n+1);
+    if (to_merge == NULL)
+        return NULL;
+
+    for (i = 0; i < n; i++) {
+        PyObject *base = PyTuple_GET_ITEM(bases, i);
+        PyObject *parentMRO;
+        if (PyType_Check(base))
+            parentMRO = PySequence_List(
+                ((PyTypeObject*)base)->tp_mro);
+        else
+            parentMRO = classic_mro(base);
+        if (parentMRO == NULL) {
+            Py_DECREF(to_merge);
+            return NULL;
+        }
+
+        PyList_SET_ITEM(to_merge, i, parentMRO);
+    }
+
+    bases_aslist = PySequence_List(bases);
+    if (bases_aslist == NULL) {
+        Py_DECREF(to_merge);
+        return NULL;
+    }
+    /* This is just a basic sanity check. */
+    if (check_duplicates(bases_aslist) < 0) {
+        Py_DECREF(to_merge);
+        Py_DECREF(bases_aslist);
+        return NULL;
+    }
+    PyList_SET_ITEM(to_merge, n, bases_aslist);
+
+    result = Py_BuildValue("[O]", (PyObject *)type);
+    if (result == NULL) {
+        Py_DECREF(to_merge);
+        return NULL;
+    }
+
+    ok = pmerge(result, to_merge);
+    Py_DECREF(to_merge);
+    if (ok < 0) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    return result;
+}
+
+static PyObject *
+mro_external(PyObject *self)
+{
+    PyTypeObject *type = (PyTypeObject *)self;
+
+    return mro_implementation(type);
+}
+
+static int
+mro_internal(PyTypeObject *type)
+{
+    PyObject *mro, *result, *tuple;
+    int checkit = 0;
+
+    if (Py_TYPE(type) == &PyType_Type) {
+        result = mro_implementation(type);
+    }
+    else {
+        static PyObject *mro_str;
+        checkit = 1;
+        mro = lookup_method((PyObject *)type, "mro", &mro_str);
+        if (mro == NULL)
+            return -1;
+        result = PyObject_CallObject(mro, NULL);
+        Py_DECREF(mro);
+    }
+    if (result == NULL)
+        return -1;
+    tuple = PySequence_Tuple(result);
+    Py_DECREF(result);
+    if (tuple == NULL)
+        return -1;
+    if (checkit) {
+        Py_ssize_t i, len;
+        PyObject *cls;
+        PyTypeObject *solid;
+
+        solid = solid_base(type);
+
+        len = PyTuple_GET_SIZE(tuple);
+
+        for (i = 0; i < len; i++) {
+            PyTypeObject *t;
+            cls = PyTuple_GET_ITEM(tuple, i);
+            if (PyClass_Check(cls))
+                continue;
+            else if (!PyType_Check(cls)) {
+                PyErr_Format(PyExc_TypeError,
+                 "mro() returned a non-class ('%.500s')",
+                                 Py_TYPE(cls)->tp_name);
+                Py_DECREF(tuple);
+                return -1;
+            }
+            t = (PyTypeObject*)cls;
+            if (!PyType_IsSubtype(solid, solid_base(t))) {
+                PyErr_Format(PyExc_TypeError,
+             "mro() returned base with unsuitable layout ('%.500s')",
+                                     t->tp_name);
+                        Py_DECREF(tuple);
+                        return -1;
+            }
+        }
+    }
+    type->tp_mro = tuple;
+
+    type_mro_modified(type, type->tp_mro);
+    /* corner case: the old-style super class might have been hidden
+       from the custom MRO */
+    type_mro_modified(type, type->tp_bases);
+
+    PyType_Modified(type);
+
+    return 0;
+}
+
+
+/* Calculate the best base amongst multiple base classes.
+   This is the first one that's on the path to the "solid base". */
+
+static PyTypeObject *
+best_base(PyObject *bases)
+{
+    Py_ssize_t i, n;
+    PyTypeObject *base, *winner, *candidate, *base_i;
+    PyObject *base_proto;
+
+    assert(PyTuple_Check(bases));
+    n = PyTuple_GET_SIZE(bases);
+    assert(n > 0);
+    base = NULL;
+    winner = NULL;
+    for (i = 0; i < n; i++) {
+        base_proto = PyTuple_GET_ITEM(bases, i);
+        if (PyClass_Check(base_proto))
+            continue;
+        if (!PyType_Check(base_proto)) {
+            PyErr_SetString(
+                PyExc_TypeError,
+                "bases must be types");
+            return NULL;
+        }
+        base_i = (PyTypeObject *)base_proto;
+        if (base_i->tp_dict == NULL) {
+            if (PyType_Ready(base_i) < 0)
+                return NULL;
+        }
+        candidate = solid_base(base_i);
+        if (winner == NULL) {
+            winner = candidate;
+            base = base_i;
+        }
+        else if (PyType_IsSubtype(winner, candidate))
+            ;
+        else if (PyType_IsSubtype(candidate, winner)) {
+            winner = candidate;
+            base = base_i;
+        }
+        else {
+            PyErr_SetString(
+                PyExc_TypeError,
+                "multiple bases have "
+                "instance lay-out conflict");
+            return NULL;
+        }
+    }
+    if (base == NULL)
+        PyErr_SetString(PyExc_TypeError,
+            "a new-style class can't have only classic bases");
+    return base;
+}
+
+static int
+extra_ivars(PyTypeObject *type, PyTypeObject *base)
+{
+    size_t t_size = type->tp_basicsize;
+    size_t b_size = base->tp_basicsize;
+
+    assert(t_size >= b_size); /* Else type smaller than base! */
+    if (type->tp_itemsize || base->tp_itemsize) {
+        /* If itemsize is involved, stricter rules */
+        return t_size != b_size ||
+            type->tp_itemsize != base->tp_itemsize;
+    }
+    if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 &&
+        type->tp_weaklistoffset + sizeof(PyObject *) == t_size &&
+        type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+        t_size -= sizeof(PyObject *);
+    if (type->tp_dictoffset && base->tp_dictoffset == 0 &&
+        type->tp_dictoffset + sizeof(PyObject *) == t_size &&
+        type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+        t_size -= sizeof(PyObject *);
+
+    return t_size != b_size;
+}
+
+static PyTypeObject *
+solid_base(PyTypeObject *type)
+{
+    PyTypeObject *base;
+
+    if (type->tp_base)
+        base = solid_base(type->tp_base);
+    else
+        base = &PyBaseObject_Type;
+    if (extra_ivars(type, base))
+        return type;
+    else
+        return base;
+}
+
+static void object_dealloc(PyObject *);
+static int object_init(PyObject *, PyObject *, PyObject *);
+static int update_slot(PyTypeObject *, PyObject *);
+static void fixup_slot_dispatchers(PyTypeObject *);
+
+/*
+ * Helpers for  __dict__ descriptor.  We don't want to expose the dicts
+ * inherited from various builtin types.  The builtin base usually provides
+ * its own __dict__ descriptor, so we use that when we can.
+ */
+static PyTypeObject *
+get_builtin_base_with_dict(PyTypeObject *type)
+{
+    while (type->tp_base != NULL) {
+        if (type->tp_dictoffset != 0 &&
+            !(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+            return type;
+        type = type->tp_base;
+    }
+    return NULL;
+}
+
+static PyObject *
+get_dict_descriptor(PyTypeObject *type)
+{
+    static PyObject *dict_str;
+    PyObject *descr;
+
+    if (dict_str == NULL) {
+        dict_str = PyString_InternFromString("__dict__");
+        if (dict_str == NULL)
+            return NULL;
+    }
+    descr = _PyType_Lookup(type, dict_str);
+    if (descr == NULL || !PyDescr_IsData(descr))
+        return NULL;
+
+    return descr;
+}
+
+static void
+raise_dict_descr_error(PyObject *obj)
+{
+    PyErr_Format(PyExc_TypeError,
+                 "this __dict__ descriptor does not support "
+                 "'%.200s' objects", obj->ob_type->tp_name);
+}
+
+static PyObject *
+subtype_dict(PyObject *obj, void *context)
+{
+    PyObject **dictptr;
+    PyObject *dict;
+    PyTypeObject *base;
+
+    base = get_builtin_base_with_dict(obj->ob_type);
+    if (base != NULL) {
+        descrgetfunc func;
+        PyObject *descr = get_dict_descriptor(base);
+        if (descr == NULL) {
+            raise_dict_descr_error(obj);
+            return NULL;
+        }
+        func = descr->ob_type->tp_descr_get;
+        if (func == NULL) {
+            raise_dict_descr_error(obj);
+            return NULL;
+        }
+        return func(descr, obj, (PyObject *)(obj->ob_type));
+    }
+
+    dictptr = _PyObject_GetDictPtr(obj);
+    if (dictptr == NULL) {
+        PyErr_SetString(PyExc_AttributeError,
+                        "This object has no __dict__");
+        return NULL;
+    }
+    dict = *dictptr;
+    if (dict == NULL)
+        *dictptr = dict = PyDict_New();
+    Py_XINCREF(dict);
+    return dict;
+}
+
+static int
+subtype_setdict(PyObject *obj, PyObject *value, void *context)
+{
+    PyObject **dictptr;
+    PyObject *dict;
+    PyTypeObject *base;
+
+    base = get_builtin_base_with_dict(obj->ob_type);
+    if (base != NULL) {
+        descrsetfunc func;
+        PyObject *descr = get_dict_descriptor(base);
+        if (descr == NULL) {
+            raise_dict_descr_error(obj);
+            return -1;
+        }
+        func = descr->ob_type->tp_descr_set;
+        if (func == NULL) {
+            raise_dict_descr_error(obj);
+            return -1;
+        }
+        return func(descr, obj, value);
+    }
+
+    dictptr = _PyObject_GetDictPtr(obj);
+    if (dictptr == NULL) {
+        PyErr_SetString(PyExc_AttributeError,
+                        "This object has no __dict__");
+        return -1;
+    }
+    if (value != NULL && !PyDict_Check(value)) {
+        PyErr_Format(PyExc_TypeError,
+                     "__dict__ must be set to a dictionary, "
+                     "not a '%.200s'", Py_TYPE(value)->tp_name);
+        return -1;
+    }
+    dict = *dictptr;
+    Py_XINCREF(value);
+    *dictptr = value;
+    Py_XDECREF(dict);
+    return 0;
+}
+
+static PyObject *
+subtype_getweakref(PyObject *obj, void *context)
+{
+    PyObject **weaklistptr;
+    PyObject *result;
+
+    if (Py_TYPE(obj)->tp_weaklistoffset == 0) {
+        PyErr_SetString(PyExc_AttributeError,
+                        "This object has no __weakref__");
+        return NULL;
+    }
+    assert(Py_TYPE(obj)->tp_weaklistoffset > 0);
+    assert(Py_TYPE(obj)->tp_weaklistoffset + sizeof(PyObject *) <=
+           (size_t)(Py_TYPE(obj)->tp_basicsize));
+    weaklistptr = (PyObject **)
+        ((char *)obj + Py_TYPE(obj)->tp_weaklistoffset);
+    if (*weaklistptr == NULL)
+        result = Py_None;
+    else
+        result = *weaklistptr;
+    Py_INCREF(result);
+    return result;
+}
+
+/* Three variants on the subtype_getsets list. */
+
+static PyGetSetDef subtype_getsets_full[] = {
+    {"__dict__", subtype_dict, subtype_setdict,
+     PyDoc_STR("dictionary for instance variables (if defined)")},
+    {"__weakref__", subtype_getweakref, NULL,
+     PyDoc_STR("list of weak references to the object (if defined)")},
+    {0}
+};
+
+static PyGetSetDef subtype_getsets_dict_only[] = {
+    {"__dict__", subtype_dict, subtype_setdict,
+     PyDoc_STR("dictionary for instance variables (if defined)")},
+    {0}
+};
+
+static PyGetSetDef subtype_getsets_weakref_only[] = {
+    {"__weakref__", subtype_getweakref, NULL,
+     PyDoc_STR("list of weak references to the object (if defined)")},
+    {0}
+};
+
+static int
+valid_identifier(PyObject *s)
+{
+    unsigned char *p;
+    Py_ssize_t i, n;
+
+    if (!PyString_Check(s)) {
+        PyErr_Format(PyExc_TypeError,
+                     "__slots__ items must be strings, not '%.200s'",
+                     Py_TYPE(s)->tp_name);
+        return 0;
+    }
+    p = (unsigned char *) PyString_AS_STRING(s);
+    n = PyString_GET_SIZE(s);
+    /* We must reject an empty name.  As a hack, we bump the
+       length to 1 so that the loop will balk on the trailing \0. */
+    if (n == 0)
+        n = 1;
+    for (i = 0; i < n; i++, p++) {
+        if (!(i == 0 ? isalpha(*p) : isalnum(*p)) && *p != '_') {
+            PyErr_SetString(PyExc_TypeError,
+                            "__slots__ must be identifiers");
+            return 0;
+        }
+    }
+    return 1;
+}
+
+#ifdef Py_USING_UNICODE
+/* Replace Unicode objects in slots.  */
+
+static PyObject *
+_unicode_to_string(PyObject *slots, Py_ssize_t nslots)
+{
+    PyObject *tmp = NULL;
+    PyObject *slot_name, *new_name;
+    Py_ssize_t i;
+
+    for (i = 0; i < nslots; i++) {
+        if (PyUnicode_Check(slot_name = PyTuple_GET_ITEM(slots, i))) {
+            if (tmp == NULL) {
+                tmp = PySequence_List(slots);
+                if (tmp == NULL)
+                    return NULL;
+            }
+            new_name = _PyUnicode_AsDefaultEncodedString(slot_name,
+                                                         NULL);
+            if (new_name == NULL) {
+                Py_DECREF(tmp);
+                return NULL;
+            }
+            Py_INCREF(new_name);
+            PyList_SET_ITEM(tmp, i, new_name);
+            Py_DECREF(slot_name);
+        }
+    }
+    if (tmp != NULL) {
+        slots = PyList_AsTuple(tmp);
+        Py_DECREF(tmp);
+    }
+    return slots;
+}
+#endif
+
+/* Forward */
+static int
+object_init(PyObject *self, PyObject *args, PyObject *kwds);
+
+static int
+type_init(PyObject *cls, PyObject *args, PyObject *kwds)
+{
+    int res;
+
+    assert(args != NULL && PyTuple_Check(args));
+    assert(kwds == NULL || PyDict_Check(kwds));
+
+    if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds) != 0) {
+        PyErr_SetString(PyExc_TypeError,
+                        "type.__init__() takes no keyword arguments");
+        return -1;
+    }
+
+    if (args != NULL && PyTuple_Check(args) &&
+        (PyTuple_GET_SIZE(args) != 1 && PyTuple_GET_SIZE(args) != 3)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "type.__init__() takes 1 or 3 arguments");
+        return -1;
+    }
+
+    /* Call object.__init__(self) now. */
+    /* XXX Could call super(type, cls).__init__() but what's the point? */
+    args = PyTuple_GetSlice(args, 0, 0);
+    res = object_init(cls, args, NULL);
+    Py_DECREF(args);
+    return res;
+}
+
+static PyObject *
+type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
+{
+    PyObject *name, *bases, *dict;
+    static char *kwlist[] = {"name", "bases", "dict", 0};
+    PyObject *slots, *tmp, *newslots;
+    PyTypeObject *type, *base, *tmptype, *winner;
+    PyHeapTypeObject *et;
+    PyMemberDef *mp;
+    Py_ssize_t i, nbases, nslots, slotoffset, add_dict, add_weak;
+    int j, may_add_dict, may_add_weak;
+
+    assert(args != NULL && PyTuple_Check(args));
+    assert(kwds == NULL || PyDict_Check(kwds));
+
+    /* Special case: type(x) should return x->ob_type */
+    {
+        const Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+        const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds);
+
+        if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) {
+            PyObject *x = PyTuple_GET_ITEM(args, 0);
+            Py_INCREF(Py_TYPE(x));
+            return (PyObject *) Py_TYPE(x);
+        }
+
+        /* SF bug 475327 -- if that didn't trigger, we need 3
+           arguments. but PyArg_ParseTupleAndKeywords below may give
+           a msg saying type() needs exactly 3. */
+        if (nargs + nkwds != 3) {
+            PyErr_SetString(PyExc_TypeError,
+                            "type() takes 1 or 3 arguments");
+            return NULL;
+        }
+    }
+
+    /* Check arguments: (name, bases, dict) */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:type", kwlist,
+                                     &name,
+                                     &PyTuple_Type, &bases,
+                                     &PyDict_Type, &dict))
+        return NULL;
+
+    /* Determine the proper metatype to deal with this,
+       and check for metatype conflicts while we're at it.
+       Note that if some other metatype wins to contract,
+       it's possible that its instances are not types. */
+    nbases = PyTuple_GET_SIZE(bases);
+    winner = metatype;
+    for (i = 0; i < nbases; i++) {
+        tmp = PyTuple_GET_ITEM(bases, i);
+        tmptype = tmp->ob_type;
+        if (tmptype == &PyClass_Type)
+            continue; /* Special case classic classes */
+        if (PyType_IsSubtype(winner, tmptype))
+            continue;
+        if (PyType_IsSubtype(tmptype, winner)) {
+            winner = tmptype;
+            continue;
+        }
+        PyErr_SetString(PyExc_TypeError,
+                        "metaclass conflict: "
+                        "the metaclass of a derived class "
+                        "must be a (non-strict) subclass "
+                        "of the metaclasses of all its bases");
+        return NULL;
+    }
+    if (winner != metatype) {
+        if (winner->tp_new != type_new) /* Pass it to the winner */
+            return winner->tp_new(winner, args, kwds);
+        metatype = winner;
+    }
+
+    /* Adjust for empty tuple bases */
+    if (nbases == 0) {
+        bases = PyTuple_Pack(1, &PyBaseObject_Type);
+        if (bases == NULL)
+            return NULL;
+        nbases = 1;
+    }
+    else
+        Py_INCREF(bases);
+
+    /* XXX From here until type is allocated, "return NULL" leaks bases! */
+
+    /* Calculate best base, and check that all bases are type objects */
+    base = best_base(bases);
+    if (base == NULL) {
+        Py_DECREF(bases);
+        return NULL;
+    }
+    if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) {
+        PyErr_Format(PyExc_TypeError,
+                     "type '%.100s' is not an acceptable base type",
+                     base->tp_name);
+        Py_DECREF(bases);
+        return NULL;
+    }
+
+    /* Check for a __slots__ sequence variable in dict, and count it */
+    slots = PyDict_GetItemString(dict, "__slots__");
+    nslots = 0;
+    add_dict = 0;
+    add_weak = 0;
+    may_add_dict = base->tp_dictoffset == 0;
+    may_add_weak = base->tp_weaklistoffset == 0 && base->tp_itemsize == 0;
+    if (slots == NULL) {
+        if (may_add_dict) {
+            add_dict++;
+        }
+        if (may_add_weak) {
+            add_weak++;
+        }
+    }
+    else {
+        /* Have slots */
+
+        /* Make it into a tuple */
+        if (PyString_Check(slots) || PyUnicode_Check(slots))
+            slots = PyTuple_Pack(1, slots);
+        else
+            slots = PySequence_Tuple(slots);
+        if (slots == NULL) {
+            Py_DECREF(bases);
+            return NULL;
+        }
+        assert(PyTuple_Check(slots));
+
+        /* Are slots allowed? */
+        nslots = PyTuple_GET_SIZE(slots);
+        if (nslots > 0 && base->tp_itemsize != 0) {
+            PyErr_Format(PyExc_TypeError,
+                         "nonempty __slots__ "
+                         "not supported for subtype of '%s'",
+                         base->tp_name);
+          bad_slots:
+            Py_DECREF(bases);
+            Py_DECREF(slots);
+            return NULL;
+        }
+
+#ifdef Py_USING_UNICODE
+        tmp = _unicode_to_string(slots, nslots);
+        if (tmp == NULL)
+            goto bad_slots;
+        if (tmp != slots) {
+            Py_DECREF(slots);
+            slots = tmp;
+        }
+#endif
+        /* Check for valid slot names and two special cases */
+        for (i = 0; i < nslots; i++) {
+            PyObject *tmp = PyTuple_GET_ITEM(slots, i);
+            char *s;
+            if (!valid_identifier(tmp))
+                goto bad_slots;
+            assert(PyString_Check(tmp));
+            s = PyString_AS_STRING(tmp);
+            if (strcmp(s, "__dict__") == 0) {
+                if (!may_add_dict || add_dict) {
+                    PyErr_SetString(PyExc_TypeError,
+                        "__dict__ slot disallowed: "
+                        "we already got one");
+                    goto bad_slots;
+                }
+                add_dict++;
+            }
+            if (strcmp(s, "__weakref__") == 0) {
+                if (!may_add_weak || add_weak) {
+                    PyErr_SetString(PyExc_TypeError,
+                        "__weakref__ slot disallowed: "
+                        "either we already got one, "
+                        "or __itemsize__ != 0");
+                    goto bad_slots;
+                }
+                add_weak++;
+            }
+        }
+
+        /* Copy slots into a list, mangle names and sort them.
+           Sorted names are needed for __class__ assignment.
+           Convert them back to tuple at the end.
+        */
+        newslots = PyList_New(nslots - add_dict - add_weak);
+        if (newslots == NULL)
+            goto bad_slots;
+        for (i = j = 0; i < nslots; i++) {
+            char *s;
+            tmp = PyTuple_GET_ITEM(slots, i);
+            s = PyString_AS_STRING(tmp);
+            if ((add_dict && strcmp(s, "__dict__") == 0) ||
+                (add_weak && strcmp(s, "__weakref__") == 0))
+                continue;
+            tmp =_Py_Mangle(name, tmp);
+            if (!tmp) {
+                Py_DECREF(newslots);
+                goto bad_slots;
+            }
+            PyList_SET_ITEM(newslots, j, tmp);
+            j++;
+        }
+        assert(j == nslots - add_dict - add_weak);
+        nslots = j;
+        Py_DECREF(slots);
+        if (PyList_Sort(newslots) == -1) {
+            Py_DECREF(bases);
+            Py_DECREF(newslots);
+            return NULL;
+        }
+        slots = PyList_AsTuple(newslots);
+        Py_DECREF(newslots);
+        if (slots == NULL) {
+            Py_DECREF(bases);
+            return NULL;
+        }
+
+        /* Secondary bases may provide weakrefs or dict */
+        if (nbases > 1 &&
+            ((may_add_dict && !add_dict) ||
+             (may_add_weak && !add_weak))) {
+            for (i = 0; i < nbases; i++) {
+                tmp = PyTuple_GET_ITEM(bases, i);
+                if (tmp == (PyObject *)base)
+                    continue; /* Skip primary base */
+                if (PyClass_Check(tmp)) {
+                    /* Classic base class provides both */
+                    if (may_add_dict && !add_dict)
+                        add_dict++;
+                    if (may_add_weak && !add_weak)
+                        add_weak++;
+                    break;
+                }
+                assert(PyType_Check(tmp));
+                tmptype = (PyTypeObject *)tmp;
+                if (may_add_dict && !add_dict &&
+                    tmptype->tp_dictoffset != 0)
+                    add_dict++;
+                if (may_add_weak && !add_weak &&
+                    tmptype->tp_weaklistoffset != 0)
+                    add_weak++;
+                if (may_add_dict && !add_dict)
+                    continue;
+                if (may_add_weak && !add_weak)
+                    continue;
+                /* Nothing more to check */
+                break;
+            }
+        }
+    }
+
+    /* XXX From here until type is safely allocated,
+       "return NULL" may leak slots! */
+
+    /* Allocate the type object */
+    type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots);
+    if (type == NULL) {
+        Py_XDECREF(slots);
+        Py_DECREF(bases);
+        return NULL;
+    }
+
+    /* Keep name and slots alive in the extended type object */
+    et = (PyHeapTypeObject *)type;
+    Py_INCREF(name);
+    et->ht_name = name;
+    et->ht_slots = slots;
+
+    /* Initialize tp_flags */
+    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
+        Py_TPFLAGS_BASETYPE;
+    if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
+        type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+    if (base->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER)
+        type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
+
+    /* It's a new-style number unless it specifically inherits any
+       old-style numeric behavior */
+    if ((base->tp_flags & Py_TPFLAGS_CHECKTYPES) ||
+        (base->tp_as_number == NULL))
+        type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
+
+    /* Initialize essential fields */
+    type->tp_as_number = &et->as_number;
+    type->tp_as_sequence = &et->as_sequence;
+    type->tp_as_mapping = &et->as_mapping;
+    type->tp_as_buffer = &et->as_buffer;
+    type->tp_name = PyString_AS_STRING(name);
+
+    /* Set tp_base and tp_bases */
+    type->tp_bases = bases;
+    Py_INCREF(base);
+    type->tp_base = base;
+
+    /* Initialize tp_dict from passed-in dict */
+    type->tp_dict = dict = PyDict_Copy(dict);
+    if (dict == NULL) {
+        Py_DECREF(type);
+        return NULL;
+    }
+
+    /* Set __module__ in the dict */
+    if (PyDict_GetItemString(dict, "__module__") == NULL) {
+        tmp = PyEval_GetGlobals();
+        if (tmp != NULL) {
+            tmp = PyDict_GetItemString(tmp, "__name__");
+            if (tmp != NULL) {
+                if (PyDict_SetItemString(dict, "__module__",
+                                         tmp) < 0)
+                    return NULL;
+            }
+        }
+    }
+
+    /* Set tp_doc to a copy of dict['__doc__'], if the latter is there
+       and is a string.  The __doc__ accessor will first look for tp_doc;
+       if that fails, it will still look into __dict__.
+    */
+    {
+        PyObject *doc = PyDict_GetItemString(dict, "__doc__");
+        if (doc != NULL && PyString_Check(doc)) {
+            const size_t n = (size_t)PyString_GET_SIZE(doc);
+            char *tp_doc = (char *)PyObject_MALLOC(n+1);
+            if (tp_doc == NULL) {
+                Py_DECREF(type);
+                return NULL;
+            }
+            memcpy(tp_doc, PyString_AS_STRING(doc), n+1);
+            type->tp_doc = tp_doc;
+        }
+    }
+
+    /* Special-case __new__: if it's a plain function,
+       make it a static function */
+    tmp = PyDict_GetItemString(dict, "__new__");
+    if (tmp != NULL && PyFunction_Check(tmp)) {
+        tmp = PyStaticMethod_New(tmp);
+        if (tmp == NULL) {
+            Py_DECREF(type);
+            return NULL;
+        }
+        PyDict_SetItemString(dict, "__new__", tmp);
+        Py_DECREF(tmp);
+    }
+
+    /* Add descriptors for custom slots from __slots__, or for __dict__ */
+    mp = PyHeapType_GET_MEMBERS(et);
+    slotoffset = base->tp_basicsize;
+    if (slots != NULL) {
+        for (i = 0; i < nslots; i++, mp++) {
+            mp->name = PyString_AS_STRING(
+                PyTuple_GET_ITEM(slots, i));
+            mp->type = T_OBJECT_EX;
+            mp->offset = slotoffset;
+
+            /* __dict__ and __weakref__ are already filtered out */
+            assert(strcmp(mp->name, "__dict__") != 0);
+            assert(strcmp(mp->name, "__weakref__") != 0);
+
+            slotoffset += sizeof(PyObject *);
+        }
+    }
+    if (add_dict) {
+        if (base->tp_itemsize)
+            type->tp_dictoffset = -(long)sizeof(PyObject *);
+        else
+            type->tp_dictoffset = slotoffset;
+        slotoffset += sizeof(PyObject *);
+    }
+    if (add_weak) {
+        assert(!base->tp_itemsize);
+        type->tp_weaklistoffset = slotoffset;
+        slotoffset += sizeof(PyObject *);
+    }
+    type->tp_basicsize = slotoffset;
+    type->tp_itemsize = base->tp_itemsize;
+    type->tp_members = PyHeapType_GET_MEMBERS(et);
+
+    if (type->tp_weaklistoffset && type->tp_dictoffset)
+        type->tp_getset = subtype_getsets_full;
+    else if (type->tp_weaklistoffset && !type->tp_dictoffset)
+        type->tp_getset = subtype_getsets_weakref_only;
+    else if (!type->tp_weaklistoffset && type->tp_dictoffset)
+        type->tp_getset = subtype_getsets_dict_only;
+    else
+        type->tp_getset = NULL;
+
+    /* Special case some slots */
+    if (type->tp_dictoffset != 0 || nslots > 0) {
+        if (base->tp_getattr == NULL && base->tp_getattro == NULL)
+            type->tp_getattro = PyObject_GenericGetAttr;
+        if (base->tp_setattr == NULL && base->tp_setattro == NULL)
+            type->tp_setattro = PyObject_GenericSetAttr;
+    }
+    type->tp_dealloc = subtype_dealloc;
+
+    /* Enable GC unless there are really no instance variables possible */
+    if (!(type->tp_basicsize == sizeof(PyObject) &&
+          type->tp_itemsize == 0))
+        type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+
+    /* Always override allocation strategy to use regular heap */
+    type->tp_alloc = PyType_GenericAlloc;
+    if (type->tp_flags & Py_TPFLAGS_HAVE_GC) {
+        type->tp_free = PyObject_GC_Del;
+        type->tp_traverse = subtype_traverse;
+        type->tp_clear = subtype_clear;
+    }
+    else
+        type->tp_free = PyObject_Del;
+
+    /* Initialize the rest */
+    if (PyType_Ready(type) < 0) {
+        Py_DECREF(type);
+        return NULL;
+    }
+
+    /* Put the proper slots in place */
+    fixup_slot_dispatchers(type);
+
+    return (PyObject *)type;
+}
+
+/* Internal API to look for a name through the MRO.
+   This returns a borrowed reference, and doesn't set an exception! */
+PyObject *
+_PyType_Lookup(PyTypeObject *type, PyObject *name)
+{
+    Py_ssize_t i, n;
+    PyObject *mro, *res, *base, *dict;
+    unsigned int h;
+
+    if (MCACHE_CACHEABLE_NAME(name) &&
+        PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) {
+        /* fast path */
+        h = MCACHE_HASH_METHOD(type, name);
+        if (method_cache[h].version == type->tp_version_tag &&
+            method_cache[h].name == name)
+            return method_cache[h].value;
+    }
+
+    /* Look in tp_dict of types in MRO */
+    mro = type->tp_mro;
+
+    /* If mro is NULL, the type is either not yet initialized
+       by PyType_Ready(), or already cleared by type_clear().
+       Either way the safest thing to do is to return NULL. */
+    if (mro == NULL)
+        return NULL;
+
+    res = NULL;
+    assert(PyTuple_Check(mro));
+    n = PyTuple_GET_SIZE(mro);
+    for (i = 0; i < n; i++) {
+        base = PyTuple_GET_ITEM(mro, i);
+        if (PyClass_Check(base))
+            dict = ((PyClassObject *)base)->cl_dict;
+        else {
+            assert(PyType_Check(base));
+            dict = ((PyTypeObject *)base)->tp_dict;
+        }
+        assert(dict && PyDict_Check(dict));
+        res = PyDict_GetItem(dict, name);
+        if (res != NULL)
+            break;
+    }
+
+    if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) {
+        h = MCACHE_HASH_METHOD(type, name);
+        method_cache[h].version = type->tp_version_tag;
+        method_cache[h].value = res;  /* borrowed */
+        Py_INCREF(name);
+        Py_DECREF(method_cache[h].name);
+        method_cache[h].name = name;
+    }
+    return res;
+}
+
+/* This is similar to PyObject_GenericGetAttr(),
+   but uses _PyType_Lookup() instead of just looking in type->tp_dict. */
+static PyObject *
+type_getattro(PyTypeObject *type, PyObject *name)
+{
+    PyTypeObject *metatype = Py_TYPE(type);
+    PyObject *meta_attribute, *attribute;
+    descrgetfunc meta_get;
+
+    if (!PyString_Check(name)) {
+        PyErr_Format(PyExc_TypeError,
+                     "attribute name must be string, not '%.200s'",
+                     name->ob_type->tp_name);
+        return NULL;
+    }
+
+    /* Initialize this type (we'll assume the metatype is initialized) */
+    if (type->tp_dict == NULL) {
+        if (PyType_Ready(type) < 0)
+            return NULL;
+    }
+
+    /* No readable descriptor found yet */
+    meta_get = NULL;
+
+    /* Look for the attribute in the metatype */
+    meta_attribute = _PyType_Lookup(metatype, name);
+
+    if (meta_attribute != NULL) {
+        meta_get = Py_TYPE(meta_attribute)->tp_descr_get;
+
+        if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {
+            /* Data descriptors implement tp_descr_set to intercept
+             * writes. Assume the attribute is not overridden in
+             * type's tp_dict (and bases): call the descriptor now.
+             */
+            return meta_get(meta_attribute, (PyObject *)type,
+                            (PyObject *)metatype);
+        }
+        Py_INCREF(meta_attribute);
+    }
+
+    /* No data descriptor found on metatype. Look in tp_dict of this
+     * type and its bases */
+    attribute = _PyType_Lookup(type, name);
+    if (attribute != NULL) {
+        /* Implement descriptor functionality, if any */
+        descrgetfunc local_get = Py_TYPE(attribute)->tp_descr_get;
+
+        Py_XDECREF(meta_attribute);
+
+        if (local_get != NULL) {
+            /* NULL 2nd argument indicates the descriptor was
+             * found on the target object itself (or a base)  */
+            return local_get(attribute, (PyObject *)NULL,
+                             (PyObject *)type);
+        }
+
+        Py_INCREF(attribute);
+        return attribute;
+    }
+
+    /* No attribute found in local __dict__ (or bases): use the
+     * descriptor from the metatype, if any */
+    if (meta_get != NULL) {
+        PyObject *res;
+        res = meta_get(meta_attribute, (PyObject *)type,
+                       (PyObject *)metatype);
+        Py_DECREF(meta_attribute);
+        return res;
+    }
+
+    /* If an ordinary attribute was found on the metatype, return it now */
+    if (meta_attribute != NULL) {
+        return meta_attribute;
+    }
+
+    /* Give up */
+    PyErr_Format(PyExc_AttributeError,
+                     "type object '%.50s' has no attribute '%.400s'",
+                     type->tp_name, PyString_AS_STRING(name));
+    return NULL;
+}
+
+static int
+type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
+{
+    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+        PyErr_Format(
+            PyExc_TypeError,
+            "can't set attributes of built-in/extension type '%s'",
+            type->tp_name);
+        return -1;
+    }
+    if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0)
+        return -1;
+    return update_slot(type, name);
+}
+
+static void
+type_dealloc(PyTypeObject *type)
+{
+    PyHeapTypeObject *et;
+
+    /* Assert this is a heap-allocated type object */
+    assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+    _PyObject_GC_UNTRACK(type);
+    PyObject_ClearWeakRefs((PyObject *)type);
+    et = (PyHeapTypeObject *)type;
+    Py_XDECREF(type->tp_base);
+    Py_XDECREF(type->tp_dict);
+    Py_XDECREF(type->tp_bases);
+    Py_XDECREF(type->tp_mro);
+    Py_XDECREF(type->tp_cache);
+    Py_XDECREF(type->tp_subclasses);
+    /* A type's tp_doc is heap allocated, unlike the tp_doc slots
+     * of most other objects.  It's okay to cast it to char *.
+     */
+    PyObject_Free((char *)type->tp_doc);
+    Py_XDECREF(et->ht_name);
+    Py_XDECREF(et->ht_slots);
+    Py_TYPE(type)->tp_free((PyObject *)type);
+}
+
+static PyObject *
+type_subclasses(PyTypeObject *type, PyObject *args_ignored)
+{
+    PyObject *list, *raw, *ref;
+    Py_ssize_t i, n;
+
+    list = PyList_New(0);
+    if (list == NULL)
+        return NULL;
+    raw = type->tp_subclasses;
+    if (raw == NULL)
+        return list;
+    assert(PyList_Check(raw));
+    n = PyList_GET_SIZE(raw);
+    for (i = 0; i < n; i++) {
+        ref = PyList_GET_ITEM(raw, i);
+        assert(PyWeakref_CheckRef(ref));
+        ref = PyWeakref_GET_OBJECT(ref);
+        if (ref != Py_None) {
+            if (PyList_Append(list, ref) < 0) {
+                Py_DECREF(list);
+                return NULL;
+            }
+        }
+    }
+    return list;
+}
+
+static PyMethodDef type_methods[] = {
+    {"mro", (PyCFunction)mro_external, METH_NOARGS,
+     PyDoc_STR("mro() -> list\nreturn a type's method resolution order")},
+    {"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS,
+     PyDoc_STR("__subclasses__() -> list of immediate subclasses")},
+    {"__instancecheck__", type___instancecheck__, METH_O,
+     PyDoc_STR("__instancecheck__() -> bool\ncheck if an object is an instance")},
+    {"__subclasscheck__", type___subclasscheck__, METH_O,
+     PyDoc_STR("__subclasscheck__() -> bool\ncheck if a class is a subclass")},
+    {0}
+};
+
+PyDoc_STRVAR(type_doc,
+"type(object) -> the object's type\n"
+"type(name, bases, dict) -> a new type");
+
+static int
+type_traverse(PyTypeObject *type, visitproc visit, void *arg)
+{
+    /* Because of type_is_gc(), the collector only calls this
+       for heaptypes. */
+    assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+    Py_VISIT(type->tp_dict);
+    Py_VISIT(type->tp_cache);
+    Py_VISIT(type->tp_mro);
+    Py_VISIT(type->tp_bases);
+    Py_VISIT(type->tp_base);
+
+    /* There's no need to visit type->tp_subclasses or
+       ((PyHeapTypeObject *)type)->ht_slots, because they can't be involved
+       in cycles; tp_subclasses is a list of weak references,
+       and slots is a tuple of strings. */
+
+    return 0;
+}
+
+static int
+type_clear(PyTypeObject *type)
+{
+    /* Because of type_is_gc(), the collector only calls this
+       for heaptypes. */
+    assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+    /* We need to invalidate the method cache carefully before clearing
+       the dict, so that other objects caught in a reference cycle
+       don't start calling destroyed methods.
+
+       Otherwise, the only field we need to clear is tp_mro, which is
+       part of a hard cycle (its first element is the class itself) that
+       won't be broken otherwise (it's a tuple and tuples don't have a
+       tp_clear handler).  None of the other fields need to be
+       cleared, and here's why:
+
+       tp_cache:
+           Not used; if it were, it would be a dict.
+
+       tp_bases, tp_base:
+           If these are involved in a cycle, there must be at least
+           one other, mutable object in the cycle, e.g. a base
+           class's dict; the cycle will be broken that way.
+
+       tp_subclasses:
+           A list of weak references can't be part of a cycle; and
+           lists have their own tp_clear.
+
+       slots (in PyHeapTypeObject):
+           A tuple of strings can't be part of a cycle.
+    */
+
+    PyType_Modified(type);
+    if (type->tp_dict)
+        PyDict_Clear(type->tp_dict);
+    Py_CLEAR(type->tp_mro);
+
+    return 0;
+}
+
+static int
+type_is_gc(PyTypeObject *type)
+{
+    return type->tp_flags & Py_TPFLAGS_HEAPTYPE;
+}
+
+PyTypeObject PyType_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "type",                                     /* tp_name */
+    sizeof(PyHeapTypeObject),                   /* tp_basicsize */
+    sizeof(PyMemberDef),                        /* tp_itemsize */
+    (destructor)type_dealloc,                   /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                  /* tp_compare */
+    (reprfunc)type_repr,                        /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)_Py_HashPointer,                  /* tp_hash */
+    (ternaryfunc)type_call,                     /* tp_call */
+    0,                                          /* tp_str */
+    (getattrofunc)type_getattro,                /* tp_getattro */
+    (setattrofunc)type_setattro,                /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS,         /* tp_flags */
+    type_doc,                                   /* tp_doc */
+    (traverseproc)type_traverse,                /* tp_traverse */
+    (inquiry)type_clear,                        /* tp_clear */
+    type_richcompare,                                           /* tp_richcompare */
+    offsetof(PyTypeObject, tp_weaklist),        /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    type_methods,                               /* tp_methods */
+    type_members,                               /* tp_members */
+    type_getsets,                               /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    offsetof(PyTypeObject, tp_dict),            /* tp_dictoffset */
+    type_init,                                  /* tp_init */
+    0,                                          /* tp_alloc */
+    type_new,                                   /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+    (inquiry)type_is_gc,                        /* tp_is_gc */
+};
+
+
+/* The base type of all types (eventually)... except itself. */
+
+/* You may wonder why object.__new__() only complains about arguments
+   when object.__init__() is not overridden, and vice versa.
+
+   Consider the use cases:
+
+   1. When neither is overridden, we want to hear complaints about
+      excess (i.e., any) arguments, since their presence could
+      indicate there's a bug.
+
+   2. When defining an Immutable type, we are likely to override only
+      __new__(), since __init__() is called too late to initialize an
+      Immutable object.  Since __new__() defines the signature for the
+      type, it would be a pain to have to override __init__() just to
+      stop it from complaining about excess arguments.
+
+   3. When defining a Mutable type, we are likely to override only
+      __init__().  So here the converse reasoning applies: we don't
+      want to have to override __new__() just to stop it from
+      complaining.
+
+   4. When __init__() is overridden, and the subclass __init__() calls
+      object.__init__(), the latter should complain about excess
+      arguments; ditto for __new__().
+
+   Use cases 2 and 3 make it unattractive to unconditionally check for
+   excess arguments.  The best solution that addresses all four use
+   cases is as follows: __init__() complains about excess arguments
+   unless __new__() is overridden and __init__() is not overridden
+   (IOW, if __init__() is overridden or __new__() is not overridden);
+   symmetrically, __new__() complains about excess arguments unless
+   __init__() is overridden and __new__() is not overridden
+   (IOW, if __new__() is overridden or __init__() is not overridden).
+
+   However, for backwards compatibility, this breaks too much code.
+   Therefore, in 2.6, we'll *warn* about excess arguments when both
+   methods are overridden; for all other cases we'll use the above
+   rules.
+
+*/
+
+/* Forward */
+static PyObject *
+object_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static int
+excess_args(PyObject *args, PyObject *kwds)
+{
+    return PyTuple_GET_SIZE(args) ||
+        (kwds && PyDict_Check(kwds) && PyDict_Size(kwds));
+}
+
+static int
+object_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int err = 0;
+    if (excess_args(args, kwds)) {
+        PyTypeObject *type = Py_TYPE(self);
+        if (type->tp_init != object_init &&
+            type->tp_new != object_new)
+        {
+            err = PyErr_WarnEx(PyExc_DeprecationWarning,
+                       "object.__init__() takes no parameters",
+                       1);
+        }
+        else if (type->tp_init != object_init ||
+                 type->tp_new == object_new)
+        {
+            PyErr_SetString(PyExc_TypeError,
+                "object.__init__() takes no parameters");
+            err = -1;
+        }
+    }
+    return err;
+}
+
+static PyObject *
+object_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    int err = 0;
+    if (excess_args(args, kwds)) {
+        if (type->tp_new != object_new &&
+            type->tp_init != object_init)
+        {
+            err = PyErr_WarnEx(PyExc_DeprecationWarning,
+                       "object() takes no parameters",
+                       1);
+        }
+        else if (type->tp_new != object_new ||
+                 type->tp_init == object_init)
+        {
+            PyErr_SetString(PyExc_TypeError,
+                "object() takes no parameters");
+            err = -1;
+        }
+    }
+    if (err < 0)
+        return NULL;
+
+    if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) {
+        static PyObject *comma = NULL;
+        PyObject *abstract_methods = NULL;
+        PyObject *builtins;
+        PyObject *sorted;
+        PyObject *sorted_methods = NULL;
+        PyObject *joined = NULL;
+        const char *joined_str;
+
+        /* Compute ", ".join(sorted(type.__abstractmethods__))
+           into joined. */
+        abstract_methods = type_abstractmethods(type, NULL);
+        if (abstract_methods == NULL)
+            goto error;
+        builtins = PyEval_GetBuiltins();
+        if (builtins == NULL)
+            goto error;
+        sorted = PyDict_GetItemString(builtins, "sorted");
+        if (sorted == NULL)
+            goto error;
+        sorted_methods = PyObject_CallFunctionObjArgs(sorted,
+                                                      abstract_methods,
+                                                      NULL);
+        if (sorted_methods == NULL)
+            goto error;
+        if (comma == NULL) {
+            comma = PyString_InternFromString(", ");
+            if (comma == NULL)
+                goto error;
+        }
+        joined = PyObject_CallMethod(comma, "join",
+                                     "O",  sorted_methods);
+        if (joined == NULL)
+            goto error;
+        joined_str = PyString_AsString(joined);
+        if (joined_str == NULL)
+            goto error;
+
+        PyErr_Format(PyExc_TypeError,
+                     "Can't instantiate abstract class %s "
+                     "with abstract methods %s",
+                     type->tp_name,
+                     joined_str);
+    error:
+        Py_XDECREF(joined);
+        Py_XDECREF(sorted_methods);
+        Py_XDECREF(abstract_methods);
+        return NULL;
+    }
+    return type->tp_alloc(type, 0);
+}
+
+static void
+object_dealloc(PyObject *self)
+{
+    Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject *
+object_repr(PyObject *self)
+{
+    PyTypeObject *type;
+    PyObject *mod, *name, *rtn;
+
+    type = Py_TYPE(self);
+    mod = type_module(type, NULL);
+    if (mod == NULL)
+        PyErr_Clear();
+    else if (!PyString_Check(mod)) {
+        Py_DECREF(mod);
+        mod = NULL;
+    }
+    name = type_name(type, NULL);
+    if (name == NULL) {
+        Py_XDECREF(mod);
+        return NULL;
+    }
+    if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__"))
+        rtn = PyString_FromFormat("<%s.%s object at %p>",
+                                  PyString_AS_STRING(mod),
+                                  PyString_AS_STRING(name),
+                                  self);
+    else
+        rtn = PyString_FromFormat("<%s object at %p>",
+                                  type->tp_name, self);
+    Py_XDECREF(mod);
+    Py_DECREF(name);
+    return rtn;
+}
+
+static PyObject *
+object_str(PyObject *self)
+{
+    unaryfunc f;
+
+    f = Py_TYPE(self)->tp_repr;
+    if (f == NULL)
+        f = object_repr;
+    return f(self);
+}
+
+static PyObject *
+object_get_class(PyObject *self, void *closure)
+{
+    Py_INCREF(Py_TYPE(self));
+    return (PyObject *)(Py_TYPE(self));
+}
+
+static int
+equiv_structs(PyTypeObject *a, PyTypeObject *b)
+{
+    return a == b ||
+           (a != NULL &&
+        b != NULL &&
+        a->tp_basicsize == b->tp_basicsize &&
+        a->tp_itemsize == b->tp_itemsize &&
+        a->tp_dictoffset == b->tp_dictoffset &&
+        a->tp_weaklistoffset == b->tp_weaklistoffset &&
+        ((a->tp_flags & Py_TPFLAGS_HAVE_GC) ==
+         (b->tp_flags & Py_TPFLAGS_HAVE_GC)));
+}
+
+static int
+same_slots_added(PyTypeObject *a, PyTypeObject *b)
+{
+    PyTypeObject *base = a->tp_base;
+    Py_ssize_t size;
+    PyObject *slots_a, *slots_b;
+
+    assert(base == b->tp_base);
+    size = base->tp_basicsize;
+    if (a->tp_dictoffset == size && b->tp_dictoffset == size)
+        size += sizeof(PyObject *);
+    if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size)
+        size += sizeof(PyObject *);
+
+    /* Check slots compliance */
+    slots_a = ((PyHeapTypeObject *)a)->ht_slots;
+    slots_b = ((PyHeapTypeObject *)b)->ht_slots;
+    if (slots_a && slots_b) {
+        if (PyObject_Compare(slots_a, slots_b) != 0)
+            return 0;
+        size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a);
+    }
+    return size == a->tp_basicsize && size == b->tp_basicsize;
+}
+
+static int
+compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
+{
+    PyTypeObject *newbase, *oldbase;
+
+    if (newto->tp_dealloc != oldto->tp_dealloc ||
+        newto->tp_free != oldto->tp_free)
+    {
+        PyErr_Format(PyExc_TypeError,
+                     "%s assignment: "
+                     "'%s' deallocator differs from '%s'",
+                     attr,
+                     newto->tp_name,
+                     oldto->tp_name);
+        return 0;
+    }
+    newbase = newto;
+    oldbase = oldto;
+    while (equiv_structs(newbase, newbase->tp_base))
+        newbase = newbase->tp_base;
+    while (equiv_structs(oldbase, oldbase->tp_base))
+        oldbase = oldbase->tp_base;
+    if (newbase != oldbase &&
+        (newbase->tp_base != oldbase->tp_base ||
+         !same_slots_added(newbase, oldbase))) {
+        PyErr_Format(PyExc_TypeError,
+                     "%s assignment: "
+                     "'%s' object layout differs from '%s'",
+                     attr,
+                     newto->tp_name,
+                     oldto->tp_name);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int
+object_set_class(PyObject *self, PyObject *value, void *closure)
+{
+    PyTypeObject *oldto = Py_TYPE(self);
+    PyTypeObject *newto;
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "can't delete __class__ attribute");
+        return -1;
+    }
+    if (!PyType_Check(value)) {
+        PyErr_Format(PyExc_TypeError,
+          "__class__ must be set to new-style class, not '%s' object",
+          Py_TYPE(value)->tp_name);
+        return -1;
+    }
+    newto = (PyTypeObject *)value;
+    if (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) ||
+        !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE))
+    {
+        PyErr_Format(PyExc_TypeError,
+                     "__class__ assignment: only for heap types");
+        return -1;
+    }
+    if (compatible_for_assignment(newto, oldto, "__class__")) {
+        Py_INCREF(newto);
+        Py_TYPE(self) = newto;
+        Py_DECREF(oldto);
+        return 0;
+    }
+    else {
+        return -1;
+    }
+}
+
+static PyGetSetDef object_getsets[] = {
+    {"__class__", object_get_class, object_set_class,
+     PyDoc_STR("the object's class")},
+    {0}
+};
+
+
+/* Stuff to implement __reduce_ex__ for pickle protocols >= 2.
+   We fall back to helpers in copy_reg for:
+   - pickle protocols < 2
+   - calculating the list of slot names (done only once per class)
+   - the __newobj__ function (which is used as a token but never called)
+*/
+
+static PyObject *
+import_copyreg(void)
+{
+    static PyObject *copyreg_str;
+
+    if (!copyreg_str) {
+        copyreg_str = PyString_InternFromString("copy_reg");
+        if (copyreg_str == NULL)
+            return NULL;
+    }
+
+    return PyImport_Import(copyreg_str);
+}
+
+static PyObject *
+slotnames(PyObject *cls)
+{
+    PyObject *clsdict;
+    PyObject *copyreg;
+    PyObject *slotnames;
+
+    if (!PyType_Check(cls)) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
+    clsdict = ((PyTypeObject *)cls)->tp_dict;
+    slotnames = PyDict_GetItemString(clsdict, "__slotnames__");
+    if (slotnames != NULL && PyList_Check(slotnames)) {
+        Py_INCREF(slotnames);
+        return slotnames;
+    }
+
+    copyreg = import_copyreg();
+    if (copyreg == NULL)
+        return NULL;
+
+    slotnames = PyObject_CallMethod(copyreg, "_slotnames", "O", cls);
+    Py_DECREF(copyreg);
+    if (slotnames != NULL &&
+        slotnames != Py_None &&
+        !PyList_Check(slotnames))
+    {
+        PyErr_SetString(PyExc_TypeError,
+            "copy_reg._slotnames didn't return a list or None");
+        Py_DECREF(slotnames);
+        slotnames = NULL;
+    }
+
+    return slotnames;
+}
+
+static PyObject *
+reduce_2(PyObject *obj)
+{
+    PyObject *cls, *getnewargs;
+    PyObject *args = NULL, *args2 = NULL;
+    PyObject *getstate = NULL, *state = NULL, *names = NULL;
+    PyObject *slots = NULL, *listitems = NULL, *dictitems = NULL;
+    PyObject *copyreg = NULL, *newobj = NULL, *res = NULL;
+    Py_ssize_t i, n;
+
+    cls = PyObject_GetAttrString(obj, "__class__");
+    if (cls == NULL)
+        return NULL;
+
+    getnewargs = PyObject_GetAttrString(obj, "__getnewargs__");
+    if (getnewargs != NULL) {
+        args = PyObject_CallObject(getnewargs, NULL);
+        Py_DECREF(getnewargs);
+        if (args != NULL && !PyTuple_Check(args)) {
+            PyErr_Format(PyExc_TypeError,
+                "__getnewargs__ should return a tuple, "
+                "not '%.200s'", Py_TYPE(args)->tp_name);
+            goto end;
+        }
+    }
+    else {
+        PyErr_Clear();
+        args = PyTuple_New(0);
+    }
+    if (args == NULL)
+        goto end;
+
+    getstate = PyObject_GetAttrString(obj, "__getstate__");
+    if (getstate != NULL) {
+        state = PyObject_CallObject(getstate, NULL);
+        Py_DECREF(getstate);
+        if (state == NULL)
+            goto end;
+    }
+    else {
+        PyErr_Clear();
+        state = PyObject_GetAttrString(obj, "__dict__");
+        if (state == NULL) {
+            PyErr_Clear();
+            state = Py_None;
+            Py_INCREF(state);
+        }
+        names = slotnames(cls);
+        if (names == NULL)
+            goto end;
+        if (names != Py_None) {
+            assert(PyList_Check(names));
+            slots = PyDict_New();
+            if (slots == NULL)
+                goto end;
+            n = 0;
+            /* Can't pre-compute the list size; the list
+               is stored on the class so accessible to other
+               threads, which may be run by DECREF */
+            for (i = 0; i < PyList_GET_SIZE(names); i++) {
+                PyObject *name, *value;
+                name = PyList_GET_ITEM(names, i);
+                value = PyObject_GetAttr(obj, name);
+                if (value == NULL)
+                    PyErr_Clear();
+                else {
+                    int err = PyDict_SetItem(slots, name,
+                                             value);
+                    Py_DECREF(value);
+                    if (err)
+                        goto end;
+                    n++;
+                }
+            }
+            if (n) {
+                state = Py_BuildValue("(NO)", state, slots);
+                if (state == NULL)
+                    goto end;
+            }
+        }
+    }
+
+    if (!PyList_Check(obj)) {
+        listitems = Py_None;
+        Py_INCREF(listitems);
+    }
+    else {
+        listitems = PyObject_GetIter(obj);
+        if (listitems == NULL)
+            goto end;
+    }
+
+    if (!PyDict_Check(obj)) {
+        dictitems = Py_None;
+        Py_INCREF(dictitems);
+    }
+    else {
+        dictitems = PyObject_CallMethod(obj, "iteritems", "");
+        if (dictitems == NULL)
+            goto end;
+    }
+
+    copyreg = import_copyreg();
+    if (copyreg == NULL)
+        goto end;
+    newobj = PyObject_GetAttrString(copyreg, "__newobj__");
+    if (newobj == NULL)
+        goto end;
+
+    n = PyTuple_GET_SIZE(args);
+    args2 = PyTuple_New(n+1);
+    if (args2 == NULL)
+        goto end;
+    PyTuple_SET_ITEM(args2, 0, cls);
+    cls = NULL;
+    for (i = 0; i < n; i++) {
+        PyObject *v = PyTuple_GET_ITEM(args, i);
+        Py_INCREF(v);
+        PyTuple_SET_ITEM(args2, i+1, v);
+    }
+
+    res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems);
+
+  end:
+    Py_XDECREF(cls);
+    Py_XDECREF(args);
+    Py_XDECREF(args2);
+    Py_XDECREF(slots);
+    Py_XDECREF(state);
+    Py_XDECREF(names);
+    Py_XDECREF(listitems);
+    Py_XDECREF(dictitems);
+    Py_XDECREF(copyreg);
+    Py_XDECREF(newobj);
+    return res;
+}
+
+/*
+ * There were two problems when object.__reduce__ and object.__reduce_ex__
+ * were implemented in the same function:
+ *  - trying to pickle an object with a custom __reduce__ method that
+ *    fell back to object.__reduce__ in certain circumstances led to
+ *    infinite recursion at Python level and eventual RuntimeError.
+ *  - Pickling objects that lied about their type by overwriting the
+ *    __class__ descriptor could lead to infinite recursion at C level
+ *    and eventual segfault.
+ *
+ * Because of backwards compatibility, the two methods still have to
+ * behave in the same way, even if this is not required by the pickle
+ * protocol. This common functionality was moved to the _common_reduce
+ * function.
+ */
+static PyObject *
+_common_reduce(PyObject *self, int proto)
+{
+    PyObject *copyreg, *res;
+
+    if (proto >= 2)
+        return reduce_2(self);
+
+    copyreg = import_copyreg();
+    if (!copyreg)
+        return NULL;
+
+    res = PyEval_CallMethod(copyreg, "_reduce_ex", "(Oi)", self, proto);
+    Py_DECREF(copyreg);
+
+    return res;
+}
+
+static PyObject *
+object_reduce(PyObject *self, PyObject *args)
+{
+    int proto = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:__reduce__", &proto))
+        return NULL;
+
+    return _common_reduce(self, proto);
+}
+
+static PyObject *
+object_reduce_ex(PyObject *self, PyObject *args)
+{
+    PyObject *reduce, *res;
+    int proto = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
+        return NULL;
+
+    reduce = PyObject_GetAttrString(self, "__reduce__");
+    if (reduce == NULL)
+        PyErr_Clear();
+    else {
+        PyObject *cls, *clsreduce, *objreduce;
+        int override;
+        cls = PyObject_GetAttrString(self, "__class__");
+        if (cls == NULL) {
+            Py_DECREF(reduce);
+            return NULL;
+        }
+        clsreduce = PyObject_GetAttrString(cls, "__reduce__");
+        Py_DECREF(cls);
+        if (clsreduce == NULL) {
+            Py_DECREF(reduce);
+            return NULL;
+        }
+        objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict,
+                                         "__reduce__");
+        override = (clsreduce != objreduce);
+        Py_DECREF(clsreduce);
+        if (override) {
+            res = PyObject_CallObject(reduce, NULL);
+            Py_DECREF(reduce);
+            return res;
+        }
+        else
+            Py_DECREF(reduce);
+    }
+
+    return _common_reduce(self, proto);
+}
+
+static PyObject *
+object_subclasshook(PyObject *cls, PyObject *args)
+{
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+PyDoc_STRVAR(object_subclasshook_doc,
+"Abstract classes can override this to customize issubclass().\n"
+"\n"
+"This is invoked early on by abc.ABCMeta.__subclasscheck__().\n"
+"It should return True, False or NotImplemented.  If it returns\n"
+"NotImplemented, the normal algorithm is used.  Otherwise, it\n"
+"overrides the normal algorithm (and the outcome is cached).\n");
+
+/*
+   from PEP 3101, this code implements:
+
+   class object:
+       def __format__(self, format_spec):
+       if isinstance(format_spec, str):
+           return format(str(self), format_spec)
+       elif isinstance(format_spec, unicode):
+           return format(unicode(self), format_spec)
+*/
+static PyObject *
+object_format(PyObject *self, PyObject *args)
+{
+    PyObject *format_spec;
+    PyObject *self_as_str = NULL;
+    PyObject *result = NULL;
+    Py_ssize_t format_len;
+
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+        return NULL;
+#ifdef Py_USING_UNICODE
+    if (PyUnicode_Check(format_spec)) {
+        format_len = PyUnicode_GET_SIZE(format_spec);
+        self_as_str = PyObject_Unicode(self);
+    } else if (PyString_Check(format_spec)) {
+#else
+    if (PyString_Check(format_spec)) {
+#endif
+        format_len = PyString_GET_SIZE(format_spec);
+        self_as_str = PyObject_Str(self);
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+                 "argument to __format__ must be unicode or str");
+        return NULL;
+    }
+
+    if (self_as_str != NULL) {
+        /* Issue 7994: If we're converting to a string, we
+           should reject format specifications */
+        if (format_len > 0) {
+            if (PyErr_WarnEx(PyExc_PendingDeprecationWarning,
+             "object.__format__ with a non-empty format "
+             "string is deprecated", 1) < 0) {
+                goto done;
+            }
+            /* Eventually this will become an error:
+            PyErr_Format(PyExc_TypeError,
+               "non-empty format string passed to object.__format__");
+            goto done;
+            */
+        }
+        result = PyObject_Format(self_as_str, format_spec);
+    }
+
+done:
+    Py_XDECREF(self_as_str);
+
+    return result;
+}
+
+static PyObject *
+object_sizeof(PyObject *self, PyObject *args)
+{
+    Py_ssize_t res, isize;
+
+    res = 0;
+    isize = self->ob_type->tp_itemsize;
+    if (isize > 0)
+        res = self->ob_type->ob_size * isize;
+    res += self->ob_type->tp_basicsize;
+
+    return PyInt_FromSsize_t(res);
+}
+
+static PyMethodDef object_methods[] = {
+    {"__reduce_ex__", object_reduce_ex, METH_VARARGS,
+     PyDoc_STR("helper for pickle")},
+    {"__reduce__", object_reduce, METH_VARARGS,
+     PyDoc_STR("helper for pickle")},
+    {"__subclasshook__", object_subclasshook, METH_CLASS | METH_VARARGS,
+     object_subclasshook_doc},
+    {"__format__", object_format, METH_VARARGS,
+     PyDoc_STR("default object formatter")},
+    {"__sizeof__", object_sizeof, METH_NOARGS,
+     PyDoc_STR("__sizeof__() -> int\nsize of object in memory, in bytes")},
+    {0}
+};
+
+
+PyTypeObject PyBaseObject_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "object",                                   /* tp_name */
+    sizeof(PyObject),                           /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    object_dealloc,                             /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    object_repr,                                /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    (hashfunc)_Py_HashPointer,                  /* tp_hash */
+    0,                                          /* tp_call */
+    object_str,                                 /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    PyObject_GenericSetAttr,                    /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    PyDoc_STR("The most base type"),            /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    object_methods,                             /* tp_methods */
+    0,                                          /* tp_members */
+    object_getsets,                             /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    object_init,                                /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    object_new,                                 /* tp_new */
+    PyObject_Del,                               /* tp_free */
+};
+
+
+/* Initialize the __dict__ in a type object */
+
+static int
+add_methods(PyTypeObject *type, PyMethodDef *meth)
+{
+    PyObject *dict = type->tp_dict;
+
+    for (; meth->ml_name != NULL; meth++) {
+        PyObject *descr;
+        int err;
+        if (PyDict_GetItemString(dict, meth->ml_name) &&
+            !(meth->ml_flags & METH_COEXIST))
+                continue;
+        if (meth->ml_flags & METH_CLASS) {
+            if (meth->ml_flags & METH_STATIC) {
+                PyErr_SetString(PyExc_ValueError,
+                     "method cannot be both class and static");
+                return -1;
+            }
+            descr = PyDescr_NewClassMethod(type, meth);
+        }
+        else if (meth->ml_flags & METH_STATIC) {
+            PyObject *cfunc = PyCFunction_New(meth, NULL);
+            if (cfunc == NULL)
+                return -1;
+            descr = PyStaticMethod_New(cfunc);
+            Py_DECREF(cfunc);
+        }
+        else {
+            descr = PyDescr_NewMethod(type, meth);
+        }
+        if (descr == NULL)
+            return -1;
+        err = PyDict_SetItemString(dict, meth->ml_name, descr);
+        Py_DECREF(descr);
+        if (err < 0)
+            return -1;
+    }
+    return 0;
+}
+
+static int
+add_members(PyTypeObject *type, PyMemberDef *memb)
+{
+    PyObject *dict = type->tp_dict;
+
+    for (; memb->name != NULL; memb++) {
+        PyObject *descr;
+        if (PyDict_GetItemString(dict, memb->name))
+            continue;
+        descr = PyDescr_NewMember(type, memb);
+        if (descr == NULL)
+            return -1;
+        if (PyDict_SetItemString(dict, memb->name, descr) < 0)
+            return -1;
+        Py_DECREF(descr);
+    }
+    return 0;
+}
+
+static int
+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
+{
+    PyObject *dict = type->tp_dict;
+
+    for (; gsp->name != NULL; gsp++) {
+        PyObject *descr;
+        if (PyDict_GetItemString(dict, gsp->name))
+            continue;
+        descr = PyDescr_NewGetSet(type, gsp);
+
+        if (descr == NULL)
+            return -1;
+        if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
+            return -1;
+        Py_DECREF(descr);
+    }
+    return 0;
+}
+
+#define BUFFER_FLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER)
+
+static void
+inherit_special(PyTypeObject *type, PyTypeObject *base)
+{
+    Py_ssize_t oldsize, newsize;
+
+    /* Special flag magic */
+    if (!type->tp_as_buffer && base->tp_as_buffer) {
+        type->tp_flags &= ~BUFFER_FLAGS;
+        type->tp_flags |=
+            base->tp_flags & BUFFER_FLAGS;
+    }
+    if (!type->tp_as_sequence && base->tp_as_sequence) {
+        type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
+        type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
+    }
+    if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
+        (base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
+        if ((!type->tp_as_number && base->tp_as_number) ||
+            (!type->tp_as_sequence && base->tp_as_sequence)) {
+            type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
+            if (!type->tp_as_number && !type->tp_as_sequence) {
+                type->tp_flags |= base->tp_flags &
+                    Py_TPFLAGS_HAVE_INPLACEOPS;
+            }
+        }
+        /* Wow */
+    }
+    if (!type->tp_as_number && base->tp_as_number) {
+        type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
+        type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
+    }
+
+    /* Copying basicsize is connected to the GC flags */
+    oldsize = base->tp_basicsize;
+    newsize = type->tp_basicsize ? type->tp_basicsize : oldsize;
+    if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+        (base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+        (type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
+        (!type->tp_traverse && !type->tp_clear)) {
+        type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+        if (type->tp_traverse == NULL)
+            type->tp_traverse = base->tp_traverse;
+        if (type->tp_clear == NULL)
+            type->tp_clear = base->tp_clear;
+    }
+    if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+        /* The condition below could use some explanation.
+           It appears that tp_new is not inherited for static types
+           whose base class is 'object'; this seems to be a precaution
+           so that old extension types don't suddenly become
+           callable (object.__new__ wouldn't insure the invariants
+           that the extension type's own factory function ensures).
+           Heap types, of course, are under our control, so they do
+           inherit tp_new; static extension types that specify some
+           other built-in type as the default are considered
+           new-style-aware so they also inherit object.__new__. */
+        if (base != &PyBaseObject_Type ||
+            (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+            if (type->tp_new == NULL)
+                type->tp_new = base->tp_new;
+        }
+    }
+    type->tp_basicsize = newsize;
+
+    /* Copy other non-function slots */
+
+#undef COPYVAL
+#define COPYVAL(SLOT) \
+    if (type->SLOT == 0) type->SLOT = base->SLOT
+
+    COPYVAL(tp_itemsize);
+    if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) {
+        COPYVAL(tp_weaklistoffset);
+    }
+    if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+        COPYVAL(tp_dictoffset);
+    }
+
+    /* Setup fast subclass flags */
+    if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException))
+        type->tp_flags |= Py_TPFLAGS_BASE_EXC_SUBCLASS;
+    else if (PyType_IsSubtype(base, &PyType_Type))
+        type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS;
+    else if (PyType_IsSubtype(base, &PyInt_Type))
+        type->tp_flags |= Py_TPFLAGS_INT_SUBCLASS;
+    else if (PyType_IsSubtype(base, &PyLong_Type))
+        type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS;
+    else if (PyType_IsSubtype(base, &PyString_Type))
+        type->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS;
+#ifdef Py_USING_UNICODE
+    else if (PyType_IsSubtype(base, &PyUnicode_Type))
+        type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS;
+#endif
+    else if (PyType_IsSubtype(base, &PyTuple_Type))
+        type->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
+    else if (PyType_IsSubtype(base, &PyList_Type))
+        type->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS;
+    else if (PyType_IsSubtype(base, &PyDict_Type))
+        type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
+}
+
+static int
+overrides_name(PyTypeObject *type, char *name)
+{
+    PyObject *dict = type->tp_dict;
+
+    assert(dict != NULL);
+    if (PyDict_GetItemString(dict, name) != NULL) {
+        return 1;
+    }
+    return 0;
+}
+
+#define OVERRIDES_HASH(x)       overrides_name(x, "__hash__")
+#define OVERRIDES_EQ(x)         overrides_name(x, "__eq__")
+
+static void
+inherit_slots(PyTypeObject *type, PyTypeObject *base)
+{
+    PyTypeObject *basebase;
+
+#undef SLOTDEFINED
+#undef COPYSLOT
+#undef COPYNUM
+#undef COPYSEQ
+#undef COPYMAP
+#undef COPYBUF
+
+#define SLOTDEFINED(SLOT) \
+    (base->SLOT != 0 && \
+     (basebase == NULL || base->SLOT != basebase->SLOT))
+
+#define COPYSLOT(SLOT) \
+    if (!type->SLOT && SLOTDEFINED(SLOT)) type->SLOT = base->SLOT
+
+#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT)
+#define COPYSEQ(SLOT) COPYSLOT(tp_as_sequence->SLOT)
+#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT)
+#define COPYBUF(SLOT) COPYSLOT(tp_as_buffer->SLOT)
+
+    /* This won't inherit indirect slots (from tp_as_number etc.)
+       if type doesn't provide the space. */
+
+    if (type->tp_as_number != NULL && base->tp_as_number != NULL) {
+        basebase = base->tp_base;
+        if (basebase->tp_as_number == NULL)
+            basebase = NULL;
+        COPYNUM(nb_add);
+        COPYNUM(nb_subtract);
+        COPYNUM(nb_multiply);
+        COPYNUM(nb_divide);
+        COPYNUM(nb_remainder);
+        COPYNUM(nb_divmod);
+        COPYNUM(nb_power);
+        COPYNUM(nb_negative);
+        COPYNUM(nb_positive);
+        COPYNUM(nb_absolute);
+        COPYNUM(nb_nonzero);
+        COPYNUM(nb_invert);
+        COPYNUM(nb_lshift);
+        COPYNUM(nb_rshift);
+        COPYNUM(nb_and);
+        COPYNUM(nb_xor);
+        COPYNUM(nb_or);
+        COPYNUM(nb_coerce);
+        COPYNUM(nb_int);
+        COPYNUM(nb_long);
+        COPYNUM(nb_float);
+        COPYNUM(nb_oct);
+        COPYNUM(nb_hex);
+        COPYNUM(nb_inplace_add);
+        COPYNUM(nb_inplace_subtract);
+        COPYNUM(nb_inplace_multiply);
+        COPYNUM(nb_inplace_divide);
+        COPYNUM(nb_inplace_remainder);
+        COPYNUM(nb_inplace_power);
+        COPYNUM(nb_inplace_lshift);
+        COPYNUM(nb_inplace_rshift);
+        COPYNUM(nb_inplace_and);
+        COPYNUM(nb_inplace_xor);
+        COPYNUM(nb_inplace_or);
+        if (base->tp_flags & Py_TPFLAGS_CHECKTYPES) {
+            COPYNUM(nb_true_divide);
+            COPYNUM(nb_floor_divide);
+            COPYNUM(nb_inplace_true_divide);
+            COPYNUM(nb_inplace_floor_divide);
+        }
+        if (base->tp_flags & Py_TPFLAGS_HAVE_INDEX) {
+            COPYNUM(nb_index);
+        }
+    }
+
+    if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
+        basebase = base->tp_base;
+        if (basebase->tp_as_sequence == NULL)
+            basebase = NULL;
+        COPYSEQ(sq_length);
+        COPYSEQ(sq_concat);
+        COPYSEQ(sq_repeat);
+        COPYSEQ(sq_item);
+        COPYSEQ(sq_slice);
+        COPYSEQ(sq_ass_item);
+        COPYSEQ(sq_ass_slice);
+        COPYSEQ(sq_contains);
+        COPYSEQ(sq_inplace_concat);
+        COPYSEQ(sq_inplace_repeat);
+    }
+
+    if (type->tp_as_mapping != NULL && base->tp_as_mapping != NULL) {
+        basebase = base->tp_base;
+        if (basebase->tp_as_mapping == NULL)
+            basebase = NULL;
+        COPYMAP(mp_length);
+        COPYMAP(mp_subscript);
+        COPYMAP(mp_ass_subscript);
+    }
+
+    if (type->tp_as_buffer != NULL && base->tp_as_buffer != NULL) {
+        basebase = base->tp_base;
+        if (basebase->tp_as_buffer == NULL)
+            basebase = NULL;
+        COPYBUF(bf_getreadbuffer);
+        COPYBUF(bf_getwritebuffer);
+        COPYBUF(bf_getsegcount);
+        COPYBUF(bf_getcharbuffer);
+        COPYBUF(bf_getbuffer);
+        COPYBUF(bf_releasebuffer);
+    }
+
+    basebase = base->tp_base;
+
+    COPYSLOT(tp_dealloc);
+    COPYSLOT(tp_print);
+    if (type->tp_getattr == NULL && type->tp_getattro == NULL) {
+        type->tp_getattr = base->tp_getattr;
+        type->tp_getattro = base->tp_getattro;
+    }
+    if (type->tp_setattr == NULL && type->tp_setattro == NULL) {
+        type->tp_setattr = base->tp_setattr;
+        type->tp_setattro = base->tp_setattro;
+    }
+    /* tp_compare see tp_richcompare */
+    COPYSLOT(tp_repr);
+    /* tp_hash see tp_richcompare */
+    COPYSLOT(tp_call);
+    COPYSLOT(tp_str);
+    if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) {
+        if (type->tp_compare == NULL &&
+            type->tp_richcompare == NULL &&
+            type->tp_hash == NULL)
+        {
+            type->tp_compare = base->tp_compare;
+            type->tp_richcompare = base->tp_richcompare;
+            type->tp_hash = base->tp_hash;
+            /* Check for changes to inherited methods in Py3k*/
+            if (Py_Py3kWarningFlag) {
+                if (base->tp_hash &&
+                                (base->tp_hash != PyObject_HashNotImplemented) &&
+                                !OVERRIDES_HASH(type)) {
+                    if (OVERRIDES_EQ(type)) {
+                        if (PyErr_WarnPy3k("Overriding "
+                                           "__eq__ blocks inheritance "
+                                           "of __hash__ in 3.x",
+                                           1) < 0)
+                            /* XXX This isn't right.  If the warning is turned
+                               into an exception, we should be communicating
+                               the error back to the caller, but figuring out
+                               how to clean up in that case is tricky.  See
+                               issue 8627 for more. */
+                            PyErr_Clear();
+                    }
+                }
+            }
+        }
+    }
+    else {
+        COPYSLOT(tp_compare);
+    }
+    if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_ITER) {
+        COPYSLOT(tp_iter);
+        COPYSLOT(tp_iternext);
+    }
+    if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+        COPYSLOT(tp_descr_get);
+        COPYSLOT(tp_descr_set);
+        COPYSLOT(tp_dictoffset);
+        COPYSLOT(tp_init);
+        COPYSLOT(tp_alloc);
+        COPYSLOT(tp_is_gc);
+        if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) ==
+            (base->tp_flags & Py_TPFLAGS_HAVE_GC)) {
+            /* They agree about gc. */
+            COPYSLOT(tp_free);
+        }
+        else if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+                 type->tp_free == NULL &&
+                 base->tp_free == _PyObject_Del) {
+            /* A bit of magic to plug in the correct default
+             * tp_free function when a derived class adds gc,
+             * didn't define tp_free, and the base uses the
+             * default non-gc tp_free.
+             */
+            type->tp_free = PyObject_GC_Del;
+        }
+        /* else they didn't agree about gc, and there isn't something
+         * obvious to be done -- the type is on its own.
+         */
+    }
+}
+
+static int add_operators(PyTypeObject *);
+
+int
+PyType_Ready(PyTypeObject *type)
+{
+    PyObject *dict, *bases;
+    PyTypeObject *base;
+    Py_ssize_t i, n;
+
+    if (type->tp_flags & Py_TPFLAGS_READY) {
+        assert(type->tp_dict != NULL);
+        return 0;
+    }
+    assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
+
+    type->tp_flags |= Py_TPFLAGS_READYING;
+
+#ifdef Py_TRACE_REFS
+    /* PyType_Ready is the closest thing we have to a choke point
+     * for type objects, so is the best place I can think of to try
+     * to get type objects into the doubly-linked list of all objects.
+     * Still, not all type objects go thru PyType_Ready.
+     */
+    _Py_AddToAllObjects((PyObject *)type, 0);
+#endif
+
+    /* Initialize tp_base (defaults to BaseObject unless that's us) */
+    base = type->tp_base;
+    if (base == NULL && type != &PyBaseObject_Type) {
+        base = type->tp_base = &PyBaseObject_Type;
+        Py_INCREF(base);
+    }
+
+    /* Now the only way base can still be NULL is if type is
+     * &PyBaseObject_Type.
+     */
+
+    /* Initialize the base class */
+    if (base && base->tp_dict == NULL) {
+        if (PyType_Ready(base) < 0)
+            goto error;
+    }
+
+    /* Initialize ob_type if NULL.      This means extensions that want to be
+       compilable separately on Windows can call PyType_Ready() instead of
+       initializing the ob_type field of their type objects. */
+    /* The test for base != NULL is really unnecessary, since base is only
+       NULL when type is &PyBaseObject_Type, and we know its ob_type is
+       not NULL (it's initialized to &PyType_Type).      But coverity doesn't
+       know that. */
+    if (Py_TYPE(type) == NULL && base != NULL)
+        Py_TYPE(type) = Py_TYPE(base);
+
+    /* Initialize tp_bases */
+    bases = type->tp_bases;
+    if (bases == NULL) {
+        if (base == NULL)
+            bases = PyTuple_New(0);
+        else
+            bases = PyTuple_Pack(1, base);
+        if (bases == NULL)
+            goto error;
+        type->tp_bases = bases;
+    }
+
+    /* Initialize tp_dict */
+    dict = type->tp_dict;
+    if (dict == NULL) {
+        dict = PyDict_New();
+        if (dict == NULL)
+            goto error;
+        type->tp_dict = dict;
+    }
+
+    /* Add type-specific descriptors to tp_dict */
+    if (add_operators(type) < 0)
+        goto error;
+    if (type->tp_methods != NULL) {
+        if (add_methods(type, type->tp_methods) < 0)
+            goto error;
+    }
+    if (type->tp_members != NULL) {
+        if (add_members(type, type->tp_members) < 0)
+            goto error;
+    }
+    if (type->tp_getset != NULL) {
+        if (add_getset(type, type->tp_getset) < 0)
+            goto error;
+    }
+
+    /* Calculate method resolution order */
+    if (mro_internal(type) < 0) {
+        goto error;
+    }
+
+    /* Inherit special flags from dominant base */
+    if (type->tp_base != NULL)
+        inherit_special(type, type->tp_base);
+
+    /* Initialize tp_dict properly */
+    bases = type->tp_mro;
+    assert(bases != NULL);
+    assert(PyTuple_Check(bases));
+    n = PyTuple_GET_SIZE(bases);
+    for (i = 1; i < n; i++) {
+        PyObject *b = PyTuple_GET_ITEM(bases, i);
+        if (PyType_Check(b))
+            inherit_slots(type, (PyTypeObject *)b);
+    }
+
+    /* Sanity check for tp_free. */
+    if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) &&
+        (type->tp_free == NULL || type->tp_free == PyObject_Del)) {
+        /* This base class needs to call tp_free, but doesn't have
+         * one, or its tp_free is for non-gc'ed objects.
+         */
+        PyErr_Format(PyExc_TypeError, "type '%.100s' participates in "
+                     "gc and is a base type but has inappropriate "
+                     "tp_free slot",
+                     type->tp_name);
+        goto error;
+    }
+
+    /* if the type dictionary doesn't contain a __doc__, set it from
+       the tp_doc slot.
+     */
+    if (PyDict_GetItemString(type->tp_dict, "__doc__") == NULL) {
+        if (type->tp_doc != NULL) {
+            PyObject *doc = PyString_FromString(type->tp_doc);
+            if (doc == NULL)
+                goto error;
+            PyDict_SetItemString(type->tp_dict, "__doc__", doc);
+            Py_DECREF(doc);
+        } else {
+            PyDict_SetItemString(type->tp_dict,
+                                 "__doc__", Py_None);
+        }
+    }
+
+    /* Some more special stuff */
+    base = type->tp_base;
+    if (base != NULL) {
+        if (type->tp_as_number == NULL)
+            type->tp_as_number = base->tp_as_number;
+        if (type->tp_as_sequence == NULL)
+            type->tp_as_sequence = base->tp_as_sequence;
+        if (type->tp_as_mapping == NULL)
+            type->tp_as_mapping = base->tp_as_mapping;
+        if (type->tp_as_buffer == NULL)
+            type->tp_as_buffer = base->tp_as_buffer;
+    }
+
+    /* Link into each base class's list of subclasses */
+    bases = type->tp_bases;
+    n = PyTuple_GET_SIZE(bases);
+    for (i = 0; i < n; i++) {
+        PyObject *b = PyTuple_GET_ITEM(bases, i);
+        if (PyType_Check(b) &&
+            add_subclass((PyTypeObject *)b, type) < 0)
+            goto error;
+    }
+
+    /* All done -- set the ready flag */
+    assert(type->tp_dict != NULL);
+    type->tp_flags =
+        (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
+    return 0;
+
+  error:
+    type->tp_flags &= ~Py_TPFLAGS_READYING;
+    return -1;
+}
+
+static int
+add_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+    Py_ssize_t i;
+    int result;
+    PyObject *list, *ref, *newobj;
+
+    list = base->tp_subclasses;
+    if (list == NULL) {
+        base->tp_subclasses = list = PyList_New(0);
+        if (list == NULL)
+            return -1;
+    }
+    assert(PyList_Check(list));
+    newobj = PyWeakref_NewRef((PyObject *)type, NULL);
+    i = PyList_GET_SIZE(list);
+    while (--i >= 0) {
+        ref = PyList_GET_ITEM(list, i);
+        assert(PyWeakref_CheckRef(ref));
+        if (PyWeakref_GET_OBJECT(ref) == Py_None)
+            return PyList_SetItem(list, i, newobj);
+    }
+    result = PyList_Append(list, newobj);
+    Py_DECREF(newobj);
+    return result;
+}
+
+static void
+remove_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+    Py_ssize_t i;
+    PyObject *list, *ref;
+
+    list = base->tp_subclasses;
+    if (list == NULL) {
+        return;
+    }
+    assert(PyList_Check(list));
+    i = PyList_GET_SIZE(list);
+    while (--i >= 0) {
+        ref = PyList_GET_ITEM(list, i);
+        assert(PyWeakref_CheckRef(ref));
+        if (PyWeakref_GET_OBJECT(ref) == (PyObject*)type) {
+            /* this can't fail, right? */
+            PySequence_DelItem(list, i);
+            return;
+        }
+    }
+}
+
+static int
+check_num_args(PyObject *ob, int n)
+{
+    if (!PyTuple_CheckExact(ob)) {
+        PyErr_SetString(PyExc_SystemError,
+            "PyArg_UnpackTuple() argument list is not a tuple");
+        return 0;
+    }
+    if (n == PyTuple_GET_SIZE(ob))
+        return 1;
+    PyErr_Format(
+        PyExc_TypeError,
+        "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob));
+    return 0;
+}
+
+/* Generic wrappers for overloadable 'operators' such as __getitem__ */
+
+/* There's a wrapper *function* for each distinct function typedef used
+   for type object slots (e.g. binaryfunc, ternaryfunc, etc.).  There's a
+   wrapper *table* for each distinct operation (e.g. __len__, __add__).
+   Most tables have only one entry; the tables for binary operators have two
+   entries, one regular and one with reversed arguments. */
+
+static PyObject *
+wrap_lenfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    lenfunc func = (lenfunc)wrapped;
+    Py_ssize_t res;
+
+    if (!check_num_args(args, 0))
+        return NULL;
+    res = (*func)(self);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    return PyInt_FromLong((long)res);
+}
+
+static PyObject *
+wrap_inquirypred(PyObject *self, PyObject *args, void *wrapped)
+{
+    inquiry func = (inquiry)wrapped;
+    int res;
+
+    if (!check_num_args(args, 0))
+        return NULL;
+    res = (*func)(self);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    return PyBool_FromLong((long)res);
+}
+
+static PyObject *
+wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    binaryfunc func = (binaryfunc)wrapped;
+    PyObject *other;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    other = PyTuple_GET_ITEM(args, 0);
+    return (*func)(self, other);
+}
+
+static PyObject *
+wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped)
+{
+    binaryfunc func = (binaryfunc)wrapped;
+    PyObject *other;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    other = PyTuple_GET_ITEM(args, 0);
+    if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
+        !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return (*func)(self, other);
+}
+
+static PyObject *
+wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
+{
+    binaryfunc func = (binaryfunc)wrapped;
+    PyObject *other;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    other = PyTuple_GET_ITEM(args, 0);
+    if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
+        !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return (*func)(other, self);
+}
+
+static PyObject *
+wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    coercion func = (coercion)wrapped;
+    PyObject *other, *res;
+    int ok;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    other = PyTuple_GET_ITEM(args, 0);
+    ok = func(&self, &other);
+    if (ok < 0)
+        return NULL;
+    if (ok > 0) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    res = PyTuple_New(2);
+    if (res == NULL) {
+        Py_DECREF(self);
+        Py_DECREF(other);
+        return NULL;
+    }
+    PyTuple_SET_ITEM(res, 0, self);
+    PyTuple_SET_ITEM(res, 1, other);
+    return res;
+}
+
+static PyObject *
+wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    ternaryfunc func = (ternaryfunc)wrapped;
+    PyObject *other;
+    PyObject *third = Py_None;
+
+    /* Note: This wrapper only works for __pow__() */
+
+    if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+        return NULL;
+    return (*func)(self, other, third);
+}
+
+static PyObject *
+wrap_ternaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
+{
+    ternaryfunc func = (ternaryfunc)wrapped;
+    PyObject *other;
+    PyObject *third = Py_None;
+
+    /* Note: This wrapper only works for __pow__() */
+
+    if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+        return NULL;
+    return (*func)(other, self, third);
+}
+
+static PyObject *
+wrap_unaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    unaryfunc func = (unaryfunc)wrapped;
+
+    if (!check_num_args(args, 0))
+        return NULL;
+    return (*func)(self);
+}
+
+static PyObject *
+wrap_indexargfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizeargfunc func = (ssizeargfunc)wrapped;
+    PyObject* o;
+    Py_ssize_t i;
+
+    if (!PyArg_UnpackTuple(args, "", 1, 1, &o))
+        return NULL;
+    i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
+    if (i == -1 && PyErr_Occurred())
+        return NULL;
+    return (*func)(self, i);
+}
+
+static Py_ssize_t
+getindex(PyObject *self, PyObject *arg)
+{
+    Py_ssize_t i;
+
+    i = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
+    if (i == -1 && PyErr_Occurred())
+        return -1;
+    if (i < 0) {
+        PySequenceMethods *sq = Py_TYPE(self)->tp_as_sequence;
+        if (sq && sq->sq_length) {
+            Py_ssize_t n = (*sq->sq_length)(self);
+            if (n < 0)
+                return -1;
+            i += n;
+        }
+    }
+    return i;
+}
+
+static PyObject *
+wrap_sq_item(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizeargfunc func = (ssizeargfunc)wrapped;
+    PyObject *arg;
+    Py_ssize_t i;
+
+    if (PyTuple_GET_SIZE(args) == 1) {
+        arg = PyTuple_GET_ITEM(args, 0);
+        i = getindex(self, arg);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        return (*func)(self, i);
+    }
+    check_num_args(args, 1);
+    assert(PyErr_Occurred());
+    return NULL;
+}
+
+static PyObject *
+wrap_ssizessizeargfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizessizeargfunc func = (ssizessizeargfunc)wrapped;
+    Py_ssize_t i, j;
+
+    if (!PyArg_ParseTuple(args, "nn", &i, &j))
+        return NULL;
+    return (*func)(self, i, j);
+}
+
+static PyObject *
+wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizeobjargproc func = (ssizeobjargproc)wrapped;
+    Py_ssize_t i;
+    int res;
+    PyObject *arg, *value;
+
+    if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
+        return NULL;
+    i = getindex(self, arg);
+    if (i == -1 && PyErr_Occurred())
+        return NULL;
+    res = (*func)(self, i, value);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizeobjargproc func = (ssizeobjargproc)wrapped;
+    Py_ssize_t i;
+    int res;
+    PyObject *arg;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    arg = PyTuple_GET_ITEM(args, 0);
+    i = getindex(self, arg);
+    if (i == -1 && PyErr_Occurred())
+        return NULL;
+    res = (*func)(self, i, NULL);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_ssizessizeobjargproc(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
+    Py_ssize_t i, j;
+    int res;
+    PyObject *value;
+
+    if (!PyArg_ParseTuple(args, "nnO", &i, &j, &value))
+        return NULL;
+    res = (*func)(self, i, j, value);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_delslice(PyObject *self, PyObject *args, void *wrapped)
+{
+    ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
+    Py_ssize_t i, j;
+    int res;
+
+    if (!PyArg_ParseTuple(args, "nn", &i, &j))
+        return NULL;
+    res = (*func)(self, i, j, NULL);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/* XXX objobjproc is a misnomer; should be objargpred */
+static PyObject *
+wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
+{
+    objobjproc func = (objobjproc)wrapped;
+    int res;
+    PyObject *value;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    value = PyTuple_GET_ITEM(args, 0);
+    res = (*func)(self, value);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    else
+        return PyBool_FromLong(res);
+}
+
+static PyObject *
+wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped)
+{
+    objobjargproc func = (objobjargproc)wrapped;
+    int res;
+    PyObject *key, *value;
+
+    if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
+        return NULL;
+    res = (*func)(self, key, value);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_delitem(PyObject *self, PyObject *args, void *wrapped)
+{
+    objobjargproc func = (objobjargproc)wrapped;
+    int res;
+    PyObject *key;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    key = PyTuple_GET_ITEM(args, 0);
+    res = (*func)(self, key, NULL);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    cmpfunc func = (cmpfunc)wrapped;
+    int res;
+    PyObject *other;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    other = PyTuple_GET_ITEM(args, 0);
+    if (Py_TYPE(other)->tp_compare != func &&
+        !PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) {
+        PyErr_Format(
+            PyExc_TypeError,
+            "%s.__cmp__(x,y) requires y to be a '%s', not a '%s'",
+            Py_TYPE(self)->tp_name,
+            Py_TYPE(self)->tp_name,
+            Py_TYPE(other)->tp_name);
+        return NULL;
+    }
+    res = (*func)(self, other);
+    if (PyErr_Occurred())
+        return NULL;
+    return PyInt_FromLong((long)res);
+}
+
+/* Helper to check for object.__setattr__ or __delattr__ applied to a type.
+   This is called the Carlo Verre hack after its discoverer. */
+static int
+hackcheck(PyObject *self, setattrofunc func, char *what)
+{
+    PyTypeObject *type = Py_TYPE(self);
+    while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+        type = type->tp_base;
+    /* If type is NULL now, this is a really weird type.
+       In the spirit of backwards compatibility (?), just shut up. */
+    if (type && type->tp_setattro != func) {
+        PyErr_Format(PyExc_TypeError,
+                     "can't apply this %s to %s object",
+                     what,
+                     type->tp_name);
+        return 0;
+    }
+    return 1;
+}
+
+static PyObject *
+wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
+{
+    setattrofunc func = (setattrofunc)wrapped;
+    int res;
+    PyObject *name, *value;
+
+    if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
+        return NULL;
+    if (!hackcheck(self, func, "__setattr__"))
+        return NULL;
+    res = (*func)(self, name, value);
+    if (res < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
+{
+    setattrofunc func = (setattrofunc)wrapped;
+    int res;
+    PyObject *name;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    name = PyTuple_GET_ITEM(args, 0);
+    if (!hackcheck(self, func, "__delattr__"))
+        return NULL;
+    res = (*func)(self, name, NULL);
+    if (res < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+    hashfunc func = (hashfunc)wrapped;
+    long res;
+
+    if (!check_num_args(args, 0))
+        return NULL;
+    res = (*func)(self);
+    if (res == -1 && PyErr_Occurred())
+        return NULL;
+    return PyInt_FromLong(res);
+}
+
+static PyObject *
+wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
+{
+    ternaryfunc func = (ternaryfunc)wrapped;
+
+    return (*func)(self, args, kwds);
+}
+
+static PyObject *
+wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op)
+{
+    richcmpfunc func = (richcmpfunc)wrapped;
+    PyObject *other;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    other = PyTuple_GET_ITEM(args, 0);
+    return (*func)(self, other, op);
+}
+
+#undef RICHCMP_WRAPPER
+#define RICHCMP_WRAPPER(NAME, OP) \
+static PyObject * \
+richcmp_##NAME(PyObject *self, PyObject *args, void *wrapped) \
+{ \
+    return wrap_richcmpfunc(self, args, wrapped, OP); \
+}
+
+RICHCMP_WRAPPER(lt, Py_LT)
+RICHCMP_WRAPPER(le, Py_LE)
+RICHCMP_WRAPPER(eq, Py_EQ)
+RICHCMP_WRAPPER(ne, Py_NE)
+RICHCMP_WRAPPER(gt, Py_GT)
+RICHCMP_WRAPPER(ge, Py_GE)
+
+static PyObject *
+wrap_next(PyObject *self, PyObject *args, void *wrapped)
+{
+    unaryfunc func = (unaryfunc)wrapped;
+    PyObject *res;
+
+    if (!check_num_args(args, 0))
+        return NULL;
+    res = (*func)(self);
+    if (res == NULL && !PyErr_Occurred())
+        PyErr_SetNone(PyExc_StopIteration);
+    return res;
+}
+
+static PyObject *
+wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
+{
+    descrgetfunc func = (descrgetfunc)wrapped;
+    PyObject *obj;
+    PyObject *type = NULL;
+
+    if (!PyArg_UnpackTuple(args, "", 1, 2, &obj, &type))
+        return NULL;
+    if (obj == Py_None)
+        obj = NULL;
+    if (type == Py_None)
+        type = NULL;
+    if (type == NULL &&obj == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__get__(None, None) is invalid");
+        return NULL;
+    }
+    return (*func)(self, obj, type);
+}
+
+static PyObject *
+wrap_descr_set(PyObject *self, PyObject *args, void *wrapped)
+{
+    descrsetfunc func = (descrsetfunc)wrapped;
+    PyObject *obj, *value;
+    int ret;
+
+    if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
+        return NULL;
+    ret = (*func)(self, obj, value);
+    if (ret < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
+{
+    descrsetfunc func = (descrsetfunc)wrapped;
+    PyObject *obj;
+    int ret;
+
+    if (!check_num_args(args, 1))
+        return NULL;
+    obj = PyTuple_GET_ITEM(args, 0);
+    ret = (*func)(self, obj, NULL);
+    if (ret < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
+{
+    initproc func = (initproc)wrapped;
+
+    if (func(self, args, kwds) < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyTypeObject *type, *subtype, *staticbase;
+    PyObject *arg0, *res;
+
+    if (self == NULL || !PyType_Check(self))
+        Py_FatalError("__new__() called with non-type 'self'");
+    type = (PyTypeObject *)self;
+    if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 1) {
+        PyErr_Format(PyExc_TypeError,
+                     "%s.__new__(): not enough arguments",
+                     type->tp_name);
+        return NULL;
+    }
+    arg0 = PyTuple_GET_ITEM(args, 0);
+    if (!PyType_Check(arg0)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%s.__new__(X): X is not a type object (%s)",
+                     type->tp_name,
+                     Py_TYPE(arg0)->tp_name);
+        return NULL;
+    }
+    subtype = (PyTypeObject *)arg0;
+    if (!PyType_IsSubtype(subtype, type)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%s.__new__(%s): %s is not a subtype of %s",
+                     type->tp_name,
+                     subtype->tp_name,
+                     subtype->tp_name,
+                     type->tp_name);
+        return NULL;
+    }
+
+    /* Check that the use doesn't do something silly and unsafe like
+       object.__new__(dict).  To do this, we check that the
+       most derived base that's not a heap type is this type. */
+    staticbase = subtype;
+    while (staticbase && (staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE))
+        staticbase = staticbase->tp_base;
+    /* If staticbase is NULL now, it is a really weird type.
+       In the spirit of backwards compatibility (?), just shut up. */
+    if (staticbase && staticbase->tp_new != type->tp_new) {
+        PyErr_Format(PyExc_TypeError,
+                     "%s.__new__(%s) is not safe, use %s.__new__()",
+                     type->tp_name,
+                     subtype->tp_name,
+                     staticbase == NULL ? "?" : staticbase->tp_name);
+        return NULL;
+    }
+
+    args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
+    if (args == NULL)
+        return NULL;
+    res = type->tp_new(subtype, args, kwds);
+    Py_DECREF(args);
+    return res;
+}
+
+static struct PyMethodDef tp_new_methoddef[] = {
+    {"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS,
+     PyDoc_STR("T.__new__(S, ...) -> "
+               "a new object with type S, a subtype of T")},
+    {0}
+};
+
+static int
+add_tp_new_wrapper(PyTypeObject *type)
+{
+    PyObject *func;
+
+    if (PyDict_GetItemString(type->tp_dict, "__new__") != NULL)
+        return 0;
+    func = PyCFunction_New(tp_new_methoddef, (PyObject *)type);
+    if (func == NULL)
+        return -1;
+    if (PyDict_SetItemString(type->tp_dict, "__new__", func)) {
+        Py_DECREF(func);
+        return -1;
+    }
+    Py_DECREF(func);
+    return 0;
+}
+
+/* Slot wrappers that call the corresponding __foo__ slot.  See comments
+   below at override_slots() for more explanation. */
+
+#define SLOT0(FUNCNAME, OPSTR) \
+static PyObject * \
+FUNCNAME(PyObject *self) \
+{ \
+    static PyObject *cache_str; \
+    return call_method(self, OPSTR, &cache_str, "()"); \
+}
+
+#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \
+static PyObject * \
+FUNCNAME(PyObject *self, ARG1TYPE arg1) \
+{ \
+    static PyObject *cache_str; \
+    return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
+}
+
+/* Boolean helper for SLOT1BINFULL().
+   right.__class__ is a nontrivial subclass of left.__class__. */
+static int
+method_is_overloaded(PyObject *left, PyObject *right, char *name)
+{
+    PyObject *a, *b;
+    int ok;
+
+    b = PyObject_GetAttrString((PyObject *)(Py_TYPE(right)), name);
+    if (b == NULL) {
+        PyErr_Clear();
+        /* If right doesn't have it, it's not overloaded */
+        return 0;
+    }
+
+    a = PyObject_GetAttrString((PyObject *)(Py_TYPE(left)), name);
+    if (a == NULL) {
+        PyErr_Clear();
+        Py_DECREF(b);
+        /* If right has it but left doesn't, it's overloaded */
+        return 1;
+    }
+
+    ok = PyObject_RichCompareBool(a, b, Py_NE);
+    Py_DECREF(a);
+    Py_DECREF(b);
+    if (ok < 0) {
+        PyErr_Clear();
+        return 0;
+    }
+
+    return ok;
+}
+
+
+#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
+static PyObject * \
+FUNCNAME(PyObject *self, PyObject *other) \
+{ \
+    static PyObject *cache_str, *rcache_str; \
+    int do_other = Py_TYPE(self) != Py_TYPE(other) && \
+        Py_TYPE(other)->tp_as_number != NULL && \
+        Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \
+    if (Py_TYPE(self)->tp_as_number != NULL && \
+        Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \
+        PyObject *r; \
+        if (do_other && \
+            PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \
+            method_is_overloaded(self, other, ROPSTR)) { \
+            r = call_maybe( \
+                other, ROPSTR, &rcache_str, "(O)", self); \
+            if (r != Py_NotImplemented) \
+                return r; \
+            Py_DECREF(r); \
+            do_other = 0; \
+        } \
+        r = call_maybe( \
+            self, OPSTR, &cache_str, "(O)", other); \
+        if (r != Py_NotImplemented || \
+            Py_TYPE(other) == Py_TYPE(self)) \
+            return r; \
+        Py_DECREF(r); \
+    } \
+    if (do_other) { \
+        return call_maybe( \
+            other, ROPSTR, &rcache_str, "(O)", self); \
+    } \
+    Py_INCREF(Py_NotImplemented); \
+    return Py_NotImplemented; \
+}
+
+#define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \
+    SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR)
+
+#define SLOT2(FUNCNAME, OPSTR, ARG1TYPE, ARG2TYPE, ARGCODES) \
+static PyObject * \
+FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \
+{ \
+    static PyObject *cache_str; \
+    return call_method(self, OPSTR, &cache_str, \
+                       "(" ARGCODES ")", arg1, arg2); \
+}
+
+static Py_ssize_t
+slot_sq_length(PyObject *self)
+{
+    static PyObject *len_str;
+    PyObject *res = call_method(self, "__len__", &len_str, "()");
+    Py_ssize_t len;
+
+    if (res == NULL)
+        return -1;
+    len = PyInt_AsSsize_t(res);
+    Py_DECREF(res);
+    if (len < 0) {
+        if (!PyErr_Occurred())
+            PyErr_SetString(PyExc_ValueError,
+                            "__len__() should return >= 0");
+        return -1;
+    }
+    return len;
+}
+
+/* Super-optimized version of slot_sq_item.
+   Other slots could do the same... */
+static PyObject *
+slot_sq_item(PyObject *self, Py_ssize_t i)
+{
+    static PyObject *getitem_str;
+    PyObject *func, *args = NULL, *ival = NULL, *retval = NULL;
+    descrgetfunc f;
+
+    if (getitem_str == NULL) {
+        getitem_str = PyString_InternFromString("__getitem__");
+        if (getitem_str == NULL)
+            return NULL;
+    }
+    func = _PyType_Lookup(Py_TYPE(self), getitem_str);
+    if (func != NULL) {
+        if ((f = Py_TYPE(func)->tp_descr_get) == NULL)
+            Py_INCREF(func);
+        else {
+            func = f(func, self, (PyObject *)(Py_TYPE(self)));
+            if (func == NULL) {
+                return NULL;
+            }
+        }
+        ival = PyInt_FromSsize_t(i);
+        if (ival != NULL) {
+            args = PyTuple_New(1);
+            if (args != NULL) {
+                PyTuple_SET_ITEM(args, 0, ival);
+                retval = PyObject_Call(func, args, NULL);
+                Py_XDECREF(args);
+                Py_XDECREF(func);
+                return retval;
+            }
+        }
+    }
+    else {
+        PyErr_SetObject(PyExc_AttributeError, getitem_str);
+    }
+    Py_XDECREF(args);
+    Py_XDECREF(ival);
+    Py_XDECREF(func);
+    return NULL;
+}
+
+static PyObject*
+slot_sq_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j)
+{
+    static PyObject *getslice_str;
+
+    if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "
+                        "use __getitem__", 1) < 0)
+        return NULL;
+    return call_method(self, "__getslice__", &getslice_str,
+        "nn", i, j);
+}
+
+static int
+slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
+{
+    PyObject *res;
+    static PyObject *delitem_str, *setitem_str;
+
+    if (value == NULL)
+        res = call_method(self, "__delitem__", &delitem_str,
+                          "(n)", index);
+    else
+        res = call_method(self, "__setitem__", &setitem_str,
+                          "(nO)", index, value);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static int
+slot_sq_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+    PyObject *res;
+    static PyObject *delslice_str, *setslice_str;
+
+    if (value == NULL) {
+        if (PyErr_WarnPy3k("in 3.x, __delslice__ has been removed; "
+                           "use __delitem__", 1) < 0)
+            return -1;
+        res = call_method(self, "__delslice__", &delslice_str,
+                          "(nn)", i, j);
+    }
+    else {
+        if (PyErr_WarnPy3k("in 3.x, __setslice__ has been removed; "
+                                "use __setitem__", 1) < 0)
+            return -1;
+        res = call_method(self, "__setslice__", &setslice_str,
+                  "(nnO)", i, j, value);
+    }
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static int
+slot_sq_contains(PyObject *self, PyObject *value)
+{
+    PyObject *func, *res, *args;
+    int result = -1;
+
+    static PyObject *contains_str;
+
+    func = lookup_maybe(self, "__contains__", &contains_str);
+    if (func != NULL) {
+        args = PyTuple_Pack(1, value);
+        if (args == NULL)
+            res = NULL;
+        else {
+            res = PyObject_Call(func, args, NULL);
+            Py_DECREF(args);
+        }
+        Py_DECREF(func);
+        if (res != NULL) {
+            result = PyObject_IsTrue(res);
+            Py_DECREF(res);
+        }
+    }
+    else if (! PyErr_Occurred()) {
+        /* Possible results: -1 and 1 */
+        result = (int)_PySequence_IterSearch(self, value,
+                                         PY_ITERSEARCH_CONTAINS);
+    }
+    return result;
+}
+
+#define slot_mp_length slot_sq_length
+
+SLOT1(slot_mp_subscript, "__getitem__", PyObject *, "O")
+
+static int
+slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value)
+{
+    PyObject *res;
+    static PyObject *delitem_str, *setitem_str;
+
+    if (value == NULL)
+        res = call_method(self, "__delitem__", &delitem_str,
+                          "(O)", key);
+    else
+        res = call_method(self, "__setitem__", &setitem_str,
+                         "(OO)", key, value);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__")
+SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__")
+SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__")
+SLOT1BIN(slot_nb_divide, nb_divide, "__div__", "__rdiv__")
+SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__")
+SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__")
+
+static PyObject *slot_nb_power(PyObject *, PyObject *, PyObject *);
+
+SLOT1BINFULL(slot_nb_power_binary, slot_nb_power,
+             nb_power, "__pow__", "__rpow__")
+
+static PyObject *
+slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
+{
+    static PyObject *pow_str;
+
+    if (modulus == Py_None)
+        return slot_nb_power_binary(self, other);
+    /* Three-arg power doesn't use __rpow__.  But ternary_op
+       can call this when the second argument's type uses
+       slot_nb_power, so check before calling self.__pow__. */
+    if (Py_TYPE(self)->tp_as_number != NULL &&
+        Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) {
+        return call_method(self, "__pow__", &pow_str,
+                           "(OO)", other, modulus);
+    }
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+SLOT0(slot_nb_negative, "__neg__")
+SLOT0(slot_nb_positive, "__pos__")
+SLOT0(slot_nb_absolute, "__abs__")
+
+static int
+slot_nb_nonzero(PyObject *self)
+{
+    PyObject *func, *args;
+    static PyObject *nonzero_str, *len_str;
+    int result = -1;
+    int using_len = 0;
+
+    func = lookup_maybe(self, "__nonzero__", &nonzero_str);
+    if (func == NULL) {
+        if (PyErr_Occurred())
+            return -1;
+        func = lookup_maybe(self, "__len__", &len_str);
+        if (func == NULL)
+            return PyErr_Occurred() ? -1 : 1;
+        using_len = 1;
+    }
+    args = PyTuple_New(0);
+    if (args != NULL) {
+        PyObject *temp = PyObject_Call(func, args, NULL);
+        Py_DECREF(args);
+        if (temp != NULL) {
+            if (PyInt_CheckExact(temp) || PyBool_Check(temp))
+                result = PyObject_IsTrue(temp);
+            else {
+                PyErr_Format(PyExc_TypeError,
+                             "%s should return "
+                             "bool or int, returned %s",
+                             (using_len ? "__len__"
+                                        : "__nonzero__"),
+                             temp->ob_type->tp_name);
+                result = -1;
+            }
+            Py_DECREF(temp);
+        }
+    }
+    Py_DECREF(func);
+    return result;
+}
+
+
+static PyObject *
+slot_nb_index(PyObject *self)
+{
+    static PyObject *index_str;
+    return call_method(self, "__index__", &index_str, "()");
+}
+
+
+SLOT0(slot_nb_invert, "__invert__")
+SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
+SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__")
+SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__")
+SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__")
+SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__")
+
+static int
+slot_nb_coerce(PyObject **a, PyObject **b)
+{
+    static PyObject *coerce_str;
+    PyObject *self = *a, *other = *b;
+
+    if (self->ob_type->tp_as_number != NULL &&
+        self->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
+        PyObject *r;
+        r = call_maybe(
+            self, "__coerce__", &coerce_str, "(O)", other);
+        if (r == NULL)
+            return -1;
+        if (r == Py_NotImplemented) {
+            Py_DECREF(r);
+        }
+        else {
+            if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
+                PyErr_SetString(PyExc_TypeError,
+                    "__coerce__ didn't return a 2-tuple");
+                Py_DECREF(r);
+                return -1;
+            }
+            *a = PyTuple_GET_ITEM(r, 0);
+            Py_INCREF(*a);
+            *b = PyTuple_GET_ITEM(r, 1);
+            Py_INCREF(*b);
+            Py_DECREF(r);
+            return 0;
+        }
+    }
+    if (other->ob_type->tp_as_number != NULL &&
+        other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
+        PyObject *r;
+        r = call_maybe(
+            other, "__coerce__", &coerce_str, "(O)", self);
+        if (r == NULL)
+            return -1;
+        if (r == Py_NotImplemented) {
+            Py_DECREF(r);
+            return 1;
+        }
+        if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
+            PyErr_SetString(PyExc_TypeError,
+                            "__coerce__ didn't return a 2-tuple");
+            Py_DECREF(r);
+            return -1;
+        }
+        *a = PyTuple_GET_ITEM(r, 1);
+        Py_INCREF(*a);
+        *b = PyTuple_GET_ITEM(r, 0);
+        Py_INCREF(*b);
+        Py_DECREF(r);
+        return 0;
+    }
+    return 1;
+}
+
+SLOT0(slot_nb_int, "__int__")
+SLOT0(slot_nb_long, "__long__")
+SLOT0(slot_nb_float, "__float__")
+SLOT0(slot_nb_oct, "__oct__")
+SLOT0(slot_nb_hex, "__hex__")
+SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")
+SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")
+SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O")
+SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject *, "O")
+SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O")
+/* Can't use SLOT1 here, because nb_inplace_power is ternary */
+static PyObject *
+slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2)
+{
+  static PyObject *cache_str;
+  return call_method(self, "__ipow__", &cache_str, "(" "O" ")", arg1);
+}
+SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O")
+SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O")
+SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O")
+SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *, "O")
+SLOT1(slot_nb_inplace_or, "__ior__", PyObject *, "O")
+SLOT1BIN(slot_nb_floor_divide, nb_floor_divide,
+         "__floordiv__", "__rfloordiv__")
+SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__")
+SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *, "O")
+SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O")
+
+static int
+half_compare(PyObject *self, PyObject *other)
+{
+    PyObject *func, *args, *res;
+    static PyObject *cmp_str;
+    Py_ssize_t c;
+
+    func = lookup_method(self, "__cmp__", &cmp_str);
+    if (func == NULL) {
+        PyErr_Clear();
+    }
+    else {
+        args = PyTuple_Pack(1, other);
+        if (args == NULL)
+            res = NULL;
+        else {
+            res = PyObject_Call(func, args, NULL);
+            Py_DECREF(args);
+        }
+        Py_DECREF(func);
+        if (res != Py_NotImplemented) {
+            if (res == NULL)
+                return -2;
+            c = PyInt_AsLong(res);
+            Py_DECREF(res);
+            if (c == -1 && PyErr_Occurred())
+                return -2;
+            return (c < 0) ? -1 : (c > 0) ? 1 : 0;
+        }
+        Py_DECREF(res);
+    }
+    return 2;
+}
+
+/* This slot is published for the benefit of try_3way_compare in object.c */
+int
+_PyObject_SlotCompare(PyObject *self, PyObject *other)
+{
+    int c;
+
+    if (Py_TYPE(self)->tp_compare == _PyObject_SlotCompare) {
+        c = half_compare(self, other);
+        if (c <= 1)
+            return c;
+    }
+    if (Py_TYPE(other)->tp_compare == _PyObject_SlotCompare) {
+        c = half_compare(other, self);
+        if (c < -1)
+            return -2;
+        if (c <= 1)
+            return -c;
+    }
+    return (void *)self < (void *)other ? -1 :
+        (void *)self > (void *)other ? 1 : 0;
+}
+
+static PyObject *
+slot_tp_repr(PyObject *self)
+{
+    PyObject *func, *res;
+    static PyObject *repr_str;
+
+    func = lookup_method(self, "__repr__", &repr_str);
+    if (func != NULL) {
+        res = PyEval_CallObject(func, NULL);
+        Py_DECREF(func);
+        return res;
+    }
+    PyErr_Clear();
+    return PyString_FromFormat("<%s object at %p>",
+                               Py_TYPE(self)->tp_name, self);
+}
+
+static PyObject *
+slot_tp_str(PyObject *self)
+{
+    PyObject *func, *res;
+    static PyObject *str_str;
+
+    func = lookup_method(self, "__str__", &str_str);
+    if (func != NULL) {
+        res = PyEval_CallObject(func, NULL);
+        Py_DECREF(func);
+        return res;
+    }
+    else {
+        PyErr_Clear();
+        return slot_tp_repr(self);
+    }
+}
+
+static long
+slot_tp_hash(PyObject *self)
+{
+    PyObject *func;
+    static PyObject *hash_str, *eq_str, *cmp_str;
+    long h;
+
+    func = lookup_method(self, "__hash__", &hash_str);
+
+    if (func != NULL && func != Py_None) {
+        PyObject *res = PyEval_CallObject(func, NULL);
+        Py_DECREF(func);
+        if (res == NULL)
+            return -1;
+        if (PyLong_Check(res))
+            h = PyLong_Type.tp_hash(res);
+        else
+            h = PyInt_AsLong(res);
+        Py_DECREF(res);
+    }
+    else {
+        Py_XDECREF(func); /* may be None */
+        PyErr_Clear();
+        func = lookup_method(self, "__eq__", &eq_str);
+        if (func == NULL) {
+            PyErr_Clear();
+            func = lookup_method(self, "__cmp__", &cmp_str);
+        }
+        if (func != NULL) {
+            Py_DECREF(func);
+            return PyObject_HashNotImplemented(self);
+        }
+        PyErr_Clear();
+        h = _Py_HashPointer((void *)self);
+    }
+    if (h == -1 && !PyErr_Occurred())
+        h = -2;
+    return h;
+}
+
+static PyObject *
+slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    static PyObject *call_str;
+    PyObject *meth = lookup_method(self, "__call__", &call_str);
+    PyObject *res;
+
+    if (meth == NULL)
+        return NULL;
+
+    res = PyObject_Call(meth, args, kwds);
+
+    Py_DECREF(meth);
+    return res;
+}
+
+/* There are two slot dispatch functions for tp_getattro.
+
+   - slot_tp_getattro() is used when __getattribute__ is overridden
+     but no __getattr__ hook is present;
+
+   - slot_tp_getattr_hook() is used when a __getattr__ hook is present.
+
+   The code in update_one_slot() always installs slot_tp_getattr_hook(); this
+   detects the absence of __getattr__ and then installs the simpler slot if
+   necessary. */
+
+static PyObject *
+slot_tp_getattro(PyObject *self, PyObject *name)
+{
+    static PyObject *getattribute_str = NULL;
+    return call_method(self, "__getattribute__", &getattribute_str,
+                       "(O)", name);
+}
+
+static PyObject *
+call_attribute(PyObject *self, PyObject *attr, PyObject *name)
+{
+    PyObject *res, *descr = NULL;
+    descrgetfunc f = Py_TYPE(attr)->tp_descr_get;
+
+    if (f != NULL) {
+        descr = f(attr, self, (PyObject *)(Py_TYPE(self)));
+        if (descr == NULL)
+            return NULL;
+        else
+            attr = descr;
+    }
+    res = PyObject_CallFunctionObjArgs(attr, name, NULL);
+    Py_XDECREF(descr);
+    return res;
+}
+
+static PyObject *
+slot_tp_getattr_hook(PyObject *self, PyObject *name)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    PyObject *getattr, *getattribute, *res;
+    static PyObject *getattribute_str = NULL;
+    static PyObject *getattr_str = NULL;
+
+    if (getattr_str == NULL) {
+        getattr_str = PyString_InternFromString("__getattr__");
+        if (getattr_str == NULL)
+            return NULL;
+    }
+    if (getattribute_str == NULL) {
+        getattribute_str =
+            PyString_InternFromString("__getattribute__");
+        if (getattribute_str == NULL)
+            return NULL;
+    }
+    /* speed hack: we could use lookup_maybe, but that would resolve the
+       method fully for each attribute lookup for classes with
+       __getattr__, even when the attribute is present. So we use
+       _PyType_Lookup and create the method only when needed, with
+       call_attribute. */
+    getattr = _PyType_Lookup(tp, getattr_str);
+    if (getattr == NULL) {
+        /* No __getattr__ hook: use a simpler dispatcher */
+        tp->tp_getattro = slot_tp_getattro;
+        return slot_tp_getattro(self, name);
+    }
+    Py_INCREF(getattr);
+    /* speed hack: we could use lookup_maybe, but that would resolve the
+       method fully for each attribute lookup for classes with
+       __getattr__, even when self has the default __getattribute__
+       method. So we use _PyType_Lookup and create the method only when
+       needed, with call_attribute. */
+    getattribute = _PyType_Lookup(tp, getattribute_str);
+    if (getattribute == NULL ||
+        (Py_TYPE(getattribute) == &PyWrapperDescr_Type &&
+         ((PyWrapperDescrObject *)getattribute)->d_wrapped ==
+         (void *)PyObject_GenericGetAttr))
+        res = PyObject_GenericGetAttr(self, name);
+    else {
+        Py_INCREF(getattribute);
+        res = call_attribute(self, getattribute, name);
+        Py_DECREF(getattribute);
+    }
+    if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Clear();
+        res = call_attribute(self, getattr, name);
+    }
+    Py_DECREF(getattr);
+    return res;
+}
+
+static int
+slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value)
+{
+    PyObject *res;
+    static PyObject *delattr_str, *setattr_str;
+
+    if (value == NULL)
+        res = call_method(self, "__delattr__", &delattr_str,
+                          "(O)", name);
+    else
+        res = call_method(self, "__setattr__", &setattr_str,
+                          "(OO)", name, value);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static char *name_op[] = {
+    "__lt__",
+    "__le__",
+    "__eq__",
+    "__ne__",
+    "__gt__",
+    "__ge__",
+};
+
+static PyObject *
+half_richcompare(PyObject *self, PyObject *other, int op)
+{
+    PyObject *func, *args, *res;
+    static PyObject *op_str[6];
+
+    func = lookup_method(self, name_op[op], &op_str[op]);
+    if (func == NULL) {
+        PyErr_Clear();
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    args = PyTuple_Pack(1, other);
+    if (args == NULL)
+        res = NULL;
+    else {
+        res = PyObject_Call(func, args, NULL);
+        Py_DECREF(args);
+    }
+    Py_DECREF(func);
+    return res;
+}
+
+static PyObject *
+slot_tp_richcompare(PyObject *self, PyObject *other, int op)
+{
+    PyObject *res;
+
+    if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) {
+        res = half_richcompare(self, other, op);
+        if (res != Py_NotImplemented)
+            return res;
+        Py_DECREF(res);
+    }
+    if (Py_TYPE(other)->tp_richcompare == slot_tp_richcompare) {
+        res = half_richcompare(other, self, _Py_SwappedOp[op]);
+        if (res != Py_NotImplemented) {
+            return res;
+        }
+        Py_DECREF(res);
+    }
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+}
+
+static PyObject *
+slot_tp_iter(PyObject *self)
+{
+    PyObject *func, *res;
+    static PyObject *iter_str, *getitem_str;
+
+    func = lookup_method(self, "__iter__", &iter_str);
+    if (func != NULL) {
+        PyObject *args;
+        args = res = PyTuple_New(0);
+        if (args != NULL) {
+            res = PyObject_Call(func, args, NULL);
+            Py_DECREF(args);
+        }
+        Py_DECREF(func);
+        return res;
+    }
+    PyErr_Clear();
+    func = lookup_method(self, "__getitem__", &getitem_str);
+    if (func == NULL) {
+        PyErr_Format(PyExc_TypeError,
+                     "'%.200s' object is not iterable",
+                     Py_TYPE(self)->tp_name);
+        return NULL;
+    }
+    Py_DECREF(func);
+    return PySeqIter_New(self);
+}
+
+static PyObject *
+slot_tp_iternext(PyObject *self)
+{
+    static PyObject *next_str;
+    return call_method(self, "next", &next_str, "()");
+}
+
+static PyObject *
+slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    PyObject *get;
+    static PyObject *get_str = NULL;
+
+    if (get_str == NULL) {
+        get_str = PyString_InternFromString("__get__");
+        if (get_str == NULL)
+            return NULL;
+    }
+    get = _PyType_Lookup(tp, get_str);
+    if (get == NULL) {
+        /* Avoid further slowdowns */
+        if (tp->tp_descr_get == slot_tp_descr_get)
+            tp->tp_descr_get = NULL;
+        Py_INCREF(self);
+        return self;
+    }
+    if (obj == NULL)
+        obj = Py_None;
+    if (type == NULL)
+        type = Py_None;
+    return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL);
+}
+
+static int
+slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value)
+{
+    PyObject *res;
+    static PyObject *del_str, *set_str;
+
+    if (value == NULL)
+        res = call_method(self, "__delete__", &del_str,
+                          "(O)", target);
+    else
+        res = call_method(self, "__set__", &set_str,
+                          "(OO)", target, value);
+    if (res == NULL)
+        return -1;
+    Py_DECREF(res);
+    return 0;
+}
+
+static int
+slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    static PyObject *init_str;
+    PyObject *meth = lookup_method(self, "__init__", &init_str);
+    PyObject *res;
+
+    if (meth == NULL)
+        return -1;
+    res = PyObject_Call(meth, args, kwds);
+    Py_DECREF(meth);
+    if (res == NULL)
+        return -1;
+    if (res != Py_None) {
+        PyErr_Format(PyExc_TypeError,
+                     "__init__() should return None, not '%.200s'",
+                     Py_TYPE(res)->tp_name);
+        Py_DECREF(res);
+        return -1;
+    }
+    Py_DECREF(res);
+    return 0;
+}
+
+static PyObject *
+slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    static PyObject *new_str;
+    PyObject *func;
+    PyObject *newargs, *x;
+    Py_ssize_t i, n;
+
+    if (new_str == NULL) {
+        new_str = PyString_InternFromString("__new__");
+        if (new_str == NULL)
+            return NULL;
+    }
+    func = PyObject_GetAttr((PyObject *)type, new_str);
+    if (func == NULL)
+        return NULL;
+    assert(PyTuple_Check(args));
+    n = PyTuple_GET_SIZE(args);
+    newargs = PyTuple_New(n+1);
+    if (newargs == NULL)
+        return NULL;
+    Py_INCREF(type);
+    PyTuple_SET_ITEM(newargs, 0, (PyObject *)type);
+    for (i = 0; i < n; i++) {
+        x = PyTuple_GET_ITEM(args, i);
+        Py_INCREF(x);
+        PyTuple_SET_ITEM(newargs, i+1, x);
+    }
+    x = PyObject_Call(func, newargs, kwds);
+    Py_DECREF(newargs);
+    Py_DECREF(func);
+    return x;
+}
+
+static void
+slot_tp_del(PyObject *self)
+{
+    static PyObject *del_str = NULL;
+    PyObject *del, *res;
+    PyObject *error_type, *error_value, *error_traceback;
+
+    /* Temporarily resurrect the object. */
+    assert(self->ob_refcnt == 0);
+    self->ob_refcnt = 1;
+
+    /* Save the current exception, if any. */
+    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+    /* Execute __del__ method, if any. */
+    del = lookup_maybe(self, "__del__", &del_str);
+    if (del != NULL) {
+        res = PyEval_CallObject(del, NULL);
+        if (res == NULL)
+            PyErr_WriteUnraisable(del);
+        else
+            Py_DECREF(res);
+        Py_DECREF(del);
+    }
+
+    /* Restore the saved exception. */
+    PyErr_Restore(error_type, error_value, error_traceback);
+
+    /* Undo the temporary resurrection; can't use DECREF here, it would
+     * cause a recursive call.
+     */
+    assert(self->ob_refcnt > 0);
+    if (--self->ob_refcnt == 0)
+        return;         /* this is the normal path out */
+
+    /* __del__ resurrected it!  Make it look like the original Py_DECREF
+     * never happened.
+     */
+    {
+        Py_ssize_t refcnt = self->ob_refcnt;
+        _Py_NewReference(self);
+        self->ob_refcnt = refcnt;
+    }
+    assert(!PyType_IS_GC(Py_TYPE(self)) ||
+           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+    /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+     * we need to undo that. */
+    _Py_DEC_REFTOTAL;
+    /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+     * chain, so no more to do there.
+     * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+     * _Py_NewReference bumped tp_allocs:  both of those need to be
+     * undone.
+     */
+#ifdef COUNT_ALLOCS
+    --Py_TYPE(self)->tp_frees;
+    --Py_TYPE(self)->tp_allocs;
+#endif
+}
+
+
+/*
+Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper functions.
+
+The table is ordered by offsets relative to the 'PyHeapTypeObject' structure,
+which incorporates the additional structures used for numbers, sequences and
+mappings.  Note that multiple names may map to the same slot (e.g. __eq__,
+__ne__ etc. all map to tp_richcompare) and one name may map to multiple slots
+(e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with
+an all-zero entry.  (This table is further initialized in init_slotdefs().)
+*/
+
+typedef struct wrapperbase slotdef;
+
+#undef TPSLOT
+#undef FLSLOT
+#undef ETSLOT
+#undef SQSLOT
+#undef MPSLOT
+#undef NBSLOT
+#undef UNSLOT
+#undef IBSLOT
+#undef BINSLOT
+#undef RBINSLOT
+
+#define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+     PyDoc_STR(DOC)}
+#define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \
+    {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+     PyDoc_STR(DOC), FLAGS}
+#define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+     PyDoc_STR(DOC)}
+#define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC)
+#define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC)
+#define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
+#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
+           "x." NAME "() <==> " DOC)
+#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
+           "x." NAME "(y) <==> x" DOC "y")
+#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+           "x." NAME "(y) <==> x" DOC "y")
+#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+           "x." NAME "(y) <==> y" DOC "x")
+#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+           "x." NAME "(y) <==> " DOC)
+#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+    ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+           "x." NAME "(y) <==> " DOC)
+
+static slotdef slotdefs[] = {
+    TPSLOT("__str__", tp_print, NULL, NULL, ""),
+    TPSLOT("__repr__", tp_print, NULL, NULL, ""),
+    TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
+    TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
+    TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
+    TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
+    TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc,
+           "x.__cmp__(y) <==> cmp(x,y)"),
+    TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
+           "x.__repr__() <==> repr(x)"),
+    TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
+           "x.__hash__() <==> hash(x)"),
+    FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
+           "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS),
+    TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
+           "x.__str__() <==> str(x)"),
+    TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
+           wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
+    TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
+    TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
+           "x.__setattr__('name', value) <==> x.name = value"),
+    TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
+           "x.__delattr__('name') <==> del x.name"),
+    TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
+           "x.__lt__(y) <==> x<y"),
+    TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
+           "x.__le__(y) <==> x<=y"),
+    TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
+           "x.__eq__(y) <==> x==y"),
+    TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
+           "x.__ne__(y) <==> x!=y"),
+    TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
+           "x.__gt__(y) <==> x>y"),
+    TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
+           "x.__ge__(y) <==> x>=y"),
+    TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
+           "x.__iter__() <==> iter(x)"),
+    TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next,
+           "x.next() -> the next value, or raise StopIteration"),
+    TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
+           "descr.__get__(obj[, type]) -> value"),
+    TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
+           "descr.__set__(obj, value)"),
+    TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,
+           wrap_descr_delete, "descr.__delete__(obj)"),
+    FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init,
+           "x.__init__(...) initializes x; "
+           "see help(type(x)) for signature",
+           PyWrapperFlag_KEYWORDS),
+    TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""),
+    TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""),
+    BINSLOT("__add__", nb_add, slot_nb_add,
+        "+"),
+    RBINSLOT("__radd__", nb_add, slot_nb_add,
+             "+"),
+    BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
+        "-"),
+    RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
+             "-"),
+    BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
+        "*"),
+    RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
+             "*"),
+    BINSLOT("__div__", nb_divide, slot_nb_divide,
+        "/"),
+    RBINSLOT("__rdiv__", nb_divide, slot_nb_divide,
+             "/"),
+    BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
+        "%"),
+    RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
+             "%"),
+    BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
+        "divmod(x, y)"),
+    RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
+             "divmod(y, x)"),
+    NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
+           "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
+    NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
+           "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
+    UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"),
+    UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"),
+    UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
+           "abs(x)"),
+    UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred,
+           "x != 0"),
+    UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"),
+    BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
+    RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
+    BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
+    RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"),
+    BINSLOT("__and__", nb_and, slot_nb_and, "&"),
+    RBINSLOT("__rand__", nb_and, slot_nb_and, "&"),
+    BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"),
+    RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"),
+    BINSLOT("__or__", nb_or, slot_nb_or, "|"),
+    RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
+    NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc,
+           "x.__coerce__(y) <==> coerce(x, y)"),
+    UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
+           "int(x)"),
+    UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc,
+           "long(x)"),
+    UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
+           "float(x)"),
+    UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc,
+           "oct(x)"),
+    UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
+           "hex(x)"),
+    IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
+           wrap_binaryfunc, "+="),
+    IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
+           wrap_binaryfunc, "-="),
+    IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply,
+           wrap_binaryfunc, "*="),
+    IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide,
+           wrap_binaryfunc, "/="),
+    IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder,
+           wrap_binaryfunc, "%="),
+    IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power,
+           wrap_binaryfunc, "**="),
+    IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift,
+           wrap_binaryfunc, "<<="),
+    IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift,
+           wrap_binaryfunc, ">>="),
+    IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and,
+           wrap_binaryfunc, "&="),
+    IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor,
+           wrap_binaryfunc, "^="),
+    IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or,
+           wrap_binaryfunc, "|="),
+    BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
+    RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
+    BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"),
+    RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"),
+    IBSLOT("__ifloordiv__", nb_inplace_floor_divide,
+           slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"),
+    IBSLOT("__itruediv__", nb_inplace_true_divide,
+           slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
+    NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
+           "x[y:z] <==> x[y.__index__():z.__index__()]"),
+    MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
+           "x.__len__() <==> len(x)"),
+    MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
+           wrap_binaryfunc,
+           "x.__getitem__(y) <==> x[y]"),
+    MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
+           wrap_objobjargproc,
+           "x.__setitem__(i, y) <==> x[i]=y"),
+    MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
+           wrap_delitem,
+           "x.__delitem__(y) <==> del x[y]"),
+    SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
+           "x.__len__() <==> len(x)"),
+    /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
+       The logic in abstract.c always falls back to nb_add/nb_multiply in
+       this case.  Defining both the nb_* and the sq_* slots to call the
+       user-defined methods has unexpected side-effects, as shown by
+       test_descr.notimplemented() */
+    SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
+      "x.__add__(y) <==> x+y"),
+    SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
+      "x.__mul__(n) <==> x*n"),
+    SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
+      "x.__rmul__(n) <==> n*x"),
+    SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
+           "x.__getitem__(y) <==> x[y]"),
+    SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
+           "x.__getslice__(i, j) <==> x[i:j]\n\
+           \n\
+           Use of negative indices is not supported."),
+    SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
+           "x.__setitem__(i, y) <==> x[i]=y"),
+    SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
+           "x.__delitem__(y) <==> del x[y]"),
+    SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
+           wrap_ssizessizeobjargproc,
+           "x.__setslice__(i, j, y) <==> x[i:j]=y\n\
+           \n\
+           Use  of negative indices is not supported."),
+    SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
+           "x.__delslice__(i, j) <==> del x[i:j]\n\
+           \n\
+           Use of negative indices is not supported."),
+    SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
+           "x.__contains__(y) <==> y in x"),
+    SQSLOT("__iadd__", sq_inplace_concat, NULL,
+      wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
+    SQSLOT("__imul__", sq_inplace_repeat, NULL,
+      wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
+    {NULL}
+};
+
+/* Given a type pointer and an offset gotten from a slotdef entry, return a
+   pointer to the actual slot.  This is not quite the same as simply adding
+   the offset to the type pointer, since it takes care to indirect through the
+   proper indirection pointer (as_buffer, etc.); it returns NULL if the
+   indirection pointer is NULL. */
+static void **
+slotptr(PyTypeObject *type, int ioffset)
+{
+    char *ptr;
+    long offset = ioffset;
+
+    /* Note: this depends on the order of the members of PyHeapTypeObject! */
+    assert(offset >= 0);
+    assert((size_t)offset < offsetof(PyHeapTypeObject, as_buffer));
+    if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) {
+        ptr = (char *)type->tp_as_sequence;
+        offset -= offsetof(PyHeapTypeObject, as_sequence);
+    }
+    else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_mapping)) {
+        ptr = (char *)type->tp_as_mapping;
+        offset -= offsetof(PyHeapTypeObject, as_mapping);
+    }
+    else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_number)) {
+        ptr = (char *)type->tp_as_number;
+        offset -= offsetof(PyHeapTypeObject, as_number);
+    }
+    else {
+        ptr = (char *)type;
+    }
+    if (ptr != NULL)
+        ptr += offset;
+    return (void **)ptr;
+}
+
+/* Length of array of slotdef pointers used to store slots with the
+   same __name__.  There should be at most MAX_EQUIV-1 slotdef entries with
+   the same __name__, for any __name__. Since that's a static property, it is
+   appropriate to declare fixed-size arrays for this. */
+#define MAX_EQUIV 10
+
+/* Return a slot pointer for a given name, but ONLY if the attribute has
+   exactly one slot function.  The name must be an interned string. */
+static void **
+resolve_slotdups(PyTypeObject *type, PyObject *name)
+{
+    /* XXX Maybe this could be optimized more -- but is it worth it? */
+
+    /* pname and ptrs act as a little cache */
+    static PyObject *pname;
+    static slotdef *ptrs[MAX_EQUIV];
+    slotdef *p, **pp;
+    void **res, **ptr;
+
+    if (pname != name) {
+        /* Collect all slotdefs that match name into ptrs. */
+        pname = name;
+        pp = ptrs;
+        for (p = slotdefs; p->name_strobj; p++) {
+            if (p->name_strobj == name)
+                *pp++ = p;
+        }
+        *pp = NULL;
+    }
+
+    /* Look in all matching slots of the type; if exactly one of these has
+       a filled-in slot, return its value.      Otherwise return NULL. */
+    res = NULL;
+    for (pp = ptrs; *pp; pp++) {
+        ptr = slotptr(type, (*pp)->offset);
+        if (ptr == NULL || *ptr == NULL)
+            continue;
+        if (res != NULL)
+            return NULL;
+        res = ptr;
+    }
+    return res;
+}
+
+/* Common code for update_slots_callback() and fixup_slot_dispatchers().  This
+   does some incredibly complex thinking and then sticks something into the
+   slot.  (It sees if the adjacent slotdefs for the same slot have conflicting
+   interests, and then stores a generic wrapper or a specific function into
+   the slot.)  Return a pointer to the next slotdef with a different offset,
+   because that's convenient  for fixup_slot_dispatchers(). */
+static slotdef *
+update_one_slot(PyTypeObject *type, slotdef *p)
+{
+    PyObject *descr;
+    PyWrapperDescrObject *d;
+    void *generic = NULL, *specific = NULL;
+    int use_generic = 0;
+    int offset = p->offset;
+    void **ptr = slotptr(type, offset);
+
+    if (ptr == NULL) {
+        do {
+            ++p;
+        } while (p->offset == offset);
+        return p;
+    }
+    do {
+        descr = _PyType_Lookup(type, p->name_strobj);
+        if (descr == NULL) {
+            if (ptr == (void**)&type->tp_iternext) {
+                specific = _PyObject_NextNotImplemented;
+            }
+            continue;
+        }
+        if (Py_TYPE(descr) == &PyWrapperDescr_Type &&
+            ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) {
+            void **tptr = resolve_slotdups(type, p->name_strobj);
+            if (tptr == NULL || tptr == ptr)
+                generic = p->function;
+            d = (PyWrapperDescrObject *)descr;
+            if (d->d_base->wrapper == p->wrapper &&
+                PyType_IsSubtype(type, d->d_type))
+            {
+                if (specific == NULL ||
+                    specific == d->d_wrapped)
+                    specific = d->d_wrapped;
+                else
+                    use_generic = 1;
+            }
+        }
+        else if (Py_TYPE(descr) == &PyCFunction_Type &&
+                 PyCFunction_GET_FUNCTION(descr) ==
+                 (PyCFunction)tp_new_wrapper &&
+                 ptr == (void**)&type->tp_new)
+        {
+            /* The __new__ wrapper is not a wrapper descriptor,
+               so must be special-cased differently.
+               If we don't do this, creating an instance will
+               always use slot_tp_new which will look up
+               __new__ in the MRO which will call tp_new_wrapper
+               which will look through the base classes looking
+               for a static base and call its tp_new (usually
+               PyType_GenericNew), after performing various
+               sanity checks and constructing a new argument
+               list.  Cut all that nonsense short -- this speeds
+               up instance creation tremendously. */
+            specific = (void *)type->tp_new;
+            /* XXX I'm not 100% sure that there isn't a hole
+               in this reasoning that requires additional
+               sanity checks.  I'll buy the first person to
+               point out a bug in this reasoning a beer. */
+        }
+        else if (descr == Py_None &&
+                 ptr == (void**)&type->tp_hash) {
+            /* We specifically allow __hash__ to be set to None
+               to prevent inheritance of the default
+               implementation from object.__hash__ */
+            specific = PyObject_HashNotImplemented;
+        }
+        else {
+            use_generic = 1;
+            generic = p->function;
+        }
+    } while ((++p)->offset == offset);
+    if (specific && !use_generic)
+        *ptr = specific;
+    else
+        *ptr = generic;
+    return p;
+}
+
+/* In the type, update the slots whose slotdefs are gathered in the pp array.
+   This is a callback for update_subclasses(). */
+static int
+update_slots_callback(PyTypeObject *type, void *data)
+{
+    slotdef **pp = (slotdef **)data;
+
+    for (; *pp; pp++)
+        update_one_slot(type, *pp);
+    return 0;
+}
+
+/* Initialize the slotdefs table by adding interned string objects for the
+   names and sorting the entries. */
+static void
+init_slotdefs(void)
+{
+    slotdef *p;
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+    for (p = slotdefs; p->name; p++) {
+        /* Slots must be ordered by their offset in the PyHeapTypeObject. */
+        assert(!p[1].name || p->offset <= p[1].offset);
+        p->name_strobj = PyString_InternFromString(p->name);
+        if (!p->name_strobj)
+            Py_FatalError("Out of memory interning slotdef names");
+    }
+    initialized = 1;
+}
+
+/* Update the slots after assignment to a class (type) attribute. */
+static int
+update_slot(PyTypeObject *type, PyObject *name)
+{
+    slotdef *ptrs[MAX_EQUIV];
+    slotdef *p;
+    slotdef **pp;
+    int offset;
+
+    /* Clear the VALID_VERSION flag of 'type' and all its
+       subclasses.  This could possibly be unified with the
+       update_subclasses() recursion below, but carefully:
+       they each have their own conditions on which to stop
+       recursing into subclasses. */
+    PyType_Modified(type);
+
+    init_slotdefs();
+    pp = ptrs;
+    for (p = slotdefs; p->name; p++) {
+        /* XXX assume name is interned! */
+        if (p->name_strobj == name)
+            *pp++ = p;
+    }
+    *pp = NULL;
+    for (pp = ptrs; *pp; pp++) {
+        p = *pp;
+        offset = p->offset;
+        while (p > slotdefs && (p-1)->offset == offset)
+            --p;
+        *pp = p;
+    }
+    if (ptrs[0] == NULL)
+        return 0; /* Not an attribute that affects any slots */
+    return update_subclasses(type, name,
+                             update_slots_callback, (void *)ptrs);
+}
+
+/* Store the proper functions in the slot dispatches at class (type)
+   definition time, based upon which operations the class overrides in its
+   dict. */
+static void
+fixup_slot_dispatchers(PyTypeObject *type)
+{
+    slotdef *p;
+
+    init_slotdefs();
+    for (p = slotdefs; p->name; )
+        p = update_one_slot(type, p);
+}
+
+static void
+update_all_slots(PyTypeObject* type)
+{
+    slotdef *p;
+
+    init_slotdefs();
+    for (p = slotdefs; p->name; p++) {
+        /* update_slot returns int but can't actually fail */
+        update_slot(type, p->name_strobj);
+    }
+}
+
+/* recurse_down_subclasses() and update_subclasses() are mutually
+   recursive functions to call a callback for all subclasses,
+   but refraining from recursing into subclasses that define 'name'. */
+
+static int
+update_subclasses(PyTypeObject *type, PyObject *name,
+                  update_callback callback, void *data)
+{
+    if (callback(type, data) < 0)
+        return -1;
+    return recurse_down_subclasses(type, name, callback, data);
+}
+
+static int
+recurse_down_subclasses(PyTypeObject *type, PyObject *name,
+                        update_callback callback, void *data)
+{
+    PyTypeObject *subclass;
+    PyObject *ref, *subclasses, *dict;
+    Py_ssize_t i, n;
+
+    subclasses = type->tp_subclasses;
+    if (subclasses == NULL)
+        return 0;
+    assert(PyList_Check(subclasses));
+    n = PyList_GET_SIZE(subclasses);
+    for (i = 0; i < n; i++) {
+        ref = PyList_GET_ITEM(subclasses, i);
+        assert(PyWeakref_CheckRef(ref));
+        subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref);
+        assert(subclass != NULL);
+        if ((PyObject *)subclass == Py_None)
+            continue;
+        assert(PyType_Check(subclass));
+        /* Avoid recursing down into unaffected classes */
+        dict = subclass->tp_dict;
+        if (dict != NULL && PyDict_Check(dict) &&
+            PyDict_GetItem(dict, name) != NULL)
+            continue;
+        if (update_subclasses(subclass, name, callback, data) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+/* This function is called by PyType_Ready() to populate the type's
+   dictionary with method descriptors for function slots.  For each
+   function slot (like tp_repr) that's defined in the type, one or more
+   corresponding descriptors are added in the type's tp_dict dictionary
+   under the appropriate name (like __repr__).  Some function slots
+   cause more than one descriptor to be added (for example, the nb_add
+   slot adds both __add__ and __radd__ descriptors) and some function
+   slots compete for the same descriptor (for example both sq_item and
+   mp_subscript generate a __getitem__ descriptor).
+
+   In the latter case, the first slotdef entry encountered wins.  Since
+   slotdef entries are sorted by the offset of the slot in the
+   PyHeapTypeObject, this gives us some control over disambiguating
+   between competing slots: the members of PyHeapTypeObject are listed
+   from most general to least general, so the most general slot is
+   preferred.  In particular, because as_mapping comes before as_sequence,
+   for a type that defines both mp_subscript and sq_item, mp_subscript
+   wins.
+
+   This only adds new descriptors and doesn't overwrite entries in
+   tp_dict that were previously defined.  The descriptors contain a
+   reference to the C function they must call, so that it's safe if they
+   are copied into a subtype's __dict__ and the subtype has a different
+   C function in its slot -- calling the method defined by the
+   descriptor will call the C function that was used to create it,
+   rather than the C function present in the slot when it is called.
+   (This is important because a subtype may have a C function in the
+   slot that calls the method from the dictionary, and we want to avoid
+   infinite recursion here.) */
+
+static int
+add_operators(PyTypeObject *type)
+{
+    PyObject *dict = type->tp_dict;
+    slotdef *p;
+    PyObject *descr;
+    void **ptr;
+
+    init_slotdefs();
+    for (p = slotdefs; p->name; p++) {
+        if (p->wrapper == NULL)
+            continue;
+        ptr = slotptr(type, p->offset);
+        if (!ptr || !*ptr)
+            continue;
+        if (PyDict_GetItem(dict, p->name_strobj))
+            continue;
+        if (*ptr == PyObject_HashNotImplemented) {
+            /* Classes may prevent the inheritance of the tp_hash
+               slot by storing PyObject_HashNotImplemented in it. Make it
+               visible as a None value for the __hash__ attribute. */
+            if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0)
+                return -1;
+        }
+        else {
+            descr = PyDescr_NewWrapper(type, p, *ptr);
+            if (descr == NULL)
+                return -1;
+            if (PyDict_SetItem(dict, p->name_strobj, descr) < 0)
+                return -1;
+            Py_DECREF(descr);
+        }
+    }
+    if (type->tp_new != NULL) {
+        if (add_tp_new_wrapper(type) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+
+/* Cooperative 'super' */
+
+typedef struct {
+    PyObject_HEAD
+    PyTypeObject *type;
+    PyObject *obj;
+    PyTypeObject *obj_type;
+} superobject;
+
+static PyMemberDef super_members[] = {
+    {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY,
+     "the class invoking super()"},
+    {"__self__",  T_OBJECT, offsetof(superobject, obj), READONLY,
+     "the instance invoking super(); may be None"},
+    {"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY,
+     "the type of the instance invoking super(); may be None"},
+    {0}
+};
+
+static void
+super_dealloc(PyObject *self)
+{
+    superobject *su = (superobject *)self;
+
+    _PyObject_GC_UNTRACK(self);
+    Py_XDECREF(su->obj);
+    Py_XDECREF(su->type);
+    Py_XDECREF(su->obj_type);
+    Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject *
+super_repr(PyObject *self)
+{
+    superobject *su = (superobject *)self;
+
+    if (su->obj_type)
+        return PyString_FromFormat(
+            "<super: <class '%s'>, <%s object>>",
+            su->type ? su->type->tp_name : "NULL",
+            su->obj_type->tp_name);
+    else
+        return PyString_FromFormat(
+            "<super: <class '%s'>, NULL>",
+            su->type ? su->type->tp_name : "NULL");
+}
+
+static PyObject *
+super_getattro(PyObject *self, PyObject *name)
+{
+    superobject *su = (superobject *)self;
+    int skip = su->obj_type == NULL;
+
+    if (!skip) {
+        /* We want __class__ to return the class of the super object
+           (i.e. super, or a subclass), not the class of su->obj. */
+        skip = (PyString_Check(name) &&
+            PyString_GET_SIZE(name) == 9 &&
+            strcmp(PyString_AS_STRING(name), "__class__") == 0);
+    }
+
+    if (!skip) {
+        PyObject *mro, *res, *tmp, *dict;
+        PyTypeObject *starttype;
+        descrgetfunc f;
+        Py_ssize_t i, n;
+
+        starttype = su->obj_type;
+        mro = starttype->tp_mro;
+
+        if (mro == NULL)
+            n = 0;
+        else {
+            assert(PyTuple_Check(mro));
+            n = PyTuple_GET_SIZE(mro);
+        }
+        for (i = 0; i < n; i++) {
+            if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i))
+                break;
+        }
+        i++;
+        res = NULL;
+        for (; i < n; i++) {
+            tmp = PyTuple_GET_ITEM(mro, i);
+            if (PyType_Check(tmp))
+                dict = ((PyTypeObject *)tmp)->tp_dict;
+            else if (PyClass_Check(tmp))
+                dict = ((PyClassObject *)tmp)->cl_dict;
+            else
+                continue;
+            res = PyDict_GetItem(dict, name);
+            if (res != NULL) {
+                Py_INCREF(res);
+                f = Py_TYPE(res)->tp_descr_get;
+                if (f != NULL) {
+                    tmp = f(res,
+                        /* Only pass 'obj' param if
+                           this is instance-mode super
+                           (See SF ID #743627)
+                        */
+                        (su->obj == (PyObject *)
+                                    su->obj_type
+                            ? (PyObject *)NULL
+                            : su->obj),
+                        (PyObject *)starttype);
+                    Py_DECREF(res);
+                    res = tmp;
+                }
+                return res;
+            }
+        }
+    }
+    return PyObject_GenericGetAttr(self, name);
+}
+
+static PyTypeObject *
+supercheck(PyTypeObject *type, PyObject *obj)
+{
+    /* Check that a super() call makes sense.  Return a type object.
+
+       obj can be a new-style class, or an instance of one:
+
+       - If it is a class, it must be a subclass of 'type'.      This case is
+         used for class methods; the return value is obj.
+
+       - If it is an instance, it must be an instance of 'type'.  This is
+         the normal case; the return value is obj.__class__.
+
+       But... when obj is an instance, we want to allow for the case where
+       Py_TYPE(obj) is not a subclass of type, but obj.__class__ is!
+       This will allow using super() with a proxy for obj.
+    */
+
+    /* Check for first bullet above (special case) */
+    if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) {
+        Py_INCREF(obj);
+        return (PyTypeObject *)obj;
+    }
+
+    /* Normal case */
+    if (PyType_IsSubtype(Py_TYPE(obj), type)) {
+        Py_INCREF(Py_TYPE(obj));
+        return Py_TYPE(obj);
+    }
+    else {
+        /* Try the slow way */
+        static PyObject *class_str = NULL;
+        PyObject *class_attr;
+
+        if (class_str == NULL) {
+            class_str = PyString_FromString("__class__");
+            if (class_str == NULL)
+                return NULL;
+        }
+
+        class_attr = PyObject_GetAttr(obj, class_str);
+
+        if (class_attr != NULL &&
+            PyType_Check(class_attr) &&
+            (PyTypeObject *)class_attr != Py_TYPE(obj))
+        {
+            int ok = PyType_IsSubtype(
+                (PyTypeObject *)class_attr, type);
+            if (ok)
+                return (PyTypeObject *)class_attr;
+        }
+
+        if (class_attr == NULL)
+            PyErr_Clear();
+        else
+            Py_DECREF(class_attr);
+    }
+
+    PyErr_SetString(PyExc_TypeError,
+                    "super(type, obj): "
+                    "obj must be an instance or subtype of type");
+    return NULL;
+}
+
+static PyObject *
+super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    superobject *su = (superobject *)self;
+    superobject *newobj;
+
+    if (obj == NULL || obj == Py_None || su->obj != NULL) {
+        /* Not binding to an object, or already bound */
+        Py_INCREF(self);
+        return self;
+    }
+    if (Py_TYPE(su) != &PySuper_Type)
+        /* If su is an instance of a (strict) subclass of super,
+           call its type */
+        return PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(su),
+                                            su->type, obj, NULL);
+    else {
+        /* Inline the common case */
+        PyTypeObject *obj_type = supercheck(su->type, obj);
+        if (obj_type == NULL)
+            return NULL;
+        newobj = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
+                                                 NULL, NULL);
+        if (newobj == NULL)
+            return NULL;
+        Py_INCREF(su->type);
+        Py_INCREF(obj);
+        newobj->type = su->type;
+        newobj->obj = obj;
+        newobj->obj_type = obj_type;
+        return (PyObject *)newobj;
+    }
+}
+
+static int
+super_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    superobject *su = (superobject *)self;
+    PyTypeObject *type;
+    PyObject *obj = NULL;
+    PyTypeObject *obj_type = NULL;
+
+    if (!_PyArg_NoKeywords("super", kwds))
+        return -1;
+    if (!PyArg_ParseTuple(args, "O!|O:super", &PyType_Type, &type, &obj))
+        return -1;
+    if (obj == Py_None)
+        obj = NULL;
+    if (obj != NULL) {
+        obj_type = supercheck(type, obj);
+        if (obj_type == NULL)
+            return -1;
+        Py_INCREF(obj);
+    }
+    Py_INCREF(type);
+    su->type = type;
+    su->obj = obj;
+    su->obj_type = obj_type;
+    return 0;
+}
+
+PyDoc_STRVAR(super_doc,
+"super(type, obj) -> bound super object; requires isinstance(obj, type)\n"
+"super(type) -> unbound super object\n"
+"super(type, type2) -> bound super object; requires issubclass(type2, type)\n"
+"Typical use to call a cooperative superclass method:\n"
+"class C(B):\n"
+"    def meth(self, arg):\n"
+"        super(C, self).meth(arg)");
+
+static int
+super_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    superobject *su = (superobject *)self;
+
+    Py_VISIT(su->obj);
+    Py_VISIT(su->type);
+    Py_VISIT(su->obj_type);
+
+    return 0;
+}
+
+PyTypeObject PySuper_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "super",                                    /* tp_name */
+    sizeof(superobject),                        /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    /* methods */
+    super_dealloc,                              /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    super_repr,                                 /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    super_getattro,                             /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+        Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    super_doc,                                  /* tp_doc */
+    super_traverse,                             /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    0,                                          /* tp_iter */
+    0,                                          /* tp_iternext */
+    0,                                          /* tp_methods */
+    super_members,                              /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    super_descr_get,                            /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    super_init,                                 /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    PyType_GenericNew,                          /* tp_new */
+    PyObject_GC_Del,                            /* tp_free */
+};
diff --git a/Python-2.7.5/Objects/unicodectype.c b/Python-2.7.5/Objects/unicodectype.c
new file mode 100644
index 0000000..9c439a7
--- /dev/null
+++ b/Python-2.7.5/Objects/unicodectype.c
@@ -0,0 +1,215 @@
+/*
+   Unicode character type helpers.
+
+   Written by Marc-Andre Lemburg ([email protected]).
+   Modified for Python 2.0 by Fredrik Lundh ([email protected])
+
+   Copyright (c) Corporation for National Research Initiatives.
+
+*/
+
+#include "Python.h"
+#include "unicodeobject.h"
+
+#define ALPHA_MASK 0x01
+#define DECIMAL_MASK 0x02
+#define DIGIT_MASK 0x04
+#define LOWER_MASK 0x08
+#define LINEBREAK_MASK 0x10
+#define SPACE_MASK 0x20
+#define TITLE_MASK 0x40
+#define UPPER_MASK 0x80
+#define NODELTA_MASK 0x100
+#define NUMERIC_MASK 0x200
+
+typedef struct {
+    const Py_UNICODE upper;
+    const Py_UNICODE lower;
+    const Py_UNICODE title;
+    const unsigned char decimal;
+    const unsigned char digit;
+    const unsigned short flags;
+} _PyUnicode_TypeRecord;
+
+#include "unicodetype_db.h"
+
+static const _PyUnicode_TypeRecord *
+gettyperecord(Py_UNICODE code)
+{
+    int index;
+
+#ifdef Py_UNICODE_WIDE
+    if (code >= 0x110000)
+        index = 0;
+    else
+#endif
+    {
+        index = index1[(code>>SHIFT)];
+        index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
+    }
+
+    return &_PyUnicode_TypeRecords[index];
+}
+
+/* Returns the titlecase Unicode characters corresponding to ch or just
+   ch if no titlecase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+    int delta = ctype->title;
+
+    if (ctype->flags & NODELTA_MASK)
+	return delta;
+
+    if (delta >= 32768)
+	    delta -= 65536;
+
+    return ch + delta;
+}
+
+/* Returns 1 for Unicode characters having the category 'Lt', 0
+   otherwise. */
+
+int _PyUnicode_IsTitlecase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & TITLE_MASK) != 0;
+}
+
+/* Returns the integer decimal (0-9) for Unicode characters having
+   this property, -1 otherwise. */
+
+int _PyUnicode_ToDecimalDigit(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1;
+}
+
+int _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
+{
+    if (_PyUnicode_ToDecimalDigit(ch) < 0)
+	return 0;
+    return 1;
+}
+
+/* Returns the integer digit (0-9) for Unicode characters having
+   this property, -1 otherwise. */
+
+int _PyUnicode_ToDigit(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1;
+}
+
+int _PyUnicode_IsDigit(Py_UNICODE ch)
+{
+    if (_PyUnicode_ToDigit(ch) < 0)
+	return 0;
+    return 1;
+}
+
+/* Returns the numeric value as double for Unicode characters having
+   this property, -1.0 otherwise. */
+
+int _PyUnicode_IsNumeric(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & NUMERIC_MASK) != 0;
+}
+
+#ifndef WANT_WCTYPE_FUNCTIONS
+
+/* Returns 1 for Unicode characters having the category 'Ll', 0
+   otherwise. */
+
+int _PyUnicode_IsLowercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & LOWER_MASK) != 0;
+}
+
+/* Returns 1 for Unicode characters having the category 'Lu', 0
+   otherwise. */
+
+int _PyUnicode_IsUppercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & UPPER_MASK) != 0;
+}
+
+/* Returns the uppercase Unicode characters corresponding to ch or just
+   ch if no uppercase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+    int delta = ctype->upper;
+    if (ctype->flags & NODELTA_MASK)
+	return delta;
+    if (delta >= 32768)
+	    delta -= 65536;
+    return ch + delta;
+}
+
+/* Returns the lowercase Unicode characters corresponding to ch or just
+   ch if no lowercase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+    int delta = ctype->lower;
+    if (ctype->flags & NODELTA_MASK)
+	return delta;
+    if (delta >= 32768)
+	    delta -= 65536;
+    return ch + delta;
+}
+
+/* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt',
+   'Lo' or 'Lm',  0 otherwise. */
+
+int _PyUnicode_IsAlpha(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & ALPHA_MASK) != 0;
+}
+
+#else
+
+/* Export the interfaces using the wchar_t type for portability
+   reasons:  */
+
+int _PyUnicode_IsLowercase(Py_UNICODE ch)
+{
+    return iswlower(ch);
+}
+
+int _PyUnicode_IsUppercase(Py_UNICODE ch)
+{
+    return iswupper(ch);
+}
+
+Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+{
+    return towlower(ch);
+}
+
+Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+{
+    return towupper(ch);
+}
+
+int _PyUnicode_IsAlpha(Py_UNICODE ch)
+{
+    return iswalpha(ch);
+}
+
+#endif
diff --git a/Python-2.7.5/Objects/unicodeobject.c b/Python-2.7.5/Objects/unicodeobject.c
new file mode 100644
index 0000000..0ead06f
--- /dev/null
+++ b/Python-2.7.5/Objects/unicodeobject.c
@@ -0,0 +1,8906 @@
+/*
+
+Unicode implementation based on original code by Fredrik Lundh,
+modified by Marc-Andre Lemburg <[email protected]> according to the
+Unicode Integration Proposal (see file Misc/unicode.txt).
+
+Major speed upgrades to the method implementations at the Reykjavik
+NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke.
+
+Copyright (c) Corporation for National Research Initiatives.
+
+--------------------------------------------------------------------
+The original string type implementation is:
+
+  Copyright (c) 1999 by Secret Labs AB
+  Copyright (c) 1999 by Fredrik Lundh
+
+By obtaining, using, and/or copying this software and/or its
+associated documentation, you agree that you have read, understood,
+and will comply with the following terms and conditions:
+
+Permission to use, copy, modify, and distribute this software and its
+associated documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies, and that both that copyright notice and this permission notice
+appear in supporting documentation, and that the name of Secret Labs
+AB or the author not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--------------------------------------------------------------------
+
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+#include "unicodeobject.h"
+#include "ucnhash.h"
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+/* Limit for the Unicode object free list */
+
+#define PyUnicode_MAXFREELIST       1024
+
+/* Limit for the Unicode object free list stay alive optimization.
+
+   The implementation will keep allocated Unicode memory intact for
+   all objects on the free list having a size less than this
+   limit. This reduces malloc() overhead for small Unicode objects.
+
+   At worst this will result in PyUnicode_MAXFREELIST *
+   (sizeof(PyUnicodeObject) + KEEPALIVE_SIZE_LIMIT +
+   malloc()-overhead) bytes of unused garbage.
+
+   Setting the limit to 0 effectively turns the feature off.
+
+   Note: This is an experimental feature ! If you get core dumps when
+   using Unicode objects, turn this feature off.
+
+*/
+
+#define KEEPALIVE_SIZE_LIMIT       9
+
+/* Endianness switches; defaults to little endian */
+
+#ifdef WORDS_BIGENDIAN
+# define BYTEORDER_IS_BIG_ENDIAN
+#else
+# define BYTEORDER_IS_LITTLE_ENDIAN
+#endif
+
+/* --- Globals ------------------------------------------------------------
+
+NOTE: In the interpreter's initialization phase, some globals are currently
+      initialized dynamically as needed. In the process Unicode objects may
+      be created before the Unicode type is ready.
+
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Free list for Unicode objects */
+static PyUnicodeObject *free_list = NULL;
+static int numfree = 0;
+
+/* The empty Unicode object is shared to improve performance. */
+static PyUnicodeObject *unicode_empty = NULL;
+
+#define _Py_RETURN_UNICODE_EMPTY()                      \
+    do {                                                \
+        if (unicode_empty != NULL)                      \
+            Py_INCREF(unicode_empty);                   \
+        else {                                          \
+            unicode_empty = _PyUnicode_New(0);          \
+            if (unicode_empty != NULL)                  \
+                Py_INCREF(unicode_empty);               \
+        }                                               \
+        return (PyObject *)unicode_empty;               \
+    } while (0)
+
+/* Single character Unicode strings in the Latin-1 range are being
+   shared as well. */
+static PyUnicodeObject *unicode_latin1[256] = {NULL};
+
+/* Default encoding to use and assume when NULL is passed as encoding
+   parameter; it is initialized by _PyUnicode_Init().
+
+   Always use the PyUnicode_SetDefaultEncoding() and
+   PyUnicode_GetDefaultEncoding() APIs to access this global.
+
+*/
+static char unicode_default_encoding[100 + 1] = "ascii";
+
+/* Fast detection of the most frequent whitespace characters */
+const unsigned char _Py_ascii_whitespace[] = {
+    0, 0, 0, 0, 0, 0, 0, 0,
+/*     case 0x0009: * CHARACTER TABULATION */
+/*     case 0x000A: * LINE FEED */
+/*     case 0x000B: * LINE TABULATION */
+/*     case 0x000C: * FORM FEED */
+/*     case 0x000D: * CARRIAGE RETURN */
+    0, 1, 1, 1, 1, 1, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+/*     case 0x001C: * FILE SEPARATOR */
+/*     case 0x001D: * GROUP SEPARATOR */
+/*     case 0x001E: * RECORD SEPARATOR */
+/*     case 0x001F: * UNIT SEPARATOR */
+    0, 0, 0, 0, 1, 1, 1, 1,
+/*     case 0x0020: * SPACE */
+    1, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Same for linebreaks */
+static unsigned char ascii_linebreak[] = {
+    0, 0, 0, 0, 0, 0, 0, 0,
+/*         0x000A, * LINE FEED */
+/*         0x000B, * LINE TABULATION */
+/*         0x000C, * FORM FEED */
+/*         0x000D, * CARRIAGE RETURN */
+    0, 0, 1, 1, 1, 1, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+/*         0x001C, * FILE SEPARATOR */
+/*         0x001D, * GROUP SEPARATOR */
+/*         0x001E, * RECORD SEPARATOR */
+    0, 0, 0, 0, 1, 1, 1, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+Py_UNICODE
+PyUnicode_GetMax(void)
+{
+#ifdef Py_UNICODE_WIDE
+    return 0x10FFFF;
+#else
+    /* This is actually an illegal character, so it should
+       not be passed to unichr. */
+    return 0xFFFF;
+#endif
+}
+
+/* --- Bloom Filters ----------------------------------------------------- */
+
+/* stuff to implement simple "bloom filters" for Unicode characters.
+   to keep things simple, we use a single bitmask, using the least 5
+   bits from each unicode characters as the bit index. */
+
+/* the linebreak mask is set up by Unicode_Init below */
+
+#if LONG_BIT >= 128
+#define BLOOM_WIDTH 128
+#elif LONG_BIT >= 64
+#define BLOOM_WIDTH 64
+#elif LONG_BIT >= 32
+#define BLOOM_WIDTH 32
+#else
+#error "LONG_BIT is smaller than 32"
+#endif
+
+#define BLOOM_MASK unsigned long
+
+static BLOOM_MASK bloom_linebreak = ~(BLOOM_MASK)0;
+
+#define BLOOM_ADD(mask, ch) ((mask |= (1UL << ((ch) & (BLOOM_WIDTH - 1)))))
+#define BLOOM(mask, ch)     ((mask &  (1UL << ((ch) & (BLOOM_WIDTH - 1)))))
+
+#define BLOOM_LINEBREAK(ch)                                             \
+    ((ch) < 128U ? ascii_linebreak[(ch)] :                              \
+     (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch)))
+
+Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len)
+{
+    /* calculate simple bloom-style bitmask for a given unicode string */
+
+    BLOOM_MASK mask;
+    Py_ssize_t i;
+
+    mask = 0;
+    for (i = 0; i < len; i++)
+        BLOOM_ADD(mask, ptr[i]);
+
+    return mask;
+}
+
+Py_LOCAL_INLINE(int) unicode_member(Py_UNICODE chr, Py_UNICODE* set, Py_ssize_t setlen)
+{
+    Py_ssize_t i;
+
+    for (i = 0; i < setlen; i++)
+        if (set[i] == chr)
+            return 1;
+
+    return 0;
+}
+
+#define BLOOM_MEMBER(mask, chr, set, setlen)                    \
+    BLOOM(mask, chr) && unicode_member(chr, set, setlen)
+
+/* --- Unicode Object ----------------------------------------------------- */
+
+static
+int unicode_resize(register PyUnicodeObject *unicode,
+                   Py_ssize_t length)
+{
+    void *oldstr;
+
+    /* Shortcut if there's nothing much to do. */
+    if (unicode->length == length)
+        goto reset;
+
+    /* Resizing shared object (unicode_empty or single character
+       objects) in-place is not allowed. Use PyUnicode_Resize()
+       instead ! */
+
+    if (unicode == unicode_empty ||
+        (unicode->length == 1 &&
+         unicode->str[0] < 256U &&
+         unicode_latin1[unicode->str[0]] == unicode)) {
+        PyErr_SetString(PyExc_SystemError,
+                        "can't resize shared unicode objects");
+        return -1;
+    }
+
+    /* We allocate one more byte to make sure the string is Ux0000 terminated.
+       The overallocation is also used by fastsearch, which assumes that it's
+       safe to look at str[length] (without making any assumptions about what
+       it contains). */
+
+    oldstr = unicode->str;
+    unicode->str = PyObject_REALLOC(unicode->str,
+                                    sizeof(Py_UNICODE) * (length + 1));
+    if (!unicode->str) {
+        unicode->str = (Py_UNICODE *)oldstr;
+        PyErr_NoMemory();
+        return -1;
+    }
+    unicode->str[length] = 0;
+    unicode->length = length;
+
+  reset:
+    /* Reset the object caches */
+    if (unicode->defenc) {
+        Py_CLEAR(unicode->defenc);
+    }
+    unicode->hash = -1;
+
+    return 0;
+}
+
+/* We allocate one more byte to make sure the string is
+   Ux0000 terminated; some code relies on that.
+
+   XXX This allocator could further be enhanced by assuring that the
+   free list never reduces its size below 1.
+
+*/
+
+static
+PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
+{
+    register PyUnicodeObject *unicode;
+
+    /* Optimization for empty strings */
+    if (length == 0 && unicode_empty != NULL) {
+        Py_INCREF(unicode_empty);
+        return unicode_empty;
+    }
+
+    /* Ensure we won't overflow the size. */
+    if (length > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) {
+        return (PyUnicodeObject *)PyErr_NoMemory();
+    }
+
+    /* Unicode freelist & memory allocation */
+    if (free_list) {
+        unicode = free_list;
+        free_list = *(PyUnicodeObject **)unicode;
+        numfree--;
+        if (unicode->str) {
+            /* Keep-Alive optimization: we only upsize the buffer,
+               never downsize it. */
+            if ((unicode->length < length) &&
+                unicode_resize(unicode, length) < 0) {
+                PyObject_DEL(unicode->str);
+                unicode->str = NULL;
+            }
+        }
+        else {
+            size_t new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
+            unicode->str = (Py_UNICODE*) PyObject_MALLOC(new_size);
+        }
+        PyObject_INIT(unicode, &PyUnicode_Type);
+    }
+    else {
+        size_t new_size;
+        unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type);
+        if (unicode == NULL)
+            return NULL;
+        new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
+        unicode->str = (Py_UNICODE*) PyObject_MALLOC(new_size);
+    }
+
+    if (!unicode->str) {
+        PyErr_NoMemory();
+        goto onError;
+    }
+    /* Initialize the first element to guard against cases where
+     * the caller fails before initializing str -- unicode_resize()
+     * reads str[0], and the Keep-Alive optimization can keep memory
+     * allocated for str alive across a call to unicode_dealloc(unicode).
+     * We don't want unicode_resize to read uninitialized memory in
+     * that case.
+     */
+    unicode->str[0] = 0;
+    unicode->str[length] = 0;
+    unicode->length = length;
+    unicode->hash = -1;
+    unicode->defenc = NULL;
+    return unicode;
+
+  onError:
+    /* XXX UNREF/NEWREF interface should be more symmetrical */
+    _Py_DEC_REFTOTAL;
+    _Py_ForgetReference((PyObject *)unicode);
+    PyObject_Del(unicode);
+    return NULL;
+}
+
+static
+void unicode_dealloc(register PyUnicodeObject *unicode)
+{
+    if (PyUnicode_CheckExact(unicode) &&
+        numfree < PyUnicode_MAXFREELIST) {
+        /* Keep-Alive optimization */
+        if (unicode->length >= KEEPALIVE_SIZE_LIMIT) {
+            PyObject_DEL(unicode->str);
+            unicode->str = NULL;
+            unicode->length = 0;
+        }
+        if (unicode->defenc) {
+            Py_CLEAR(unicode->defenc);
+        }
+        /* Add to free list */
+        *(PyUnicodeObject **)unicode = free_list;
+        free_list = unicode;
+        numfree++;
+    }
+    else {
+        PyObject_DEL(unicode->str);
+        Py_XDECREF(unicode->defenc);
+        Py_TYPE(unicode)->tp_free((PyObject *)unicode);
+    }
+}
+
+static
+int _PyUnicode_Resize(PyUnicodeObject **unicode, Py_ssize_t length)
+{
+    register PyUnicodeObject *v;
+
+    /* Argument checks */
+    if (unicode == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    v = *unicode;
+    if (v == NULL || !PyUnicode_Check(v) || Py_REFCNT(v) != 1 || length < 0) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+
+    /* Resizing unicode_empty and single character objects is not
+       possible since these are being shared. We simply return a fresh
+       copy with the same Unicode content. */
+    if (v->length != length &&
+        (v == unicode_empty || v->length == 1)) {
+        PyUnicodeObject *w = _PyUnicode_New(length);
+        if (w == NULL)
+            return -1;
+        Py_UNICODE_COPY(w->str, v->str,
+                        length < v->length ? length : v->length);
+        Py_DECREF(*unicode);
+        *unicode = w;
+        return 0;
+    }
+
+    /* Note that we don't have to modify *unicode for unshared Unicode
+       objects, since we can modify them in-place. */
+    return unicode_resize(v, length);
+}
+
+int PyUnicode_Resize(PyObject **unicode, Py_ssize_t length)
+{
+    return _PyUnicode_Resize((PyUnicodeObject **)unicode, length);
+}
+
+PyObject *PyUnicode_FromUnicode(const Py_UNICODE *u,
+                                Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+
+    /* If the Unicode data is known at construction time, we can apply
+       some optimizations which share commonly used objects. */
+    if (u != NULL) {
+
+        /* Optimization for empty strings */
+        if (size == 0)
+            _Py_RETURN_UNICODE_EMPTY();
+
+        /* Single character Unicode objects in the Latin-1 range are
+           shared when using this constructor */
+        if (size == 1 && *u < 256) {
+            unicode = unicode_latin1[*u];
+            if (!unicode) {
+                unicode = _PyUnicode_New(1);
+                if (!unicode)
+                    return NULL;
+                unicode->str[0] = *u;
+                unicode_latin1[*u] = unicode;
+            }
+            Py_INCREF(unicode);
+            return (PyObject *)unicode;
+        }
+    }
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+
+    /* Copy the Unicode data into the new object */
+    if (u != NULL)
+        Py_UNICODE_COPY(unicode->str, u, size);
+
+    return (PyObject *)unicode;
+}
+
+PyObject *PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+
+    if (size < 0) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Negative size passed to PyUnicode_FromStringAndSize");
+        return NULL;
+    }
+
+    /* If the Unicode data is known at construction time, we can apply
+       some optimizations which share commonly used objects.
+       Also, this means the input must be UTF-8, so fall back to the
+       UTF-8 decoder at the end. */
+    if (u != NULL) {
+
+        /* Optimization for empty strings */
+        if (size == 0)
+            _Py_RETURN_UNICODE_EMPTY();
+
+        /* Single characters are shared when using this constructor.
+           Restrict to ASCII, since the input must be UTF-8. */
+        if (size == 1 && Py_CHARMASK(*u) < 128) {
+            unicode = unicode_latin1[Py_CHARMASK(*u)];
+            if (!unicode) {
+                unicode = _PyUnicode_New(1);
+                if (!unicode)
+                    return NULL;
+                unicode->str[0] = Py_CHARMASK(*u);
+                unicode_latin1[Py_CHARMASK(*u)] = unicode;
+            }
+            Py_INCREF(unicode);
+            return (PyObject *)unicode;
+        }
+
+        return PyUnicode_DecodeUTF8(u, size, NULL);
+    }
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+
+    return (PyObject *)unicode;
+}
+
+PyObject *PyUnicode_FromString(const char *u)
+{
+    size_t size = strlen(u);
+    if (size > PY_SSIZE_T_MAX) {
+        PyErr_SetString(PyExc_OverflowError, "input too long");
+        return NULL;
+    }
+
+    return PyUnicode_FromStringAndSize(u, size);
+}
+
+#ifdef HAVE_WCHAR_H
+
+#if (Py_UNICODE_SIZE == 2) && defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
+# define CONVERT_WCHAR_TO_SURROGATES
+#endif
+
+#ifdef CONVERT_WCHAR_TO_SURROGATES
+
+/* Here sizeof(wchar_t) is 4 but Py_UNICODE_SIZE == 2, so we need
+   to convert from UTF32 to UTF16. */
+
+PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
+                                 Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+    register Py_ssize_t i;
+    Py_ssize_t alloc;
+    const wchar_t *orig_w;
+
+    if (w == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+
+    alloc = size;
+    orig_w = w;
+    for (i = size; i > 0; i--) {
+        if (*w > 0xFFFF)
+            alloc++;
+        w++;
+    }
+    w = orig_w;
+    unicode = _PyUnicode_New(alloc);
+    if (!unicode)
+        return NULL;
+
+    /* Copy the wchar_t data into the new object */
+    {
+        register Py_UNICODE *u;
+        u = PyUnicode_AS_UNICODE(unicode);
+        for (i = size; i > 0; i--) {
+            if (*w > 0xFFFF) {
+                wchar_t ordinal = *w++;
+                ordinal -= 0x10000;
+                *u++ = 0xD800 | (ordinal >> 10);
+                *u++ = 0xDC00 | (ordinal & 0x3FF);
+            }
+            else
+                *u++ = *w++;
+        }
+    }
+    return (PyObject *)unicode;
+}
+
+#else
+
+PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
+                                 Py_ssize_t size)
+{
+    PyUnicodeObject *unicode;
+
+    if (w == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+
+    /* Copy the wchar_t data into the new object */
+#ifdef HAVE_USABLE_WCHAR_T
+    memcpy(unicode->str, w, size * sizeof(wchar_t));
+#else
+    {
+        register Py_UNICODE *u;
+        register Py_ssize_t i;
+        u = PyUnicode_AS_UNICODE(unicode);
+        for (i = size; i > 0; i--)
+            *u++ = *w++;
+    }
+#endif
+
+    return (PyObject *)unicode;
+}
+
+#endif /* CONVERT_WCHAR_TO_SURROGATES */
+
+#undef CONVERT_WCHAR_TO_SURROGATES
+
+static void
+makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int precision, char c)
+{
+    *fmt++ = '%';
+    if (width) {
+        if (zeropad)
+            *fmt++ = '0';
+        fmt += sprintf(fmt, "%d", width);
+    }
+    if (precision)
+        fmt += sprintf(fmt, ".%d", precision);
+    if (longflag)
+        *fmt++ = 'l';
+    else if (size_tflag) {
+        char *f = PY_FORMAT_SIZE_T;
+        while (*f)
+            *fmt++ = *f++;
+    }
+    *fmt++ = c;
+    *fmt = '\0';
+}
+
+#define appendstring(string) {for (copy = string;*copy;) *s++ = *copy++;}
+
+PyObject *
+PyUnicode_FromFormatV(const char *format, va_list vargs)
+{
+    va_list count;
+    Py_ssize_t callcount = 0;
+    PyObject **callresults = NULL;
+    PyObject **callresult = NULL;
+    Py_ssize_t n = 0;
+    int width = 0;
+    int precision = 0;
+    int zeropad;
+    const char* f;
+    Py_UNICODE *s;
+    PyObject *string;
+    /* used by sprintf */
+    char buffer[21];
+    /* use abuffer instead of buffer, if we need more space
+     * (which can happen if there's a format specifier with width). */
+    char *abuffer = NULL;
+    char *realbuffer;
+    Py_ssize_t abuffersize = 0;
+    char fmt[60]; /* should be enough for %0width.precisionld */
+    const char *copy;
+
+#ifdef VA_LIST_IS_ARRAY
+    Py_MEMCPY(count, vargs, sizeof(va_list));
+#else
+#ifdef  __va_copy
+    __va_copy(count, vargs);
+#else
+    count = vargs;
+#endif
+#endif
+     /* step 1: count the number of %S/%R/%s format specifications
+      * (we call PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() for these
+      * objects once during step 3 and put the result in an array) */
+    for (f = format; *f; f++) {
+         if (*f == '%') {
+             if (*(f+1)=='%')
+                 continue;
+             if (*(f+1)=='S' || *(f+1)=='R')
+                 ++callcount;
+             while (isdigit((unsigned)*f))
+                 width = (width*10) + *f++ - '0';
+             while (*++f && *f != '%' && !isalpha((unsigned)*f))
+                 ;
+             if (*f == 's')
+                 ++callcount;
+         }
+    }
+    /* step 2: allocate memory for the results of
+     * PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() calls */
+    if (callcount) {
+        callresults = PyObject_Malloc(sizeof(PyObject *)*callcount);
+        if (!callresults) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+        callresult = callresults;
+    }
+    /* step 3: figure out how large a buffer we need */
+    for (f = format; *f; f++) {
+        if (*f == '%') {
+            const char* p = f;
+            width = 0;
+            while (isdigit((unsigned)*f))
+                width = (width*10) + *f++ - '0';
+            while (*++f && *f != '%' && !isalpha((unsigned)*f))
+                ;
+
+            /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+             * they don't affect the amount of space we reserve.
+             */
+            if ((*f == 'l' || *f == 'z') &&
+                (f[1] == 'd' || f[1] == 'u'))
+                ++f;
+
+            switch (*f) {
+            case 'c':
+                (void)va_arg(count, int);
+                /* fall through... */
+            case '%':
+                n++;
+                break;
+            case 'd': case 'u': case 'i': case 'x':
+                (void) va_arg(count, int);
+                /* 20 bytes is enough to hold a 64-bit
+                   integer.  Decimal takes the most space.
+                   This isn't enough for octal.
+                   If a width is specified we need more
+                   (which we allocate later). */
+                if (width < 20)
+                    width = 20;
+                n += width;
+                if (abuffersize < width)
+                    abuffersize = width;
+                break;
+            case 's':
+            {
+                /* UTF-8 */
+                const char *s = va_arg(count, const char*);
+                PyObject *str = PyUnicode_DecodeUTF8(s, strlen(s), "replace");
+                if (!str)
+                    goto fail;
+                n += PyUnicode_GET_SIZE(str);
+                /* Remember the str and switch to the next slot */
+                *callresult++ = str;
+                break;
+            }
+            case 'U':
+            {
+                PyObject *obj = va_arg(count, PyObject *);
+                assert(obj && PyUnicode_Check(obj));
+                n += PyUnicode_GET_SIZE(obj);
+                break;
+            }
+            case 'V':
+            {
+                PyObject *obj = va_arg(count, PyObject *);
+                const char *str = va_arg(count, const char *);
+                assert(obj || str);
+                assert(!obj || PyUnicode_Check(obj));
+                if (obj)
+                    n += PyUnicode_GET_SIZE(obj);
+                else
+                    n += strlen(str);
+                break;
+            }
+            case 'S':
+            {
+                PyObject *obj = va_arg(count, PyObject *);
+                PyObject *str;
+                assert(obj);
+                str = PyObject_Str(obj);
+                if (!str)
+                    goto fail;
+                n += PyUnicode_GET_SIZE(str);
+                /* Remember the str and switch to the next slot */
+                *callresult++ = str;
+                break;
+            }
+            case 'R':
+            {
+                PyObject *obj = va_arg(count, PyObject *);
+                PyObject *repr;
+                assert(obj);
+                repr = PyObject_Repr(obj);
+                if (!repr)
+                    goto fail;
+                n += PyUnicode_GET_SIZE(repr);
+                /* Remember the repr and switch to the next slot */
+                *callresult++ = repr;
+                break;
+            }
+            case 'p':
+                (void) va_arg(count, int);
+                /* maximum 64-bit pointer representation:
+                 * 0xffffffffffffffff
+                 * so 19 characters is enough.
+                 * XXX I count 18 -- what's the extra for?
+                 */
+                n += 19;
+                break;
+            default:
+                /* if we stumble upon an unknown
+                   formatting code, copy the rest of
+                   the format string to the output
+                   string. (we cannot just skip the
+                   code, since there's no way to know
+                   what's in the argument list) */
+                n += strlen(p);
+                goto expand;
+            }
+        } else
+            n++;
+    }
+  expand:
+    if (abuffersize > 20) {
+        abuffer = PyObject_Malloc(abuffersize);
+        if (!abuffer) {
+            PyErr_NoMemory();
+            goto fail;
+        }
+        realbuffer = abuffer;
+    }
+    else
+        realbuffer = buffer;
+    /* step 4: fill the buffer */
+    /* Since we've analyzed how much space we need for the worst case,
+       we don't have to resize the string.
+       There can be no errors beyond this point. */
+    string = PyUnicode_FromUnicode(NULL, n);
+    if (!string)
+        goto fail;
+
+    s = PyUnicode_AS_UNICODE(string);
+    callresult = callresults;
+
+    for (f = format; *f; f++) {
+        if (*f == '%') {
+            const char* p = f++;
+            int longflag = 0;
+            int size_tflag = 0;
+            zeropad = (*f == '0');
+            /* parse the width.precision part */
+            width = 0;
+            while (isdigit((unsigned)*f))
+                width = (width*10) + *f++ - '0';
+            precision = 0;
+            if (*f == '.') {
+                f++;
+                while (isdigit((unsigned)*f))
+                    precision = (precision*10) + *f++ - '0';
+            }
+            /* handle the long flag, but only for %ld and %lu.
+               others can be added when necessary. */
+            if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) {
+                longflag = 1;
+                ++f;
+            }
+            /* handle the size_t flag. */
+            if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+                size_tflag = 1;
+                ++f;
+            }
+
+            switch (*f) {
+            case 'c':
+                *s++ = va_arg(vargs, int);
+                break;
+            case 'd':
+                makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'd');
+                if (longflag)
+                    sprintf(realbuffer, fmt, va_arg(vargs, long));
+                else if (size_tflag)
+                    sprintf(realbuffer, fmt, va_arg(vargs, Py_ssize_t));
+                else
+                    sprintf(realbuffer, fmt, va_arg(vargs, int));
+                appendstring(realbuffer);
+                break;
+            case 'u':
+                makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'u');
+                if (longflag)
+                    sprintf(realbuffer, fmt, va_arg(vargs, unsigned long));
+                else if (size_tflag)
+                    sprintf(realbuffer, fmt, va_arg(vargs, size_t));
+                else
+                    sprintf(realbuffer, fmt, va_arg(vargs, unsigned int));
+                appendstring(realbuffer);
+                break;
+            case 'i':
+                makefmt(fmt, 0, 0, zeropad, width, precision, 'i');
+                sprintf(realbuffer, fmt, va_arg(vargs, int));
+                appendstring(realbuffer);
+                break;
+            case 'x':
+                makefmt(fmt, 0, 0, zeropad, width, precision, 'x');
+                sprintf(realbuffer, fmt, va_arg(vargs, int));
+                appendstring(realbuffer);
+                break;
+            case 's':
+            {
+                /* unused, since we already have the result */
+                (void) va_arg(vargs, char *);
+                Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(*callresult),
+                                PyUnicode_GET_SIZE(*callresult));
+                s += PyUnicode_GET_SIZE(*callresult);
+                /* We're done with the unicode()/repr() => forget it */
+                Py_DECREF(*callresult);
+                /* switch to next unicode()/repr() result */
+                ++callresult;
+                break;
+            }
+            case 'U':
+            {
+                PyObject *obj = va_arg(vargs, PyObject *);
+                Py_ssize_t size = PyUnicode_GET_SIZE(obj);
+                Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
+                s += size;
+                break;
+            }
+            case 'V':
+            {
+                PyObject *obj = va_arg(vargs, PyObject *);
+                const char *str = va_arg(vargs, const char *);
+                if (obj) {
+                    Py_ssize_t size = PyUnicode_GET_SIZE(obj);
+                    Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
+                    s += size;
+                } else {
+                    appendstring(str);
+                }
+                break;
+            }
+            case 'S':
+            case 'R':
+            {
+                Py_UNICODE *ucopy;
+                Py_ssize_t usize;
+                Py_ssize_t upos;
+                /* unused, since we already have the result */
+                (void) va_arg(vargs, PyObject *);
+                ucopy = PyUnicode_AS_UNICODE(*callresult);
+                usize = PyUnicode_GET_SIZE(*callresult);
+                for (upos = 0; upos<usize;)
+                    *s++ = ucopy[upos++];
+                /* We're done with the unicode()/repr() => forget it */
+                Py_DECREF(*callresult);
+                /* switch to next unicode()/repr() result */
+                ++callresult;
+                break;
+            }
+            case 'p':
+                sprintf(buffer, "%p", va_arg(vargs, void*));
+                /* %p is ill-defined:  ensure leading 0x. */
+                if (buffer[1] == 'X')
+                    buffer[1] = 'x';
+                else if (buffer[1] != 'x') {
+                    memmove(buffer+2, buffer, strlen(buffer)+1);
+                    buffer[0] = '0';
+                    buffer[1] = 'x';
+                }
+                appendstring(buffer);
+                break;
+            case '%':
+                *s++ = '%';
+                break;
+            default:
+                appendstring(p);
+                goto end;
+            }
+        } else
+            *s++ = *f;
+    }
+
+  end:
+    if (callresults)
+        PyObject_Free(callresults);
+    if (abuffer)
+        PyObject_Free(abuffer);
+    PyUnicode_Resize(&string, s - PyUnicode_AS_UNICODE(string));
+    return string;
+  fail:
+    if (callresults) {
+        PyObject **callresult2 = callresults;
+        while (callresult2 < callresult) {
+            Py_DECREF(*callresult2);
+            ++callresult2;
+        }
+        PyObject_Free(callresults);
+    }
+    if (abuffer)
+        PyObject_Free(abuffer);
+    return NULL;
+}
+
+#undef appendstring
+
+PyObject *
+PyUnicode_FromFormat(const char *format, ...)
+{
+    PyObject* ret;
+    va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+    va_start(vargs, format);
+#else
+    va_start(vargs);
+#endif
+    ret = PyUnicode_FromFormatV(format, vargs);
+    va_end(vargs);
+    return ret;
+}
+
+Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,
+                                wchar_t *w,
+                                Py_ssize_t size)
+{
+    if (unicode == NULL) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+
+    /* If possible, try to copy the 0-termination as well */
+    if (size > PyUnicode_GET_SIZE(unicode))
+        size = PyUnicode_GET_SIZE(unicode) + 1;
+
+#ifdef HAVE_USABLE_WCHAR_T
+    memcpy(w, unicode->str, size * sizeof(wchar_t));
+#else
+    {
+        register Py_UNICODE *u;
+        register Py_ssize_t i;
+        u = PyUnicode_AS_UNICODE(unicode);
+        for (i = size; i > 0; i--)
+            *w++ = *u++;
+    }
+#endif
+
+    if (size > PyUnicode_GET_SIZE(unicode))
+        return PyUnicode_GET_SIZE(unicode);
+    else
+        return size;
+}
+
+#endif
+
+PyObject *PyUnicode_FromOrdinal(int ordinal)
+{
+    Py_UNICODE s[1];
+
+#ifdef Py_UNICODE_WIDE
+    if (ordinal < 0 || ordinal > 0x10ffff) {
+        PyErr_SetString(PyExc_ValueError,
+                        "unichr() arg not in range(0x110000) "
+                        "(wide Python build)");
+        return NULL;
+    }
+#else
+    if (ordinal < 0 || ordinal > 0xffff) {
+        PyErr_SetString(PyExc_ValueError,
+                        "unichr() arg not in range(0x10000) "
+                        "(narrow Python build)");
+        return NULL;
+    }
+#endif
+
+    s[0] = (Py_UNICODE)ordinal;
+    return PyUnicode_FromUnicode(s, 1);
+}
+
+PyObject *PyUnicode_FromObject(register PyObject *obj)
+{
+    /* XXX Perhaps we should make this API an alias of
+       PyObject_Unicode() instead ?! */
+    if (PyUnicode_CheckExact(obj)) {
+        Py_INCREF(obj);
+        return obj;
+    }
+    if (PyUnicode_Check(obj)) {
+        /* For a Unicode subtype that's not a Unicode object,
+           return a true Unicode object with the same data. */
+        return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
+                                     PyUnicode_GET_SIZE(obj));
+    }
+    return PyUnicode_FromEncodedObject(obj, NULL, "strict");
+}
+
+PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
+                                      const char *encoding,
+                                      const char *errors)
+{
+    const char *s = NULL;
+    Py_ssize_t len;
+    PyObject *v;
+
+    if (obj == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+
+#if 0
+    /* For b/w compatibility we also accept Unicode objects provided
+       that no encodings is given and then redirect to
+       PyObject_Unicode() which then applies the additional logic for
+       Unicode subclasses.
+
+       NOTE: This API should really only be used for object which
+       represent *encoded* Unicode !
+
+    */
+    if (PyUnicode_Check(obj)) {
+        if (encoding) {
+            PyErr_SetString(PyExc_TypeError,
+                            "decoding Unicode is not supported");
+            return NULL;
+        }
+        return PyObject_Unicode(obj);
+    }
+#else
+    if (PyUnicode_Check(obj)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "decoding Unicode is not supported");
+        return NULL;
+    }
+#endif
+
+    /* Coerce object */
+    if (PyString_Check(obj)) {
+        s = PyString_AS_STRING(obj);
+        len = PyString_GET_SIZE(obj);
+    }
+    else if (PyByteArray_Check(obj)) {
+        /* Python 2.x specific */
+        PyErr_Format(PyExc_TypeError,
+                     "decoding bytearray is not supported");
+        return NULL;
+    }
+    else if (PyObject_AsCharBuffer(obj, &s, &len)) {
+        /* Overwrite the error message with something more useful in
+           case of a TypeError. */
+        if (PyErr_ExceptionMatches(PyExc_TypeError))
+            PyErr_Format(PyExc_TypeError,
+                         "coercing to Unicode: need string or buffer, "
+                         "%.80s found",
+                         Py_TYPE(obj)->tp_name);
+        goto onError;
+    }
+
+    /* Convert to Unicode */
+    if (len == 0)
+        _Py_RETURN_UNICODE_EMPTY();
+
+    v = PyUnicode_Decode(s, len, encoding, errors);
+    return v;
+
+  onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_Decode(const char *s,
+                           Py_ssize_t size,
+                           const char *encoding,
+                           const char *errors)
+{
+    PyObject *buffer = NULL, *unicode;
+
+    if (encoding == NULL)
+        encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Shortcuts for common default encodings */
+    if (strcmp(encoding, "utf-8") == 0)
+        return PyUnicode_DecodeUTF8(s, size, errors);
+    else if (strcmp(encoding, "latin-1") == 0)
+        return PyUnicode_DecodeLatin1(s, size, errors);
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+    else if (strcmp(encoding, "mbcs") == 0)
+        return PyUnicode_DecodeMBCS(s, size, errors);
+#endif
+    else if (strcmp(encoding, "ascii") == 0)
+        return PyUnicode_DecodeASCII(s, size, errors);
+
+    /* Decode via the codec registry */
+    buffer = PyBuffer_FromMemory((void *)s, size);
+    if (buffer == NULL)
+        goto onError;
+    unicode = PyCodec_Decode(buffer, encoding, errors);
+    if (unicode == NULL)
+        goto onError;
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return an unicode object (type=%.400s)",
+                     Py_TYPE(unicode)->tp_name);
+        Py_DECREF(unicode);
+        goto onError;
+    }
+    Py_DECREF(buffer);
+    return unicode;
+
+  onError:
+    Py_XDECREF(buffer);
+    return NULL;
+}
+
+PyObject *PyUnicode_AsDecodedObject(PyObject *unicode,
+                                    const char *encoding,
+                                    const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+        encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Decode via the codec registry */
+    v = PyCodec_Decode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    return v;
+
+  onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_Encode(const Py_UNICODE *s,
+                           Py_ssize_t size,
+                           const char *encoding,
+                           const char *errors)
+{
+    PyObject *v, *unicode;
+
+    unicode = PyUnicode_FromUnicode(s, size);
+    if (unicode == NULL)
+        return NULL;
+    v = PyUnicode_AsEncodedString(unicode, encoding, errors);
+    Py_DECREF(unicode);
+    return v;
+}
+
+PyObject *PyUnicode_AsEncodedObject(PyObject *unicode,
+                                    const char *encoding,
+                                    const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+        encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    return v;
+
+  onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
+                                    const char *encoding,
+                                    const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+        encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Shortcuts for common default encodings */
+    if (errors == NULL) {
+        if (strcmp(encoding, "utf-8") == 0)
+            return PyUnicode_AsUTF8String(unicode);
+        else if (strcmp(encoding, "latin-1") == 0)
+            return PyUnicode_AsLatin1String(unicode);
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+        else if (strcmp(encoding, "mbcs") == 0)
+            return PyUnicode_AsMBCSString(unicode);
+#endif
+        else if (strcmp(encoding, "ascii") == 0)
+            return PyUnicode_AsASCIIString(unicode);
+    }
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string object (type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+    return v;
+
+  onError:
+    return NULL;
+}
+
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+                                            const char *errors)
+{
+    PyObject *v = ((PyUnicodeObject *)unicode)->defenc;
+
+    if (v)
+        return v;
+    v = PyUnicode_AsEncodedString(unicode, NULL, errors);
+    if (v && errors == NULL)
+        ((PyUnicodeObject *)unicode)->defenc = v;
+    return v;
+}
+
+Py_UNICODE *PyUnicode_AsUnicode(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+    return PyUnicode_AS_UNICODE(unicode);
+
+  onError:
+    return NULL;
+}
+
+Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+    return PyUnicode_GET_SIZE(unicode);
+
+  onError:
+    return -1;
+}
+
+const char *PyUnicode_GetDefaultEncoding(void)
+{
+    return unicode_default_encoding;
+}
+
+int PyUnicode_SetDefaultEncoding(const char *encoding)
+{
+    PyObject *v;
+
+    /* Make sure the encoding is valid. As side effect, this also
+       loads the encoding into the codec registry cache. */
+    v = _PyCodec_Lookup(encoding);
+    if (v == NULL)
+        goto onError;
+    Py_DECREF(v);
+    strncpy(unicode_default_encoding,
+            encoding,
+            sizeof(unicode_default_encoding) - 1);
+    return 0;
+
+  onError:
+    return -1;
+}
+
+/* error handling callback helper:
+   build arguments, call the callback and check the arguments,
+   if no exception occurred, copy the replacement to the output
+   and adjust various state variables.
+   return 0 on success, -1 on error
+*/
+
+static
+int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler,
+                                     const char *encoding, const char *reason,
+                                     const char *input, Py_ssize_t insize, Py_ssize_t *startinpos,
+                                     Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
+                                     PyUnicodeObject **output, Py_ssize_t *outpos, Py_UNICODE **outptr)
+{
+    static char *argparse = "O!n;decoding error handler must return (unicode, int) tuple";
+
+    PyObject *restuple = NULL;
+    PyObject *repunicode = NULL;
+    Py_ssize_t outsize = PyUnicode_GET_SIZE(*output);
+    Py_ssize_t requiredsize;
+    Py_ssize_t newpos;
+    Py_UNICODE *repptr;
+    Py_ssize_t repsize;
+    int res = -1;
+
+    if (*errorHandler == NULL) {
+        *errorHandler = PyCodec_LookupError(errors);
+        if (*errorHandler == NULL)
+            goto onError;
+    }
+
+    if (*exceptionObject == NULL) {
+        *exceptionObject = PyUnicodeDecodeError_Create(
+            encoding, input, insize, *startinpos, *endinpos, reason);
+        if (*exceptionObject == NULL)
+            goto onError;
+    }
+    else {
+        if (PyUnicodeDecodeError_SetStart(*exceptionObject, *startinpos))
+            goto onError;
+        if (PyUnicodeDecodeError_SetEnd(*exceptionObject, *endinpos))
+            goto onError;
+        if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason))
+            goto onError;
+    }
+
+    restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL);
+    if (restuple == NULL)
+        goto onError;
+    if (!PyTuple_Check(restuple)) {
+        PyErr_SetString(PyExc_TypeError, &argparse[4]);
+        goto onError;
+    }
+    if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &repunicode, &newpos))
+        goto onError;
+    if (newpos<0)
+        newpos = insize+newpos;
+    if (newpos<0 || newpos>insize) {
+        PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos);
+        goto onError;
+    }
+
+    /* need more space? (at least enough for what we
+       have+the replacement+the rest of the string (starting
+       at the new input position), so we won't have to check space
+       when there are no errors in the rest of the string) */
+    repptr = PyUnicode_AS_UNICODE(repunicode);
+    repsize = PyUnicode_GET_SIZE(repunicode);
+    requiredsize = *outpos + repsize + insize-newpos;
+    if (requiredsize > outsize) {
+        if (requiredsize<2*outsize)
+            requiredsize = 2*outsize;
+        if (_PyUnicode_Resize(output, requiredsize) < 0)
+            goto onError;
+        *outptr = PyUnicode_AS_UNICODE(*output) + *outpos;
+    }
+    *endinpos = newpos;
+    *inptr = input + newpos;
+    Py_UNICODE_COPY(*outptr, repptr, repsize);
+    *outptr += repsize;
+    *outpos += repsize;
+    /* we made it! */
+    res = 0;
+
+  onError:
+    Py_XDECREF(restuple);
+    return res;
+}
+
+/* --- UTF-7 Codec -------------------------------------------------------- */
+
+/* See RFC2152 for details.  We encode conservatively and decode liberally. */
+
+/* Three simple macros defining base-64. */
+
+/* Is c a base-64 character? */
+
+#define IS_BASE64(c) \
+    (isalnum(c) || (c) == '+' || (c) == '/')
+
+/* given that c is a base-64 character, what is its base-64 value? */
+
+#define FROM_BASE64(c)                                                  \
+    (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' :                           \
+     ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 26 :                      \
+     ((c) >= '0' && (c) <= '9') ? (c) - '0' + 52 :                      \
+     (c) == '+' ? 62 : 63)
+
+/* What is the base-64 character of the bottom 6 bits of n? */
+
+#define TO_BASE64(n)  \
+    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f])
+
+/* DECODE_DIRECT: this byte encountered in a UTF-7 string should be
+ * decoded as itself.  We are permissive on decoding; the only ASCII
+ * byte not decoding to itself is the + which begins a base64
+ * string. */
+
+#define DECODE_DIRECT(c)                                \
+    ((c) <= 127 && (c) != '+')
+
+/* The UTF-7 encoder treats ASCII characters differently according to
+ * whether they are Set D, Set O, Whitespace, or special (i.e. none of
+ * the above).  See RFC2152.  This array identifies these different
+ * sets:
+ * 0 : "Set D"
+ *     alphanumeric and '(),-./:?
+ * 1 : "Set O"
+ *     !"#$%&*;<=>@[]^_`{|}
+ * 2 : "whitespace"
+ *     ht nl cr sp
+ * 3 : special (must be base64 encoded)
+ *     everything else (i.e. +\~ and non-printing codes 0-8 11-12 14-31 127)
+ */
+
+static
+char utf7_category[128] = {
+/* nul soh stx etx eot enq ack bel bs  ht  nl  vt  np  cr  so  si  */
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  3,  3,  2,  3,  3,
+/* dle dc1 dc2 dc3 dc4 nak syn etb can em  sub esc fs  gs  rs  us  */
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+/* sp   !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /  */
+    2,  1,  1,  1,  1,  1,  1,  0,  0,  0,  1,  3,  0,  0,  0,  0,
+/*  0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?  */
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,
+/*  @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O  */
+    1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+/*  P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _  */
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  3,  1,  1,  1,
+/*  `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o  */
+    1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+/*  p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~  del */
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  3,  3,
+};
+
+/* ENCODE_DIRECT: this character should be encoded as itself.  The
+ * answer depends on whether we are encoding set O as itself, and also
+ * on whether we are encoding whitespace as itself.  RFC2152 makes it
+ * clear that the answers to these questions vary between
+ * applications, so this code needs to be flexible.  */
+
+#define ENCODE_DIRECT(c, directO, directWS)             \
+    ((c) < 128 && (c) > 0 &&                            \
+     ((utf7_category[(c)] == 0) ||                      \
+      (directWS && (utf7_category[(c)] == 2)) ||        \
+      (directO && (utf7_category[(c)] == 1))))
+
+PyObject *PyUnicode_DecodeUTF7(const char *s,
+                               Py_ssize_t size,
+                               const char *errors)
+{
+    return PyUnicode_DecodeUTF7Stateful(s, size, errors, NULL);
+}
+
+/* The decoder.  The only state we preserve is our read position,
+ * i.e. how many characters we have consumed.  So if we end in the
+ * middle of a shift sequence we have to back off the read position
+ * and the output to the beginning of the sequence, otherwise we lose
+ * all the shift state (seen bits, number of bits seen, high
+ * surrogate). */
+
+PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
+                                       Py_ssize_t size,
+                                       const char *errors,
+                                       Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+    const char *errmsg = "";
+    int inShift = 0;
+    Py_UNICODE *shiftOutStart;
+    unsigned int base64bits = 0;
+    unsigned long base64buffer = 0;
+    Py_UNICODE surrogate = 0;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+    if (size == 0) {
+        if (consumed)
+            *consumed = 0;
+        return (PyObject *)unicode;
+    }
+
+    p = unicode->str;
+    shiftOutStart = p;
+    e = s + size;
+
+    while (s < e) {
+        Py_UNICODE ch = (unsigned char) *s;
+
+        if (inShift) { /* in a base-64 section */
+            if (IS_BASE64(ch)) { /* consume a base-64 character */
+                base64buffer = (base64buffer << 6) | FROM_BASE64(ch);
+                base64bits += 6;
+                s++;
+                if (base64bits >= 16) {
+                    /* we have enough bits for a UTF-16 value */
+                    Py_UNICODE outCh = (Py_UNICODE)
+                                       (base64buffer >> (base64bits-16));
+                    base64bits -= 16;
+                    base64buffer &= (1 << base64bits) - 1; /* clear high bits */
+                    if (surrogate) {
+                        /* expecting a second surrogate */
+                        if (outCh >= 0xDC00 && outCh <= 0xDFFF) {
+#ifdef Py_UNICODE_WIDE
+                            *p++ = (((surrogate & 0x3FF)<<10)
+                                    | (outCh & 0x3FF)) + 0x10000;
+#else
+                            *p++ = surrogate;
+                            *p++ = outCh;
+#endif
+                            surrogate = 0;
+                            continue;
+                        }
+                        else {
+                            *p++ = surrogate;
+                            surrogate = 0;
+                        }
+                    }
+                    if (outCh >= 0xD800 && outCh <= 0xDBFF) {
+                        /* first surrogate */
+                        surrogate = outCh;
+                    }
+                    else {
+                        *p++ = outCh;
+                    }
+                }
+            }
+            else { /* now leaving a base-64 section */
+                inShift = 0;
+                s++;
+                if (surrogate) {
+                    *p++ = surrogate;
+                    surrogate = 0;
+                }
+                if (base64bits > 0) { /* left-over bits */
+                    if (base64bits >= 6) {
+                        /* We've seen at least one base-64 character */
+                        errmsg = "partial character in shift sequence";
+                        goto utf7Error;
+                    }
+                    else {
+                        /* Some bits remain; they should be zero */
+                        if (base64buffer != 0) {
+                            errmsg = "non-zero padding bits in shift sequence";
+                            goto utf7Error;
+                        }
+                    }
+                }
+                if (ch != '-') {
+                    /* '-' is absorbed; other terminating
+                       characters are preserved */
+                    *p++ = ch;
+                }
+            }
+        }
+        else if ( ch == '+' ) {
+            startinpos = s-starts;
+            s++; /* consume '+' */
+            if (s < e && *s == '-') { /* '+-' encodes '+' */
+                s++;
+                *p++ = '+';
+            }
+            else { /* begin base64-encoded section */
+                inShift = 1;
+                shiftOutStart = p;
+                base64bits = 0;
+            }
+        }
+        else if (DECODE_DIRECT(ch)) { /* character decodes as itself */
+            *p++ = ch;
+            s++;
+        }
+        else {
+            startinpos = s-starts;
+            s++;
+            errmsg = "unexpected special character";
+            goto utf7Error;
+        }
+        continue;
+utf7Error:
+        outpos = p-PyUnicode_AS_UNICODE(unicode);
+        endinpos = s-starts;
+        if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "utf7", errmsg,
+                starts, size, &startinpos, &endinpos, &exc, &s,
+                &unicode, &outpos, &p))
+            goto onError;
+    }
+
+    /* end of string */
+
+    if (inShift && !consumed) { /* in shift sequence, no more to follow */
+        /* if we're in an inconsistent state, that's an error */
+        if (surrogate ||
+                (base64bits >= 6) ||
+                (base64bits > 0 && base64buffer != 0)) {
+            outpos = p-PyUnicode_AS_UNICODE(unicode);
+            endinpos = size;
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "utf7", "unterminated shift sequence",
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    &unicode, &outpos, &p))
+                goto onError;
+        }
+    }
+
+    /* return state */
+    if (consumed) {
+        if (inShift) {
+            p = shiftOutStart; /* back off output */
+            *consumed = startinpos;
+        }
+        else {
+            *consumed = s-starts;
+        }
+    }
+
+    if (_PyUnicode_Resize(&unicode, p - PyUnicode_AS_UNICODE(unicode)) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+  onError:
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    Py_DECREF(unicode);
+    return NULL;
+}
+
+
+PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
+                               Py_ssize_t size,
+                               int base64SetO,
+                               int base64WhiteSpace,
+                               const char *errors)
+{
+    PyObject *v;
+    /* It might be possible to tighten this worst case */
+    Py_ssize_t allocated = 8 * size;
+    int inShift = 0;
+    Py_ssize_t i = 0;
+    unsigned int base64bits = 0;
+    unsigned long base64buffer = 0;
+    char * out;
+    char * start;
+
+    if (allocated / 8 != size)
+        return PyErr_NoMemory();
+
+    if (size == 0)
+        return PyString_FromStringAndSize(NULL, 0);
+
+    v = PyString_FromStringAndSize(NULL, allocated);
+    if (v == NULL)
+        return NULL;
+
+    start = out = PyString_AS_STRING(v);
+    for (;i < size; ++i) {
+        Py_UNICODE ch = s[i];
+
+        if (inShift) {
+            if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
+                /* shifting out */
+                if (base64bits) { /* output remaining bits */
+                    *out++ = TO_BASE64(base64buffer << (6-base64bits));
+                    base64buffer = 0;
+                    base64bits = 0;
+                }
+                inShift = 0;
+                /* Characters not in the BASE64 set implicitly unshift the sequence
+                   so no '-' is required, except if the character is itself a '-' */
+                if (IS_BASE64(ch) || ch == '-') {
+                    *out++ = '-';
+                }
+                *out++ = (char) ch;
+            }
+            else {
+                goto encode_char;
+            }
+        }
+        else { /* not in a shift sequence */
+            if (ch == '+') {
+                *out++ = '+';
+                        *out++ = '-';
+            }
+            else if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
+                *out++ = (char) ch;
+            }
+            else {
+                *out++ = '+';
+                inShift = 1;
+                goto encode_char;
+            }
+        }
+        continue;
+encode_char:
+#ifdef Py_UNICODE_WIDE
+        if (ch >= 0x10000) {
+            /* code first surrogate */
+            base64bits += 16;
+            base64buffer = (base64buffer << 16) | 0xd800 | ((ch-0x10000) >> 10);
+            while (base64bits >= 6) {
+                *out++ = TO_BASE64(base64buffer >> (base64bits-6));
+                base64bits -= 6;
+            }
+            /* prepare second surrogate */
+            ch =  0xDC00 | ((ch-0x10000) & 0x3FF);
+        }
+#endif
+        base64bits += 16;
+        base64buffer = (base64buffer << 16) | ch;
+        while (base64bits >= 6) {
+            *out++ = TO_BASE64(base64buffer >> (base64bits-6));
+            base64bits -= 6;
+        }
+    }
+    if (base64bits)
+        *out++= TO_BASE64(base64buffer << (6-base64bits) );
+    if (inShift)
+        *out++ = '-';
+
+    if (_PyString_Resize(&v, out - start))
+        return NULL;
+    return v;
+}
+
+#undef IS_BASE64
+#undef FROM_BASE64
+#undef TO_BASE64
+#undef DECODE_DIRECT
+#undef ENCODE_DIRECT
+
+/* --- UTF-8 Codec -------------------------------------------------------- */
+
+static
+char utf8_code_length[256] = {
+    /* Map UTF-8 encoded prefix byte to sequence length.  Zero means
+       illegal prefix.  See RFC 3629 for details */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70-7F */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8F */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0-BF */
+    0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* C0-C1 + C2-CF */
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* D0-DF */
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* E0-EF */
+    4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* F0-F4 + F5-FF */
+};
+
+PyObject *PyUnicode_DecodeUTF8(const char *s,
+                               Py_ssize_t size,
+                               const char *errors)
+{
+    return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
+}
+
+PyObject *PyUnicode_DecodeUTF8Stateful(const char *s,
+                                       Py_ssize_t size,
+                                       const char *errors,
+                                       Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    int n;
+    int k;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+    const char *errmsg = "";
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Note: size will always be longer than the resulting Unicode
+       character count */
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+    if (size == 0) {
+        if (consumed)
+            *consumed = 0;
+        return (PyObject *)unicode;
+    }
+
+    /* Unpack UTF-8 encoded data */
+    p = unicode->str;
+    e = s + size;
+
+    while (s < e) {
+        Py_UCS4 ch = (unsigned char)*s;
+
+        if (ch < 0x80) {
+            *p++ = (Py_UNICODE)ch;
+            s++;
+            continue;
+        }
+
+        n = utf8_code_length[ch];
+
+        if (s + n > e) {
+            if (consumed)
+                break;
+            else {
+                errmsg = "unexpected end of data";
+                startinpos = s-starts;
+                endinpos = startinpos+1;
+                for (k=1; (k < size-startinpos) && ((s[k]&0xC0) == 0x80); k++)
+                    endinpos++;
+                goto utf8Error;
+            }
+        }
+
+        switch (n) {
+
+        case 0:
+            errmsg = "invalid start byte";
+            startinpos = s-starts;
+            endinpos = startinpos+1;
+            goto utf8Error;
+
+        case 1:
+            errmsg = "internal error";
+            startinpos = s-starts;
+            endinpos = startinpos+1;
+            goto utf8Error;
+
+        case 2:
+            if ((s[1] & 0xc0) != 0x80) {
+                errmsg = "invalid continuation byte";
+                startinpos = s-starts;
+                endinpos = startinpos + 1;
+                goto utf8Error;
+            }
+            ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f);
+            assert ((ch > 0x007F) && (ch <= 0x07FF));
+            *p++ = (Py_UNICODE)ch;
+            break;
+
+        case 3:
+            /* XXX: surrogates shouldn't be valid UTF-8!
+               see http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf
+               (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt
+               Uncomment the 2 lines below to make them invalid,
+               codepoints: d800-dfff; UTF-8: \xed\xa0\x80-\xed\xbf\xbf. */
+            if ((s[1] & 0xc0) != 0x80 ||
+                (s[2] & 0xc0) != 0x80 ||
+                ((unsigned char)s[0] == 0xE0 &&
+                 (unsigned char)s[1] < 0xA0)/* ||
+                ((unsigned char)s[0] == 0xED &&
+                 (unsigned char)s[1] > 0x9F)*/) {
+                errmsg = "invalid continuation byte";
+                startinpos = s-starts;
+                endinpos = startinpos + 1;
+
+                /* if s[1] first two bits are 1 and 0, then the invalid
+                   continuation byte is s[2], so increment endinpos by 1,
+                   if not, s[1] is invalid and endinpos doesn't need to
+                   be incremented. */
+                if ((s[1] & 0xC0) == 0x80)
+                    endinpos++;
+                goto utf8Error;
+            }
+            ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f);
+            assert ((ch > 0x07FF) && (ch <= 0xFFFF));
+            *p++ = (Py_UNICODE)ch;
+            break;
+
+        case 4:
+            if ((s[1] & 0xc0) != 0x80 ||
+                (s[2] & 0xc0) != 0x80 ||
+                (s[3] & 0xc0) != 0x80 ||
+                ((unsigned char)s[0] == 0xF0 &&
+                 (unsigned char)s[1] < 0x90) ||
+                ((unsigned char)s[0] == 0xF4 &&
+                 (unsigned char)s[1] > 0x8F)) {
+                errmsg = "invalid continuation byte";
+                startinpos = s-starts;
+                endinpos = startinpos + 1;
+                if ((s[1] & 0xC0) == 0x80) {
+                    endinpos++;
+                    if ((s[2] & 0xC0) == 0x80)
+                        endinpos++;
+                }
+                goto utf8Error;
+            }
+            ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) +
+                 ((s[2] & 0x3f) << 6) + (s[3] & 0x3f);
+            assert ((ch > 0xFFFF) && (ch <= 0x10ffff));
+
+#ifdef Py_UNICODE_WIDE
+            *p++ = (Py_UNICODE)ch;
+#else
+            /*  compute and append the two surrogates: */
+
+            /*  translate from 10000..10FFFF to 0..FFFF */
+            ch -= 0x10000;
+
+            /*  high surrogate = top 10 bits added to D800 */
+            *p++ = (Py_UNICODE)(0xD800 + (ch >> 10));
+
+            /*  low surrogate = bottom 10 bits added to DC00 */
+            *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF));
+#endif
+            break;
+        }
+        s += n;
+        continue;
+
+      utf8Error:
+        outpos = p-PyUnicode_AS_UNICODE(unicode);
+        if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "utf8", errmsg,
+                starts, size, &startinpos, &endinpos, &exc, &s,
+                &unicode, &outpos, &p))
+            goto onError;
+    }
+    if (consumed)
+        *consumed = s-starts;
+
+    /* Adjust length */
+    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+  onError:
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    Py_DECREF(unicode);
+    return NULL;
+}
+
+/* Allocation strategy:  if the string is short, convert into a stack buffer
+   and allocate exactly as much space needed at the end.  Else allocate the
+   maximum possible needed (4 result bytes per Unicode character), and return
+   the excess memory at the end.
+*/
+PyObject *
+PyUnicode_EncodeUTF8(const Py_UNICODE *s,
+                     Py_ssize_t size,
+                     const char *errors)
+{
+#define MAX_SHORT_UNICHARS 300  /* largest size we'll do on the stack */
+
+    Py_ssize_t i;           /* index into s of next input byte */
+    PyObject *v;        /* result string object */
+    char *p;            /* next free byte in output buffer */
+    Py_ssize_t nallocated;  /* number of result bytes allocated */
+    Py_ssize_t nneeded;        /* number of result bytes needed */
+    char stackbuf[MAX_SHORT_UNICHARS * 4];
+
+    assert(s != NULL);
+    assert(size >= 0);
+
+    if (size <= MAX_SHORT_UNICHARS) {
+        /* Write into the stack buffer; nallocated can't overflow.
+         * At the end, we'll allocate exactly as much heap space as it
+         * turns out we need.
+         */
+        nallocated = Py_SAFE_DOWNCAST(sizeof(stackbuf), size_t, int);
+        v = NULL;   /* will allocate after we're done */
+        p = stackbuf;
+    }
+    else {
+        /* Overallocate on the heap, and give the excess back at the end. */
+        nallocated = size * 4;
+        if (nallocated / 4 != size)  /* overflow! */
+            return PyErr_NoMemory();
+        v = PyString_FromStringAndSize(NULL, nallocated);
+        if (v == NULL)
+            return NULL;
+        p = PyString_AS_STRING(v);
+    }
+
+    for (i = 0; i < size;) {
+        Py_UCS4 ch = s[i++];
+
+        if (ch < 0x80)
+            /* Encode ASCII */
+            *p++ = (char) ch;
+
+        else if (ch < 0x0800) {
+            /* Encode Latin-1 */
+            *p++ = (char)(0xc0 | (ch >> 6));
+            *p++ = (char)(0x80 | (ch & 0x3f));
+        }
+        else {
+            /* Encode UCS2 Unicode ordinals */
+            if (ch < 0x10000) {
+                /* Special case: check for high surrogate */
+                if (0xD800 <= ch && ch <= 0xDBFF && i != size) {
+                    Py_UCS4 ch2 = s[i];
+                    /* Check for low surrogate and combine the two to
+                       form a UCS4 value */
+                    if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+                        ch = ((ch - 0xD800) << 10 | (ch2 - 0xDC00)) + 0x10000;
+                        i++;
+                        goto encodeUCS4;
+                    }
+                    /* Fall through: handles isolated high surrogates */
+                }
+                *p++ = (char)(0xe0 | (ch >> 12));
+                *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
+                *p++ = (char)(0x80 | (ch & 0x3f));
+                continue;
+            }
+          encodeUCS4:
+            /* Encode UCS4 Unicode ordinals */
+            *p++ = (char)(0xf0 | (ch >> 18));
+            *p++ = (char)(0x80 | ((ch >> 12) & 0x3f));
+            *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
+            *p++ = (char)(0x80 | (ch & 0x3f));
+        }
+    }
+
+    if (v == NULL) {
+        /* This was stack allocated. */
+        nneeded = p - stackbuf;
+        assert(nneeded <= nallocated);
+        v = PyString_FromStringAndSize(stackbuf, nneeded);
+    }
+    else {
+        /* Cut back to size actually needed. */
+        nneeded = p - PyString_AS_STRING(v);
+        assert(nneeded <= nallocated);
+        if (_PyString_Resize(&v, nneeded))
+            return NULL;
+    }
+    return v;
+
+#undef MAX_SHORT_UNICHARS
+}
+
+PyObject *PyUnicode_AsUTF8String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),
+                                PyUnicode_GET_SIZE(unicode),
+                                NULL);
+}
+
+/* --- UTF-32 Codec ------------------------------------------------------- */
+
+PyObject *
+PyUnicode_DecodeUTF32(const char *s,
+                      Py_ssize_t size,
+                      const char *errors,
+                      int *byteorder)
+{
+    return PyUnicode_DecodeUTF32Stateful(s, size, errors, byteorder, NULL);
+}
+
+PyObject *
+PyUnicode_DecodeUTF32Stateful(const char *s,
+                              Py_ssize_t size,
+                              const char *errors,
+                              int *byteorder,
+                              Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+#ifndef Py_UNICODE_WIDE
+    int pairs = 0;
+    const unsigned char *qq;
+#else
+    const int pairs = 0;
+#endif
+    const unsigned char *q, *e;
+    int bo = 0;       /* assume native ordering by default */
+    const char *errmsg = "";
+    /* Offsets from q for retrieving bytes in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int iorder[] = {0, 1, 2, 3};
+#else
+    int iorder[] = {3, 2, 1, 0};
+#endif
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    q = (unsigned char *)s;
+    e = q + size;
+
+    if (byteorder)
+        bo = *byteorder;
+
+    /* Check for BOM marks (U+FEFF) in the input and adjust current
+       byte order setting accordingly. In native mode, the leading BOM
+       mark is skipped, in all other modes, it is copied to the output
+       stream as-is (giving a ZWNBSP character). */
+    if (bo == 0) {
+        if (size >= 4) {
+            const Py_UCS4 bom = (q[iorder[3]] << 24) | (q[iorder[2]] << 16) |
+                (q[iorder[1]] << 8) | q[iorder[0]];
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+            if (bom == 0x0000FEFF) {
+                q += 4;
+                bo = -1;
+            }
+            else if (bom == 0xFFFE0000) {
+                q += 4;
+                bo = 1;
+            }
+#else
+            if (bom == 0x0000FEFF) {
+                q += 4;
+                bo = 1;
+            }
+            else if (bom == 0xFFFE0000) {
+                q += 4;
+                bo = -1;
+            }
+#endif
+        }
+    }
+
+    if (bo == -1) {
+        /* force LE */
+        iorder[0] = 0;
+        iorder[1] = 1;
+        iorder[2] = 2;
+        iorder[3] = 3;
+    }
+    else if (bo == 1) {
+        /* force BE */
+        iorder[0] = 3;
+        iorder[1] = 2;
+        iorder[2] = 1;
+        iorder[3] = 0;
+    }
+
+    /* On narrow builds we split characters outside the BMP into two
+       codepoints => count how much extra space we need. */
+#ifndef Py_UNICODE_WIDE
+    for (qq = q; e - qq >= 4; qq += 4)
+        if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0)
+            pairs++;
+#endif
+
+    /* This might be one to much, because of a BOM */
+    unicode = _PyUnicode_New((size+3)/4+pairs);
+    if (!unicode)
+        return NULL;
+    if (size == 0)
+        return (PyObject *)unicode;
+
+    /* Unpack UTF-32 encoded data */
+    p = unicode->str;
+
+    while (q < e) {
+        Py_UCS4 ch;
+        /* remaining bytes at the end? (size should be divisible by 4) */
+        if (e-q<4) {
+            if (consumed)
+                break;
+            errmsg = "truncated data";
+            startinpos = ((const char *)q)-starts;
+            endinpos = ((const char *)e)-starts;
+            goto utf32Error;
+            /* The remaining input chars are ignored if the callback
+               chooses to skip the input */
+        }
+        ch = (q[iorder[3]] << 24) | (q[iorder[2]] << 16) |
+            (q[iorder[1]] << 8) | q[iorder[0]];
+
+        if (ch >= 0x110000)
+        {
+            errmsg = "codepoint not in range(0x110000)";
+            startinpos = ((const char *)q)-starts;
+            endinpos = startinpos+4;
+            goto utf32Error;
+        }
+#ifndef Py_UNICODE_WIDE
+        if (ch >= 0x10000)
+        {
+            *p++ = 0xD800 | ((ch-0x10000) >> 10);
+            *p++ = 0xDC00 | ((ch-0x10000) & 0x3FF);
+        }
+        else
+#endif
+            *p++ = ch;
+        q += 4;
+        continue;
+      utf32Error:
+        outpos = p-PyUnicode_AS_UNICODE(unicode);
+        if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "utf32", errmsg,
+                starts, size, &startinpos, &endinpos, &exc, (const char **)&q,
+                &unicode, &outpos, &p))
+            goto onError;
+    }
+
+    if (byteorder)
+        *byteorder = bo;
+
+    if (consumed)
+        *consumed = (const char *)q-starts;
+
+    /* Adjust length */
+    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+  onError:
+    Py_DECREF(unicode);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *
+PyUnicode_EncodeUTF32(const Py_UNICODE *s,
+                      Py_ssize_t size,
+                      const char *errors,
+                      int byteorder)
+{
+    PyObject *v;
+    unsigned char *p;
+    Py_ssize_t nsize, bytesize;
+#ifndef Py_UNICODE_WIDE
+    Py_ssize_t i, pairs;
+#else
+    const int pairs = 0;
+#endif
+    /* Offsets from p for storing byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int iorder[] = {0, 1, 2, 3};
+#else
+    int iorder[] = {3, 2, 1, 0};
+#endif
+
+#define STORECHAR(CH)                           \
+    do {                                        \
+        p[iorder[3]] = ((CH) >> 24) & 0xff;     \
+        p[iorder[2]] = ((CH) >> 16) & 0xff;     \
+        p[iorder[1]] = ((CH) >> 8) & 0xff;      \
+        p[iorder[0]] = (CH) & 0xff;             \
+        p += 4;                                 \
+    } while(0)
+
+    /* In narrow builds we can output surrogate pairs as one codepoint,
+       so we need less space. */
+#ifndef Py_UNICODE_WIDE
+    for (i = pairs = 0; i < size-1; i++)
+        if (0xD800 <= s[i] && s[i] <= 0xDBFF &&
+            0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF)
+            pairs++;
+#endif
+    nsize = (size - pairs + (byteorder == 0));
+    bytesize = nsize * 4;
+    if (bytesize / 4 != nsize)
+        return PyErr_NoMemory();
+    v = PyString_FromStringAndSize(NULL, bytesize);
+    if (v == NULL)
+        return NULL;
+
+    p = (unsigned char *)PyString_AS_STRING(v);
+    if (byteorder == 0)
+        STORECHAR(0xFEFF);
+    if (size == 0)
+        return v;
+
+    if (byteorder == -1) {
+        /* force LE */
+        iorder[0] = 0;
+        iorder[1] = 1;
+        iorder[2] = 2;
+        iorder[3] = 3;
+    }
+    else if (byteorder == 1) {
+        /* force BE */
+        iorder[0] = 3;
+        iorder[1] = 2;
+        iorder[2] = 1;
+        iorder[3] = 0;
+    }
+
+    while (size-- > 0) {
+        Py_UCS4 ch = *s++;
+#ifndef Py_UNICODE_WIDE
+        if (0xD800 <= ch && ch <= 0xDBFF && size > 0) {
+            Py_UCS4 ch2 = *s;
+            if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+                ch = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+                s++;
+                size--;
+            }
+        }
+#endif
+        STORECHAR(ch);
+    }
+    return v;
+#undef STORECHAR
+}
+
+PyObject *PyUnicode_AsUTF32String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(unicode),
+                                 PyUnicode_GET_SIZE(unicode),
+                                 NULL,
+                                 0);
+}
+
+/* --- UTF-16 Codec ------------------------------------------------------- */
+
+PyObject *
+PyUnicode_DecodeUTF16(const char *s,
+                      Py_ssize_t size,
+                      const char *errors,
+                      int *byteorder)
+{
+    return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL);
+}
+
+PyObject *
+PyUnicode_DecodeUTF16Stateful(const char *s,
+                              Py_ssize_t size,
+                              const char *errors,
+                              int *byteorder,
+                              Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+    const unsigned char *q, *e;
+    int bo = 0;       /* assume native ordering by default */
+    const char *errmsg = "";
+    /* Offsets from q for retrieving byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int ihi = 1, ilo = 0;
+#else
+    int ihi = 0, ilo = 1;
+#endif
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Note: size will always be longer than the resulting Unicode
+       character count */
+    unicode = _PyUnicode_New(size);
+    if (!unicode)
+        return NULL;
+    if (size == 0)
+        return (PyObject *)unicode;
+
+    /* Unpack UTF-16 encoded data */
+    p = unicode->str;
+    q = (unsigned char *)s;
+    e = q + size;
+
+    if (byteorder)
+        bo = *byteorder;
+
+    /* Check for BOM marks (U+FEFF) in the input and adjust current
+       byte order setting accordingly. In native mode, the leading BOM
+       mark is skipped, in all other modes, it is copied to the output
+       stream as-is (giving a ZWNBSP character). */
+    if (bo == 0) {
+        if (size >= 2) {
+            const Py_UNICODE bom = (q[ihi] << 8) | q[ilo];
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+            if (bom == 0xFEFF) {
+                q += 2;
+                bo = -1;
+            }
+            else if (bom == 0xFFFE) {
+                q += 2;
+                bo = 1;
+            }
+#else
+            if (bom == 0xFEFF) {
+                q += 2;
+                bo = 1;
+            }
+            else if (bom == 0xFFFE) {
+                q += 2;
+                bo = -1;
+            }
+#endif
+        }
+    }
+
+    if (bo == -1) {
+        /* force LE */
+        ihi = 1;
+        ilo = 0;
+    }
+    else if (bo == 1) {
+        /* force BE */
+        ihi = 0;
+        ilo = 1;
+    }
+
+    while (q < e) {
+        Py_UNICODE ch;
+        /* remaining bytes at the end? (size should be even) */
+        if (e-q<2) {
+            if (consumed)
+                break;
+            errmsg = "truncated data";
+            startinpos = ((const char *)q)-starts;
+            endinpos = ((const char *)e)-starts;
+            goto utf16Error;
+            /* The remaining input chars are ignored if the callback
+               chooses to skip the input */
+        }
+        ch = (q[ihi] << 8) | q[ilo];
+
+        q += 2;
+
+        if (ch < 0xD800 || ch > 0xDFFF) {
+            *p++ = ch;
+            continue;
+        }
+
+        /* UTF-16 code pair: */
+        if (e - q < 2) {
+            q -= 2;
+            if (consumed)
+                break;
+            errmsg = "unexpected end of data";
+            startinpos = ((const char *)q)-starts;
+            endinpos = ((const char *)e)-starts;
+            goto utf16Error;
+        }
+        if (0xD800 <= ch && ch <= 0xDBFF) {
+            Py_UNICODE ch2 = (q[ihi] << 8) | q[ilo];
+            q += 2;
+            if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+#ifndef Py_UNICODE_WIDE
+                *p++ = ch;
+                *p++ = ch2;
+#else
+                *p++ = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+#endif
+                continue;
+            }
+            else {
+                errmsg = "illegal UTF-16 surrogate";
+                startinpos = (((const char *)q)-4)-starts;
+                endinpos = startinpos+2;
+                goto utf16Error;
+            }
+
+        }
+        errmsg = "illegal encoding";
+        startinpos = (((const char *)q)-2)-starts;
+        endinpos = startinpos+2;
+        /* Fall through to report the error */
+
+      utf16Error:
+        outpos = p-PyUnicode_AS_UNICODE(unicode);
+        if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "utf16", errmsg,
+                starts, size, &startinpos, &endinpos, &exc, (const char **)&q,
+                &unicode, &outpos, &p))
+            goto onError;
+    }
+
+    if (byteorder)
+        *byteorder = bo;
+
+    if (consumed)
+        *consumed = (const char *)q-starts;
+
+    /* Adjust length */
+    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+  onError:
+    Py_DECREF(unicode);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *
+PyUnicode_EncodeUTF16(const Py_UNICODE *s,
+                      Py_ssize_t size,
+                      const char *errors,
+                      int byteorder)
+{
+    PyObject *v;
+    unsigned char *p;
+    Py_ssize_t nsize, bytesize;
+#ifdef Py_UNICODE_WIDE
+    Py_ssize_t i, pairs;
+#else
+    const int pairs = 0;
+#endif
+    /* Offsets from p for storing byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int ihi = 1, ilo = 0;
+#else
+    int ihi = 0, ilo = 1;
+#endif
+
+#define STORECHAR(CH)                           \
+    do {                                        \
+        p[ihi] = ((CH) >> 8) & 0xff;            \
+        p[ilo] = (CH) & 0xff;                   \
+        p += 2;                                 \
+    } while(0)
+
+#ifdef Py_UNICODE_WIDE
+    for (i = pairs = 0; i < size; i++)
+        if (s[i] >= 0x10000)
+            pairs++;
+#endif
+    /* 2 * (size + pairs + (byteorder == 0)) */
+    if (size > PY_SSIZE_T_MAX ||
+        size > PY_SSIZE_T_MAX - pairs - (byteorder == 0))
+        return PyErr_NoMemory();
+    nsize = size + pairs + (byteorder == 0);
+    bytesize = nsize * 2;
+    if (bytesize / 2 != nsize)
+        return PyErr_NoMemory();
+    v = PyString_FromStringAndSize(NULL, bytesize);
+    if (v == NULL)
+        return NULL;
+
+    p = (unsigned char *)PyString_AS_STRING(v);
+    if (byteorder == 0)
+        STORECHAR(0xFEFF);
+    if (size == 0)
+        return v;
+
+    if (byteorder == -1) {
+        /* force LE */
+        ihi = 1;
+        ilo = 0;
+    }
+    else if (byteorder == 1) {
+        /* force BE */
+        ihi = 0;
+        ilo = 1;
+    }
+
+    while (size-- > 0) {
+        Py_UNICODE ch = *s++;
+        Py_UNICODE ch2 = 0;
+#ifdef Py_UNICODE_WIDE
+        if (ch >= 0x10000) {
+            ch2 = 0xDC00 | ((ch-0x10000) & 0x3FF);
+            ch  = 0xD800 | ((ch-0x10000) >> 10);
+        }
+#endif
+        STORECHAR(ch);
+        if (ch2)
+            STORECHAR(ch2);
+    }
+    return v;
+#undef STORECHAR
+}
+
+PyObject *PyUnicode_AsUTF16String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(unicode),
+                                 PyUnicode_GET_SIZE(unicode),
+                                 NULL,
+                                 0);
+}
+
+/* --- Unicode Escape Codec ----------------------------------------------- */
+
+static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;
+
+PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
+                                        Py_ssize_t size,
+                                        const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    char* message;
+    Py_UCS4 chr = 0xffffffff; /* in case 'getcode' messes up */
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Escaped strings will always be longer than the resulting
+       Unicode string, so we start with size here and then reduce the
+       length after conversion to the true value.
+       (but if the error callback returns a long replacement string
+       we'll have to allocate more space) */
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+        goto onError;
+    if (size == 0)
+        return (PyObject *)v;
+
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+
+    while (s < end) {
+        unsigned char c;
+        Py_UNICODE x;
+        int digits;
+
+        /* Non-escape characters are interpreted as Unicode ordinals */
+        if (*s != '\\') {
+            *p++ = (unsigned char) *s++;
+            continue;
+        }
+
+        startinpos = s-starts;
+        /* \ - Escapes */
+        s++;
+        c = *s++;
+        if (s > end)
+            c = '\0'; /* Invalid after \ */
+        switch (c) {
+
+            /* \x escapes */
+        case '\n': break;
+        case '\\': *p++ = '\\'; break;
+        case '\'': *p++ = '\''; break;
+        case '\"': *p++ = '\"'; break;
+        case 'b': *p++ = '\b'; break;
+        case 'f': *p++ = '\014'; break; /* FF */
+        case 't': *p++ = '\t'; break;
+        case 'n': *p++ = '\n'; break;
+        case 'r': *p++ = '\r'; break;
+        case 'v': *p++ = '\013'; break; /* VT */
+        case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+
+            /* \OOO (octal) escapes */
+        case '0': case '1': case '2': case '3':
+        case '4': case '5': case '6': case '7':
+            x = s[-1] - '0';
+            if (s < end && '0' <= *s && *s <= '7') {
+                x = (x<<3) + *s++ - '0';
+                if (s < end && '0' <= *s && *s <= '7')
+                    x = (x<<3) + *s++ - '0';
+            }
+            *p++ = x;
+            break;
+
+            /* hex escapes */
+            /* \xXX */
+        case 'x':
+            digits = 2;
+            message = "truncated \\xXX escape";
+            goto hexescape;
+
+            /* \uXXXX */
+        case 'u':
+            digits = 4;
+            message = "truncated \\uXXXX escape";
+            goto hexescape;
+
+            /* \UXXXXXXXX */
+        case 'U':
+            digits = 8;
+            message = "truncated \\UXXXXXXXX escape";
+        hexescape:
+            chr = 0;
+            if (end - s < digits) {
+                /* count only hex digits */
+                for (; s < end; ++s) {
+                    c = (unsigned char)*s;
+                    if (!Py_ISXDIGIT(c))
+                        goto error;
+                }
+                goto error;
+            }
+            for (; digits--; ++s) {
+                c = (unsigned char)*s;
+                if (!Py_ISXDIGIT(c))
+                    goto error;
+                chr = (chr<<4) & ~0xF;
+                if (c >= '0' && c <= '9')
+                    chr += c - '0';
+                else if (c >= 'a' && c <= 'f')
+                    chr += 10 + c - 'a';
+                else
+                    chr += 10 + c - 'A';
+            }
+            if (chr == 0xffffffff && PyErr_Occurred())
+                /* _decoding_error will have already written into the
+                   target buffer. */
+                break;
+        store:
+            /* when we get here, chr is a 32-bit unicode character */
+            if (chr <= 0xffff)
+                /* UCS-2 character */
+                *p++ = (Py_UNICODE) chr;
+            else if (chr <= 0x10ffff) {
+                /* UCS-4 character. Either store directly, or as
+                   surrogate pair. */
+#ifdef Py_UNICODE_WIDE
+                *p++ = chr;
+#else
+                chr -= 0x10000L;
+                *p++ = 0xD800 + (Py_UNICODE) (chr >> 10);
+                *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF);
+#endif
+            } else {
+                message = "illegal Unicode character";
+                goto error;
+            }
+            break;
+
+            /* \N{name} */
+        case 'N':
+            message = "malformed \\N character escape";
+            if (ucnhash_CAPI == NULL) {
+                /* load the unicode data module */
+                ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import(PyUnicodeData_CAPSULE_NAME, 1);
+                if (ucnhash_CAPI == NULL)
+                    goto ucnhashError;
+            }
+            if (*s == '{') {
+                const char *start = s+1;
+                /* look for the closing brace */
+                while (*s != '}' && s < end)
+                    s++;
+                if (s > start && s < end && *s == '}') {
+                    /* found a name.  look it up in the unicode database */
+                    message = "unknown Unicode character name";
+                    s++;
+                    if (s - start - 1 <= INT_MAX &&
+                        ucnhash_CAPI->getcode(NULL, start, (int)(s-start-1), &chr))
+                        goto store;
+                }
+            }
+            goto error;
+
+        default:
+            if (s > end) {
+                message = "\\ at end of string";
+                s--;
+                goto error;
+            }
+            else {
+                *p++ = '\\';
+                *p++ = (unsigned char)s[-1];
+            }
+            break;
+        }
+        continue;
+
+      error:
+        endinpos = s-starts;
+        outpos = p-PyUnicode_AS_UNICODE(v);
+        if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "unicodeescape", message,
+                starts, size, &startinpos, &endinpos, &exc, &s,
+                &v, &outpos, &p))
+            goto onError;
+        continue;
+    }
+    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+        goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+  ucnhashError:
+    PyErr_SetString(
+        PyExc_UnicodeError,
+        "\\N escapes not supported (can't load unicodedata module)"
+        );
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+
+  onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+/* Return a Unicode-Escape string version of the Unicode object.
+
+   If quotes is true, the string is enclosed in u"" or u'' quotes as
+   appropriate.
+
+*/
+
+Py_LOCAL_INLINE(const Py_UNICODE *) findchar(const Py_UNICODE *s,
+                                             Py_ssize_t size,
+                                             Py_UNICODE ch)
+{
+    /* like wcschr, but doesn't stop at NULL characters */
+
+    while (size-- > 0) {
+        if (*s == ch)
+            return s;
+        s++;
+    }
+
+    return NULL;
+}
+
+static
+PyObject *unicodeescape_string(const Py_UNICODE *s,
+                               Py_ssize_t size,
+                               int quotes)
+{
+    PyObject *repr;
+    char *p;
+
+    static const char *hexdigit = "0123456789abcdef";
+#ifdef Py_UNICODE_WIDE
+    const Py_ssize_t expandsize = 10;
+#else
+    const Py_ssize_t expandsize = 6;
+#endif
+
+    /* XXX(nnorwitz): rather than over-allocating, it would be
+       better to choose a different scheme.  Perhaps scan the
+       first N-chars of the string and allocate based on that size.
+    */
+    /* Initial allocation is based on the longest-possible unichr
+       escape.
+
+       In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
+       unichr, so in this case it's the longest unichr escape. In
+       narrow (UTF-16) builds this is five chars per source unichr
+       since there are two unichrs in the surrogate pair, so in narrow
+       (UTF-16) builds it's not the longest unichr escape.
+
+       In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
+       so in the narrow (UTF-16) build case it's the longest unichr
+       escape.
+    */
+
+    if (size > (PY_SSIZE_T_MAX - 2 - 1) / expandsize)
+        return PyErr_NoMemory();
+
+    repr = PyString_FromStringAndSize(NULL,
+                                      2
+                                      + expandsize*size
+                                      + 1);
+    if (repr == NULL)
+        return NULL;
+
+    p = PyString_AS_STRING(repr);
+
+    if (quotes) {
+        *p++ = 'u';
+        *p++ = (findchar(s, size, '\'') &&
+                !findchar(s, size, '"')) ? '"' : '\'';
+    }
+    while (size-- > 0) {
+        Py_UNICODE ch = *s++;
+
+        /* Escape quotes and backslashes */
+        if ((quotes &&
+             ch == (Py_UNICODE) PyString_AS_STRING(repr)[1]) || ch == '\\') {
+            *p++ = '\\';
+            *p++ = (char) ch;
+            continue;
+        }
+
+#ifdef Py_UNICODE_WIDE
+        /* Map 21-bit characters to '\U00xxxxxx' */
+        else if (ch >= 0x10000) {
+            *p++ = '\\';
+            *p++ = 'U';
+            *p++ = hexdigit[(ch >> 28) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 24) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 20) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 16) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 12) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 8) & 0x0000000F];
+            *p++ = hexdigit[(ch >> 4) & 0x0000000F];
+            *p++ = hexdigit[ch & 0x0000000F];
+            continue;
+        }
+#else
+        /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
+        else if (ch >= 0xD800 && ch < 0xDC00) {
+            Py_UNICODE ch2;
+            Py_UCS4 ucs;
+
+            ch2 = *s++;
+            size--;
+            if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+                ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
+                *p++ = '\\';
+                *p++ = 'U';
+                *p++ = hexdigit[(ucs >> 28) & 0x0000000F];
+                *p++ = hexdigit[(ucs >> 24) & 0x0000000F];
+                *p++ = hexdigit[(ucs >> 20) & 0x0000000F];
+                *p++ = hexdigit[(ucs >> 16) & 0x0000000F];
+                *p++ = hexdigit[(ucs >> 12) & 0x0000000F];
+                *p++ = hexdigit[(ucs >> 8) & 0x0000000F];
+                *p++ = hexdigit[(ucs >> 4) & 0x0000000F];
+                *p++ = hexdigit[ucs & 0x0000000F];
+                continue;
+            }
+            /* Fall through: isolated surrogates are copied as-is */
+            s--;
+            size++;
+        }
+#endif
+
+        /* Map 16-bit characters to '\uxxxx' */
+        if (ch >= 256) {
+            *p++ = '\\';
+            *p++ = 'u';
+            *p++ = hexdigit[(ch >> 12) & 0x000F];
+            *p++ = hexdigit[(ch >> 8) & 0x000F];
+            *p++ = hexdigit[(ch >> 4) & 0x000F];
+            *p++ = hexdigit[ch & 0x000F];
+        }
+
+        /* Map special whitespace to '\t', \n', '\r' */
+        else if (ch == '\t') {
+            *p++ = '\\';
+            *p++ = 't';
+        }
+        else if (ch == '\n') {
+            *p++ = '\\';
+            *p++ = 'n';
+        }
+        else if (ch == '\r') {
+            *p++ = '\\';
+            *p++ = 'r';
+        }
+
+        /* Map non-printable US ASCII to '\xhh' */
+        else if (ch < ' ' || ch >= 0x7F) {
+            *p++ = '\\';
+            *p++ = 'x';
+            *p++ = hexdigit[(ch >> 4) & 0x000F];
+            *p++ = hexdigit[ch & 0x000F];
+        }
+
+        /* Copy everything else as-is */
+        else
+            *p++ = (char) ch;
+    }
+    if (quotes)
+        *p++ = PyString_AS_STRING(repr)[1];
+
+    *p = '\0';
+    if (_PyString_Resize(&repr, p - PyString_AS_STRING(repr)))
+        return NULL;
+    return repr;
+}
+
+PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s,
+                                        Py_ssize_t size)
+{
+    return unicodeescape_string(s, size, 0);
+}
+
+PyObject *PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(unicode),
+                                         PyUnicode_GET_SIZE(unicode));
+}
+
+/* --- Raw Unicode Escape Codec ------------------------------------------- */
+
+PyObject *PyUnicode_DecodeRawUnicodeEscape(const char *s,
+                                           Py_ssize_t size,
+                                           const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    const char *bs;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* Escaped strings will always be longer than the resulting
+       Unicode string, so we start with size here and then reduce the
+       length after conversion to the true value. (But decoding error
+       handler might have to resize the string) */
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+        goto onError;
+    if (size == 0)
+        return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+    while (s < end) {
+        unsigned char c;
+        Py_UCS4 x;
+        int i;
+        int count;
+
+        /* Non-escape characters are interpreted as Unicode ordinals */
+        if (*s != '\\') {
+            *p++ = (unsigned char)*s++;
+            continue;
+        }
+        startinpos = s-starts;
+
+        /* \u-escapes are only interpreted iff the number of leading
+           backslashes if odd */
+        bs = s;
+        for (;s < end;) {
+            if (*s != '\\')
+                break;
+            *p++ = (unsigned char)*s++;
+        }
+        if (((s - bs) & 1) == 0 ||
+            s >= end ||
+            (*s != 'u' && *s != 'U')) {
+            continue;
+        }
+        p--;
+        count = *s=='u' ? 4 : 8;
+        s++;
+
+        /* \uXXXX with 4 hex digits, \Uxxxxxxxx with 8 */
+        outpos = p-PyUnicode_AS_UNICODE(v);
+        for (x = 0, i = 0; i < count; ++i, ++s) {
+            c = (unsigned char)*s;
+            if (!isxdigit(c)) {
+                endinpos = s-starts;
+                if (unicode_decode_call_errorhandler(
+                        errors, &errorHandler,
+                        "rawunicodeescape", "truncated \\uXXXX",
+                        starts, size, &startinpos, &endinpos, &exc, &s,
+                        &v, &outpos, &p))
+                    goto onError;
+                goto nextByte;
+            }
+            x = (x<<4) & ~0xF;
+            if (c >= '0' && c <= '9')
+                x += c - '0';
+            else if (c >= 'a' && c <= 'f')
+                x += 10 + c - 'a';
+            else
+                x += 10 + c - 'A';
+        }
+        if (x <= 0xffff)
+            /* UCS-2 character */
+            *p++ = (Py_UNICODE) x;
+        else if (x <= 0x10ffff) {
+            /* UCS-4 character. Either store directly, or as
+               surrogate pair. */
+#ifdef Py_UNICODE_WIDE
+            *p++ = (Py_UNICODE) x;
+#else
+            x -= 0x10000L;
+            *p++ = 0xD800 + (Py_UNICODE) (x >> 10);
+            *p++ = 0xDC00 + (Py_UNICODE) (x & 0x03FF);
+#endif
+        } else {
+            endinpos = s-starts;
+            outpos = p-PyUnicode_AS_UNICODE(v);
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "rawunicodeescape", "\\Uxxxxxxxx out of range",
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    &v, &outpos, &p))
+                goto onError;
+        }
+      nextByte:
+        ;
+    }
+    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+        goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+  onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s,
+                                           Py_ssize_t size)
+{
+    PyObject *repr;
+    char *p;
+    char *q;
+
+    static const char *hexdigit = "0123456789abcdef";
+#ifdef Py_UNICODE_WIDE
+    const Py_ssize_t expandsize = 10;
+#else
+    const Py_ssize_t expandsize = 6;
+#endif
+
+    if (size > PY_SSIZE_T_MAX / expandsize)
+        return PyErr_NoMemory();
+
+    repr = PyString_FromStringAndSize(NULL, expandsize * size);
+    if (repr == NULL)
+        return NULL;
+    if (size == 0)
+        return repr;
+
+    p = q = PyString_AS_STRING(repr);
+    while (size-- > 0) {
+        Py_UNICODE ch = *s++;
+#ifdef Py_UNICODE_WIDE
+        /* Map 32-bit characters to '\Uxxxxxxxx' */
+        if (ch >= 0x10000) {
+            *p++ = '\\';
+            *p++ = 'U';
+            *p++ = hexdigit[(ch >> 28) & 0xf];
+            *p++ = hexdigit[(ch >> 24) & 0xf];
+            *p++ = hexdigit[(ch >> 20) & 0xf];
+            *p++ = hexdigit[(ch >> 16) & 0xf];
+            *p++ = hexdigit[(ch >> 12) & 0xf];
+            *p++ = hexdigit[(ch >> 8) & 0xf];
+            *p++ = hexdigit[(ch >> 4) & 0xf];
+            *p++ = hexdigit[ch & 15];
+        }
+        else
+#else
+            /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
+            if (ch >= 0xD800 && ch < 0xDC00) {
+                Py_UNICODE ch2;
+                Py_UCS4 ucs;
+
+                ch2 = *s++;
+                size--;
+                if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+                    ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
+                    *p++ = '\\';
+                    *p++ = 'U';
+                    *p++ = hexdigit[(ucs >> 28) & 0xf];
+                    *p++ = hexdigit[(ucs >> 24) & 0xf];
+                    *p++ = hexdigit[(ucs >> 20) & 0xf];
+                    *p++ = hexdigit[(ucs >> 16) & 0xf];
+                    *p++ = hexdigit[(ucs >> 12) & 0xf];
+                    *p++ = hexdigit[(ucs >> 8) & 0xf];
+                    *p++ = hexdigit[(ucs >> 4) & 0xf];
+                    *p++ = hexdigit[ucs & 0xf];
+                    continue;
+                }
+                /* Fall through: isolated surrogates are copied as-is */
+                s--;
+                size++;
+            }
+#endif
+        /* Map 16-bit characters to '\uxxxx' */
+        if (ch >= 256) {
+            *p++ = '\\';
+            *p++ = 'u';
+            *p++ = hexdigit[(ch >> 12) & 0xf];
+            *p++ = hexdigit[(ch >> 8) & 0xf];
+            *p++ = hexdigit[(ch >> 4) & 0xf];
+            *p++ = hexdigit[ch & 15];
+        }
+        /* Copy everything else as-is */
+        else
+            *p++ = (char) ch;
+    }
+    *p = '\0';
+    if (_PyString_Resize(&repr, p - q))
+        return NULL;
+    return repr;
+}
+
+PyObject *PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeRawUnicodeEscape(PyUnicode_AS_UNICODE(unicode),
+                                            PyUnicode_GET_SIZE(unicode));
+}
+
+/* --- Unicode Internal Codec ------------------------------------------- */
+
+PyObject *_PyUnicode_DecodeUnicodeInternal(const char *s,
+                                           Py_ssize_t size,
+                                           const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    const char *reason;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+#ifdef Py_UNICODE_WIDE
+    Py_UNICODE unimax = PyUnicode_GetMax();
+#endif
+
+    /* XXX overflow detection missing */
+    v = _PyUnicode_New((size+Py_UNICODE_SIZE-1)/ Py_UNICODE_SIZE);
+    if (v == NULL)
+        goto onError;
+    if (PyUnicode_GetSize((PyObject *)v) == 0)
+        return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+
+    while (s < end) {
+        if (end-s < Py_UNICODE_SIZE) {
+            endinpos = end-starts;
+            reason = "truncated input";
+            goto error;
+        }
+        memcpy(p, s, sizeof(Py_UNICODE));
+#ifdef Py_UNICODE_WIDE
+        /* We have to sanity check the raw data, otherwise doom looms for
+           some malformed UCS-4 data. */
+        if (*p > unimax || *p < 0) {
+            endinpos = s - starts + Py_UNICODE_SIZE;
+            reason = "illegal code point (> 0x10FFFF)";
+            goto error;
+        }
+#endif
+        p++;
+        s += Py_UNICODE_SIZE;
+        continue;
+
+  error:
+        startinpos = s - starts;
+        outpos = p - PyUnicode_AS_UNICODE(v);
+        if (unicode_decode_call_errorhandler(
+                errors, &errorHandler,
+                "unicode_internal", reason,
+                starts, size, &startinpos, &endinpos, &exc, &s,
+                &v, &outpos, &p)) {
+            goto onError;
+        }
+    }
+
+    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+        goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+  onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+/* --- Latin-1 Codec ------------------------------------------------------ */
+
+PyObject *PyUnicode_DecodeLatin1(const char *s,
+                                 Py_ssize_t size,
+                                 const char *errors)
+{
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+
+    /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */
+    if (size == 1) {
+        Py_UNICODE r = *(unsigned char*)s;
+        return PyUnicode_FromUnicode(&r, 1);
+    }
+
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+        goto onError;
+    if (size == 0)
+        return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    while (size-- > 0)
+        *p++ = (unsigned char)*s++;
+    return (PyObject *)v;
+
+  onError:
+    Py_XDECREF(v);
+    return NULL;
+}
+
+/* create or adjust a UnicodeEncodeError */
+static void make_encode_exception(PyObject **exceptionObject,
+                                  const char *encoding,
+                                  const Py_UNICODE *unicode, Py_ssize_t size,
+                                  Py_ssize_t startpos, Py_ssize_t endpos,
+                                  const char *reason)
+{
+    if (*exceptionObject == NULL) {
+        *exceptionObject = PyUnicodeEncodeError_Create(
+            encoding, unicode, size, startpos, endpos, reason);
+    }
+    else {
+        if (PyUnicodeEncodeError_SetStart(*exceptionObject, startpos))
+            goto onError;
+        if (PyUnicodeEncodeError_SetEnd(*exceptionObject, endpos))
+            goto onError;
+        if (PyUnicodeEncodeError_SetReason(*exceptionObject, reason))
+            goto onError;
+        return;
+      onError:
+        Py_DECREF(*exceptionObject);
+        *exceptionObject = NULL;
+    }
+}
+
+/* raises a UnicodeEncodeError */
+static void raise_encode_exception(PyObject **exceptionObject,
+                                   const char *encoding,
+                                   const Py_UNICODE *unicode, Py_ssize_t size,
+                                   Py_ssize_t startpos, Py_ssize_t endpos,
+                                   const char *reason)
+{
+    make_encode_exception(exceptionObject,
+                          encoding, unicode, size, startpos, endpos, reason);
+    if (*exceptionObject != NULL)
+        PyCodec_StrictErrors(*exceptionObject);
+}
+
+/* error handling callback helper:
+   build arguments, call the callback and check the arguments,
+   put the result into newpos and return the replacement string, which
+   has to be freed by the caller */
+static PyObject *unicode_encode_call_errorhandler(const char *errors,
+                                                  PyObject **errorHandler,
+                                                  const char *encoding, const char *reason,
+                                                  const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject,
+                                                  Py_ssize_t startpos, Py_ssize_t endpos,
+                                                  Py_ssize_t *newpos)
+{
+    static char *argparse = "O!n;encoding error handler must return (unicode, int) tuple";
+
+    PyObject *restuple;
+    PyObject *resunicode;
+
+    if (*errorHandler == NULL) {
+        *errorHandler = PyCodec_LookupError(errors);
+        if (*errorHandler == NULL)
+            return NULL;
+    }
+
+    make_encode_exception(exceptionObject,
+                          encoding, unicode, size, startpos, endpos, reason);
+    if (*exceptionObject == NULL)
+        return NULL;
+
+    restuple = PyObject_CallFunctionObjArgs(
+        *errorHandler, *exceptionObject, NULL);
+    if (restuple == NULL)
+        return NULL;
+    if (!PyTuple_Check(restuple)) {
+        PyErr_SetString(PyExc_TypeError, &argparse[4]);
+        Py_DECREF(restuple);
+        return NULL;
+    }
+    if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type,
+                          &resunicode, newpos)) {
+        Py_DECREF(restuple);
+        return NULL;
+    }
+    if (*newpos<0)
+        *newpos = size+*newpos;
+    if (*newpos<0 || *newpos>size) {
+        PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
+        Py_DECREF(restuple);
+        return NULL;
+    }
+    Py_INCREF(resunicode);
+    Py_DECREF(restuple);
+    return resunicode;
+}
+
+static PyObject *unicode_encode_ucs1(const Py_UNICODE *p,
+                                     Py_ssize_t size,
+                                     const char *errors,
+                                     int limit)
+{
+    /* output object */
+    PyObject *res;
+    /* pointers to the beginning and end+1 of input */
+    const Py_UNICODE *startp = p;
+    const Py_UNICODE *endp = p + size;
+    /* pointer to the beginning of the unencodable characters */
+    /* const Py_UNICODE *badp = NULL; */
+    /* pointer into the output */
+    char *str;
+    /* current output position */
+    Py_ssize_t respos = 0;
+    Py_ssize_t ressize;
+    const char *encoding = (limit == 256) ? "latin-1" : "ascii";
+    const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)";
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    /* allocate enough for a simple encoding without
+       replacements, if we need more, we'll resize */
+    res = PyString_FromStringAndSize(NULL, size);
+    if (res == NULL)
+        goto onError;
+    if (size == 0)
+        return res;
+    str = PyString_AS_STRING(res);
+    ressize = size;
+
+    while (p<endp) {
+        Py_UNICODE c = *p;
+
+        /* can we encode this? */
+        if (c<limit) {
+            /* no overflow check, because we know that the space is enough */
+            *str++ = (char)c;
+            ++p;
+        }
+        else {
+            Py_ssize_t unicodepos = p-startp;
+            Py_ssize_t requiredsize;
+            PyObject *repunicode;
+            Py_ssize_t repsize;
+            Py_ssize_t newpos;
+            Py_ssize_t respos;
+            Py_UNICODE *uni2;
+            /* startpos for collecting unencodable chars */
+            const Py_UNICODE *collstart = p;
+            const Py_UNICODE *collend = p;
+            /* find all unecodable characters */
+            while ((collend < endp) && ((*collend)>=limit))
+                ++collend;
+            /* cache callback name lookup (if not done yet, i.e. it's the first error) */
+            if (known_errorHandler==-1) {
+                if ((errors==NULL) || (!strcmp(errors, "strict")))
+                    known_errorHandler = 1;
+                else if (!strcmp(errors, "replace"))
+                    known_errorHandler = 2;
+                else if (!strcmp(errors, "ignore"))
+                    known_errorHandler = 3;
+                else if (!strcmp(errors, "xmlcharrefreplace"))
+                    known_errorHandler = 4;
+                else
+                    known_errorHandler = 0;
+            }
+            switch (known_errorHandler) {
+            case 1: /* strict */
+                raise_encode_exception(&exc, encoding, startp, size, collstart-startp, collend-startp, reason);
+                goto onError;
+            case 2: /* replace */
+                while (collstart++<collend)
+                    *str++ = '?'; /* fall through */
+            case 3: /* ignore */
+                p = collend;
+                break;
+            case 4: /* xmlcharrefreplace */
+                respos = str-PyString_AS_STRING(res);
+                /* determine replacement size (temporarily (mis)uses p) */
+                for (p = collstart, repsize = 0; p < collend; ++p) {
+                    if (*p<10)
+                        repsize += 2+1+1;
+                    else if (*p<100)
+                        repsize += 2+2+1;
+                    else if (*p<1000)
+                        repsize += 2+3+1;
+                    else if (*p<10000)
+                        repsize += 2+4+1;
+#ifndef Py_UNICODE_WIDE
+                    else
+                        repsize += 2+5+1;
+#else
+                    else if (*p<100000)
+                        repsize += 2+5+1;
+                    else if (*p<1000000)
+                        repsize += 2+6+1;
+                    else
+                        repsize += 2+7+1;
+#endif
+                }
+                requiredsize = respos+repsize+(endp-collend);
+                if (requiredsize > ressize) {
+                    if (requiredsize<2*ressize)
+                        requiredsize = 2*ressize;
+                    if (_PyString_Resize(&res, requiredsize))
+                        goto onError;
+                    str = PyString_AS_STRING(res) + respos;
+                    ressize = requiredsize;
+                }
+                /* generate replacement (temporarily (mis)uses p) */
+                for (p = collstart; p < collend; ++p) {
+                    str += sprintf(str, "&#%d;", (int)*p);
+                }
+                p = collend;
+                break;
+            default:
+                repunicode = unicode_encode_call_errorhandler(errors, &errorHandler,
+                                                              encoding, reason, startp, size, &exc,
+                                                              collstart-startp, collend-startp, &newpos);
+                if (repunicode == NULL)
+                    goto onError;
+                /* need more space? (at least enough for what we have+the
+                   replacement+the rest of the string, so we won't have to
+                   check space for encodable characters) */
+                respos = str-PyString_AS_STRING(res);
+                repsize = PyUnicode_GET_SIZE(repunicode);
+                requiredsize = respos+repsize+(endp-collend);
+                if (requiredsize > ressize) {
+                    if (requiredsize<2*ressize)
+                        requiredsize = 2*ressize;
+                    if (_PyString_Resize(&res, requiredsize)) {
+                        Py_DECREF(repunicode);
+                        goto onError;
+                    }
+                    str = PyString_AS_STRING(res) + respos;
+                    ressize = requiredsize;
+                }
+                /* check if there is anything unencodable in the replacement
+                   and copy it to the output */
+                for (uni2 = PyUnicode_AS_UNICODE(repunicode);repsize-->0; ++uni2, ++str) {
+                    c = *uni2;
+                    if (c >= limit) {
+                        raise_encode_exception(&exc, encoding, startp, size,
+                                               unicodepos, unicodepos+1, reason);
+                        Py_DECREF(repunicode);
+                        goto onError;
+                    }
+                    *str = (char)c;
+                }
+                p = startp + newpos;
+                Py_DECREF(repunicode);
+            }
+        }
+    }
+    /* Resize if we allocated to much */
+    respos = str-PyString_AS_STRING(res);
+    if (respos<ressize)
+        /* If this falls res will be NULL */
+        _PyString_Resize(&res, respos);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return res;
+
+  onError:
+    Py_XDECREF(res);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p,
+                                 Py_ssize_t size,
+                                 const char *errors)
+{
+    return unicode_encode_ucs1(p, size, errors, 256);
+}
+
+PyObject *PyUnicode_AsLatin1String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode),
+                                  PyUnicode_GET_SIZE(unicode),
+                                  NULL);
+}
+
+/* --- 7-bit ASCII Codec -------------------------------------------------- */
+
+PyObject *PyUnicode_DecodeASCII(const char *s,
+                                Py_ssize_t size,
+                                const char *errors)
+{
+    const char *starts = s;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    /* ASCII is equivalent to the first 128 ordinals in Unicode. */
+    if (size == 1 && *(unsigned char*)s < 128) {
+        Py_UNICODE r = *(unsigned char*)s;
+        return PyUnicode_FromUnicode(&r, 1);
+    }
+
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+        goto onError;
+    if (size == 0)
+        return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    e = s + size;
+    while (s < e) {
+        register unsigned char c = (unsigned char)*s;
+        if (c < 128) {
+            *p++ = c;
+            ++s;
+        }
+        else {
+            startinpos = s-starts;
+            endinpos = startinpos + 1;
+            outpos = p - (Py_UNICODE *)PyUnicode_AS_UNICODE(v);
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "ascii", "ordinal not in range(128)",
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    &v, &outpos, &p))
+                goto onError;
+        }
+    }
+    if (p - PyUnicode_AS_UNICODE(v) < PyString_GET_SIZE(v))
+        if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+            goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+  onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p,
+                                Py_ssize_t size,
+                                const char *errors)
+{
+    return unicode_encode_ucs1(p, size, errors, 128);
+}
+
+PyObject *PyUnicode_AsASCIIString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode),
+                                 PyUnicode_GET_SIZE(unicode),
+                                 NULL);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+/* --- MBCS codecs for Windows -------------------------------------------- */
+
+#if SIZEOF_INT < SIZEOF_SIZE_T
+#define NEED_RETRY
+#endif
+
+/* XXX This code is limited to "true" double-byte encodings, as
+   a) it assumes an incomplete character consists of a single byte, and
+   b) IsDBCSLeadByte (probably) does not work for non-DBCS multi-byte
+   encodings, see IsDBCSLeadByteEx documentation. */
+
+static int is_dbcs_lead_byte(const char *s, int offset)
+{
+    const char *curr = s + offset;
+
+    if (IsDBCSLeadByte(*curr)) {
+        const char *prev = CharPrev(s, curr);
+        return (prev == curr) || !IsDBCSLeadByte(*prev) || (curr - prev == 2);
+    }
+    return 0;
+}
+
+/*
+ * Decode MBCS string into unicode object. If 'final' is set, converts
+ * trailing lead-byte too. Returns consumed size if succeed, -1 otherwise.
+ */
+static int decode_mbcs(PyUnicodeObject **v,
+                       const char *s, /* MBCS string */
+                       int size, /* sizeof MBCS string */
+                       int final)
+{
+    Py_UNICODE *p;
+    Py_ssize_t n = 0;
+    int usize = 0;
+
+    assert(size >= 0);
+
+    /* Skip trailing lead-byte unless 'final' is set */
+    if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1))
+        --size;
+
+    /* First get the size of the result */
+    if (size > 0) {
+        usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0);
+        if (usize == 0) {
+            PyErr_SetFromWindowsErrWithFilename(0, NULL);
+            return -1;
+        }
+    }
+
+    if (*v == NULL) {
+        /* Create unicode object */
+        *v = _PyUnicode_New(usize);
+        if (*v == NULL)
+            return -1;
+    }
+    else {
+        /* Extend unicode object */
+        n = PyUnicode_GET_SIZE(*v);
+        if (_PyUnicode_Resize(v, n + usize) < 0)
+            return -1;
+    }
+
+    /* Do the conversion */
+    if (size > 0) {
+        p = PyUnicode_AS_UNICODE(*v) + n;
+        if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) {
+            PyErr_SetFromWindowsErrWithFilename(0, NULL);
+            return -1;
+        }
+    }
+
+    return size;
+}
+
+PyObject *PyUnicode_DecodeMBCSStateful(const char *s,
+                                       Py_ssize_t size,
+                                       const char *errors,
+                                       Py_ssize_t *consumed)
+{
+    PyUnicodeObject *v = NULL;
+    int done;
+
+    if (consumed)
+        *consumed = 0;
+
+#ifdef NEED_RETRY
+  retry:
+    if (size > INT_MAX)
+        done = decode_mbcs(&v, s, INT_MAX, 0);
+    else
+#endif
+        done = decode_mbcs(&v, s, (int)size, !consumed);
+
+    if (done < 0) {
+        Py_XDECREF(v);
+        return NULL;
+    }
+
+    if (consumed)
+        *consumed += done;
+
+#ifdef NEED_RETRY
+    if (size > INT_MAX) {
+        s += done;
+        size -= done;
+        goto retry;
+    }
+#endif
+
+    return (PyObject *)v;
+}
+
+PyObject *PyUnicode_DecodeMBCS(const char *s,
+                               Py_ssize_t size,
+                               const char *errors)
+{
+    return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL);
+}
+
+/*
+ * Convert unicode into string object (MBCS).
+ * Returns 0 if succeed, -1 otherwise.
+ */
+static int encode_mbcs(PyObject **repr,
+                       const Py_UNICODE *p, /* unicode */
+                       int size) /* size of unicode */
+{
+    int mbcssize = 0;
+    Py_ssize_t n = 0;
+
+    assert(size >= 0);
+
+    /* First get the size of the result */
+    if (size > 0) {
+        mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL);
+        if (mbcssize == 0) {
+            PyErr_SetFromWindowsErrWithFilename(0, NULL);
+            return -1;
+        }
+    }
+
+    if (*repr == NULL) {
+        /* Create string object */
+        *repr = PyString_FromStringAndSize(NULL, mbcssize);
+        if (*repr == NULL)
+            return -1;
+    }
+    else {
+        /* Extend string object */
+        n = PyString_Size(*repr);
+        if (_PyString_Resize(repr, n + mbcssize) < 0)
+            return -1;
+    }
+
+    /* Do the conversion */
+    if (size > 0) {
+        char *s = PyString_AS_STRING(*repr) + n;
+        if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) {
+            PyErr_SetFromWindowsErrWithFilename(0, NULL);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p,
+                               Py_ssize_t size,
+                               const char *errors)
+{
+    PyObject *repr = NULL;
+    int ret;
+
+#ifdef NEED_RETRY
+  retry:
+    if (size > INT_MAX)
+        ret = encode_mbcs(&repr, p, INT_MAX);
+    else
+#endif
+        ret = encode_mbcs(&repr, p, (int)size);
+
+    if (ret < 0) {
+        Py_XDECREF(repr);
+        return NULL;
+    }
+
+#ifdef NEED_RETRY
+    if (size > INT_MAX) {
+        p += INT_MAX;
+        size -= INT_MAX;
+        goto retry;
+    }
+#endif
+
+    return repr;
+}
+
+PyObject *PyUnicode_AsMBCSString(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode),
+                                PyUnicode_GET_SIZE(unicode),
+                                NULL);
+}
+
+#undef NEED_RETRY
+
+#endif /* MS_WINDOWS */
+
+/* --- Character Mapping Codec -------------------------------------------- */
+
+PyObject *PyUnicode_DecodeCharmap(const char *s,
+                                  Py_ssize_t size,
+                                  PyObject *mapping,
+                                  const char *errors)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    const char *e;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    Py_ssize_t extrachars = 0;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    Py_UNICODE *mapstring = NULL;
+    Py_ssize_t maplen = 0;
+
+    /* Default to Latin-1 */
+    if (mapping == NULL)
+        return PyUnicode_DecodeLatin1(s, size, errors);
+
+    v = _PyUnicode_New(size);
+    if (v == NULL)
+        goto onError;
+    if (size == 0)
+        return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    e = s + size;
+    if (PyUnicode_CheckExact(mapping)) {
+        mapstring = PyUnicode_AS_UNICODE(mapping);
+        maplen = PyUnicode_GET_SIZE(mapping);
+        while (s < e) {
+            unsigned char ch = *s;
+            Py_UNICODE x = 0xfffe; /* illegal value */
+
+            if (ch < maplen)
+                x = mapstring[ch];
+
+            if (x == 0xfffe) {
+                /* undefined mapping */
+                outpos = p-PyUnicode_AS_UNICODE(v);
+                startinpos = s-starts;
+                endinpos = startinpos+1;
+                if (unicode_decode_call_errorhandler(
+                        errors, &errorHandler,
+                        "charmap", "character maps to <undefined>",
+                        starts, size, &startinpos, &endinpos, &exc, &s,
+                        &v, &outpos, &p)) {
+                    goto onError;
+                }
+                continue;
+            }
+            *p++ = x;
+            ++s;
+        }
+    }
+    else {
+        while (s < e) {
+            unsigned char ch = *s;
+            PyObject *w, *x;
+
+            /* Get mapping (char ordinal -> integer, Unicode char or None) */
+            w = PyInt_FromLong((long)ch);
+            if (w == NULL)
+                goto onError;
+            x = PyObject_GetItem(mapping, w);
+            Py_DECREF(w);
+            if (x == NULL) {
+                if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+                    /* No mapping found means: mapping is undefined. */
+                    PyErr_Clear();
+                    goto Undefined;
+                } else
+                    goto onError;
+            }
+
+            /* Apply mapping */
+            if (x == Py_None)
+                goto Undefined;
+            if (PyInt_Check(x)) {
+                long value = PyInt_AS_LONG(x);
+                if (value == 0xFFFE)
+                    goto Undefined;
+                if (value < 0 || value > 0x10FFFF) {
+                    PyErr_SetString(PyExc_TypeError,
+                                    "character mapping must be in range(0x110000)");
+                    Py_DECREF(x);
+                    goto onError;
+                }
+
+#ifndef Py_UNICODE_WIDE
+                if (value > 0xFFFF) {
+                    /* see the code for 1-n mapping below */
+                    if (extrachars < 2) {
+                        /* resize first */
+                        Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v);
+                        Py_ssize_t needed = 10 - extrachars;
+                        extrachars += needed;
+                        /* XXX overflow detection missing */
+                        if (_PyUnicode_Resize(&v,
+                                              PyUnicode_GET_SIZE(v) + needed) < 0) {
+                            Py_DECREF(x);
+                            goto onError;
+                        }
+                        p = PyUnicode_AS_UNICODE(v) + oldpos;
+                    }
+                    value -= 0x10000;
+                    *p++ = 0xD800 | (value >> 10);
+                    *p++ = 0xDC00 | (value & 0x3FF);
+                    extrachars -= 2;
+                }
+                else
+#endif
+                *p++ = (Py_UNICODE)value;
+            }
+            else if (PyUnicode_Check(x)) {
+                Py_ssize_t targetsize = PyUnicode_GET_SIZE(x);
+
+                if (targetsize == 1) {
+                    /* 1-1 mapping */
+                    Py_UNICODE value = *PyUnicode_AS_UNICODE(x);
+                    if (value == 0xFFFE)
+                        goto Undefined;
+                    *p++ = value;
+                }
+                else if (targetsize > 1) {
+                    /* 1-n mapping */
+                    if (targetsize > extrachars) {
+                        /* resize first */
+                        Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v);
+                        Py_ssize_t needed = (targetsize - extrachars) + \
+                            (targetsize << 2);
+                        extrachars += needed;
+                        /* XXX overflow detection missing */
+                        if (_PyUnicode_Resize(&v,
+                                              PyUnicode_GET_SIZE(v) + needed) < 0) {
+                            Py_DECREF(x);
+                            goto onError;
+                        }
+                        p = PyUnicode_AS_UNICODE(v) + oldpos;
+                    }
+                    Py_UNICODE_COPY(p,
+                                    PyUnicode_AS_UNICODE(x),
+                                    targetsize);
+                    p += targetsize;
+                    extrachars -= targetsize;
+                }
+                /* 1-0 mapping: skip the character */
+            }
+            else {
+                /* wrong return value */
+                PyErr_SetString(PyExc_TypeError,
+                                "character mapping must return integer, None or unicode");
+                Py_DECREF(x);
+                goto onError;
+            }
+            Py_DECREF(x);
+            ++s;
+            continue;
+Undefined:
+            /* undefined mapping */
+            Py_XDECREF(x);
+            outpos = p-PyUnicode_AS_UNICODE(v);
+            startinpos = s-starts;
+            endinpos = startinpos+1;
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "charmap", "character maps to <undefined>",
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    &v, &outpos, &p)) {
+                goto onError;
+            }
+        }
+    }
+    if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v))
+        if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+            goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+  onError:
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    Py_XDECREF(v);
+    return NULL;
+}
+
+/* Charmap encoding: the lookup table */
+
+struct encoding_map{
+    PyObject_HEAD
+    unsigned char level1[32];
+    int count2, count3;
+    unsigned char level23[1];
+};
+
+static PyObject*
+encoding_map_size(PyObject *obj, PyObject* args)
+{
+    struct encoding_map *map = (struct encoding_map*)obj;
+    return PyInt_FromLong(sizeof(*map) - 1 + 16*map->count2 +
+                          128*map->count3);
+}
+
+static PyMethodDef encoding_map_methods[] = {
+    {"size", encoding_map_size, METH_NOARGS,
+     PyDoc_STR("Return the size (in bytes) of this object") },
+    { 0 }
+};
+
+static void
+encoding_map_dealloc(PyObject* o)
+{
+    PyObject_FREE(o);
+}
+
+static PyTypeObject EncodingMapType = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "EncodingMap",          /*tp_name*/
+    sizeof(struct encoding_map),   /*tp_basicsize*/
+    0,                      /*tp_itemsize*/
+    /* methods */
+    encoding_map_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*/
+    0,                      /*tp_str*/
+    0,                      /*tp_getattro*/
+    0,                      /*tp_setattro*/
+    0,                      /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+    0,                      /*tp_doc*/
+    0,                      /*tp_traverse*/
+    0,                      /*tp_clear*/
+    0,                      /*tp_richcompare*/
+    0,                      /*tp_weaklistoffset*/
+    0,                      /*tp_iter*/
+    0,                      /*tp_iternext*/
+    encoding_map_methods,   /*tp_methods*/
+    0,                      /*tp_members*/
+    0,                      /*tp_getset*/
+    0,                      /*tp_base*/
+    0,                      /*tp_dict*/
+    0,                      /*tp_descr_get*/
+    0,                      /*tp_descr_set*/
+    0,                      /*tp_dictoffset*/
+    0,                      /*tp_init*/
+    0,                      /*tp_alloc*/
+    0,                      /*tp_new*/
+    0,                      /*tp_free*/
+    0,                      /*tp_is_gc*/
+};
+
+PyObject*
+PyUnicode_BuildEncodingMap(PyObject* string)
+{
+    Py_UNICODE *decode;
+    PyObject *result;
+    struct encoding_map *mresult;
+    int i;
+    int need_dict = 0;
+    unsigned char level1[32];
+    unsigned char level2[512];
+    unsigned char *mlevel1, *mlevel2, *mlevel3;
+    int count2 = 0, count3 = 0;
+
+    if (!PyUnicode_Check(string) || PyUnicode_GetSize(string) != 256) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    decode = PyUnicode_AS_UNICODE(string);
+    memset(level1, 0xFF, sizeof level1);
+    memset(level2, 0xFF, sizeof level2);
+
+    /* If there isn't a one-to-one mapping of NULL to \0,
+       or if there are non-BMP characters, we need to use
+       a mapping dictionary. */
+    if (decode[0] != 0)
+        need_dict = 1;
+    for (i = 1; i < 256; i++) {
+        int l1, l2;
+        if (decode[i] == 0
+#ifdef Py_UNICODE_WIDE
+            || decode[i] > 0xFFFF
+#endif
+            ) {
+            need_dict = 1;
+            break;
+        }
+        if (decode[i] == 0xFFFE)
+            /* unmapped character */
+            continue;
+        l1 = decode[i] >> 11;
+        l2 = decode[i] >> 7;
+        if (level1[l1] == 0xFF)
+            level1[l1] = count2++;
+        if (level2[l2] == 0xFF)
+            level2[l2] = count3++;
+    }
+
+    if (count2 >= 0xFF || count3 >= 0xFF)
+        need_dict = 1;
+
+    if (need_dict) {
+        PyObject *result = PyDict_New();
+        PyObject *key, *value;
+        if (!result)
+            return NULL;
+        for (i = 0; i < 256; i++) {
+            value = NULL;
+            key = PyInt_FromLong(decode[i]);
+            value = PyInt_FromLong(i);
+            if (!key || !value)
+                goto failed1;
+            if (PyDict_SetItem(result, key, value) == -1)
+                goto failed1;
+            Py_DECREF(key);
+            Py_DECREF(value);
+        }
+        return result;
+      failed1:
+        Py_XDECREF(key);
+        Py_XDECREF(value);
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    /* Create a three-level trie */
+    result = PyObject_MALLOC(sizeof(struct encoding_map) +
+                             16*count2 + 128*count3 - 1);
+    if (!result)
+        return PyErr_NoMemory();
+    PyObject_Init(result, &EncodingMapType);
+    mresult = (struct encoding_map*)result;
+    mresult->count2 = count2;
+    mresult->count3 = count3;
+    mlevel1 = mresult->level1;
+    mlevel2 = mresult->level23;
+    mlevel3 = mresult->level23 + 16*count2;
+    memcpy(mlevel1, level1, 32);
+    memset(mlevel2, 0xFF, 16*count2);
+    memset(mlevel3, 0, 128*count3);
+    count3 = 0;
+    for (i = 1; i < 256; i++) {
+        int o1, o2, o3, i2, i3;
+        if (decode[i] == 0xFFFE)
+            /* unmapped character */
+            continue;
+        o1 = decode[i]>>11;
+        o2 = (decode[i]>>7) & 0xF;
+        i2 = 16*mlevel1[o1] + o2;
+        if (mlevel2[i2] == 0xFF)
+            mlevel2[i2] = count3++;
+        o3 = decode[i] & 0x7F;
+        i3 = 128*mlevel2[i2] + o3;
+        mlevel3[i3] = i;
+    }
+    return result;
+}
+
+static int
+encoding_map_lookup(Py_UNICODE c, PyObject *mapping)
+{
+    struct encoding_map *map = (struct encoding_map*)mapping;
+    int l1 = c>>11;
+    int l2 = (c>>7) & 0xF;
+    int l3 = c & 0x7F;
+    int i;
+
+#ifdef Py_UNICODE_WIDE
+    if (c > 0xFFFF) {
+        return -1;
+    }
+#endif
+    if (c == 0)
+        return 0;
+    /* level 1*/
+    i = map->level1[l1];
+    if (i == 0xFF) {
+        return -1;
+    }
+    /* level 2*/
+    i = map->level23[16*i+l2];
+    if (i == 0xFF) {
+        return -1;
+    }
+    /* level 3 */
+    i = map->level23[16*map->count2 + 128*i + l3];
+    if (i == 0) {
+        return -1;
+    }
+    return i;
+}
+
+/* Lookup the character ch in the mapping. If the character
+   can't be found, Py_None is returned (or NULL, if another
+   error occurred). */
+static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping)
+{
+    PyObject *w = PyInt_FromLong((long)c);
+    PyObject *x;
+
+    if (w == NULL)
+        return NULL;
+    x = PyObject_GetItem(mapping, w);
+    Py_DECREF(w);
+    if (x == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+            /* No mapping found means: mapping is undefined. */
+            PyErr_Clear();
+            x = Py_None;
+            Py_INCREF(x);
+            return x;
+        } else
+            return NULL;
+    }
+    else if (x == Py_None)
+        return x;
+    else if (PyInt_Check(x)) {
+        long value = PyInt_AS_LONG(x);
+        if (value < 0 || value > 255) {
+            PyErr_SetString(PyExc_TypeError,
+                            "character mapping must be in range(256)");
+            Py_DECREF(x);
+            return NULL;
+        }
+        return x;
+    }
+    else if (PyString_Check(x))
+        return x;
+    else {
+        /* wrong return value */
+        PyErr_SetString(PyExc_TypeError,
+                        "character mapping must return integer, None or str");
+        Py_DECREF(x);
+        return NULL;
+    }
+}
+
+static int
+charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize)
+{
+    Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
+    /* exponentially overallocate to minimize reallocations */
+    if (requiredsize < 2*outsize)
+        requiredsize = 2*outsize;
+    if (_PyString_Resize(outobj, requiredsize)) {
+        return 0;
+    }
+    return 1;
+}
+
+typedef enum charmapencode_result {
+    enc_SUCCESS, enc_FAILED, enc_EXCEPTION
+}charmapencode_result;
+/* lookup the character, put the result in the output string and adjust
+   various state variables. Reallocate the output string if not enough
+   space is available. Return a new reference to the object that
+   was put in the output buffer, or Py_None, if the mapping was undefined
+   (in which case no character was written) or NULL, if a
+   reallocation error occurred. The caller must decref the result */
+static
+charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
+                                          PyObject **outobj, Py_ssize_t *outpos)
+{
+    PyObject *rep;
+    char *outstart;
+    Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
+
+    if (Py_TYPE(mapping) == &EncodingMapType) {
+        int res = encoding_map_lookup(c, mapping);
+        Py_ssize_t requiredsize = *outpos+1;
+        if (res == -1)
+            return enc_FAILED;
+        if (outsize<requiredsize)
+            if (!charmapencode_resize(outobj, outpos, requiredsize))
+                return enc_EXCEPTION;
+        outstart = PyString_AS_STRING(*outobj);
+        outstart[(*outpos)++] = (char)res;
+        return enc_SUCCESS;
+    }
+
+    rep = charmapencode_lookup(c, mapping);
+    if (rep==NULL)
+        return enc_EXCEPTION;
+    else if (rep==Py_None) {
+        Py_DECREF(rep);
+        return enc_FAILED;
+    } else {
+        if (PyInt_Check(rep)) {
+            Py_ssize_t requiredsize = *outpos+1;
+            if (outsize<requiredsize)
+                if (!charmapencode_resize(outobj, outpos, requiredsize)) {
+                    Py_DECREF(rep);
+                    return enc_EXCEPTION;
+                }
+            outstart = PyString_AS_STRING(*outobj);
+            outstart[(*outpos)++] = (char)PyInt_AS_LONG(rep);
+        }
+        else {
+            const char *repchars = PyString_AS_STRING(rep);
+            Py_ssize_t repsize = PyString_GET_SIZE(rep);
+            Py_ssize_t requiredsize = *outpos+repsize;
+            if (outsize<requiredsize)
+                if (!charmapencode_resize(outobj, outpos, requiredsize)) {
+                    Py_DECREF(rep);
+                    return enc_EXCEPTION;
+                }
+            outstart = PyString_AS_STRING(*outobj);
+            memcpy(outstart + *outpos, repchars, repsize);
+            *outpos += repsize;
+        }
+    }
+    Py_DECREF(rep);
+    return enc_SUCCESS;
+}
+
+/* handle an error in PyUnicode_EncodeCharmap
+   Return 0 on success, -1 on error */
+static
+int charmap_encoding_error(
+    const Py_UNICODE *p, Py_ssize_t size, Py_ssize_t *inpos, PyObject *mapping,
+    PyObject **exceptionObject,
+    int *known_errorHandler, PyObject **errorHandler, const char *errors,
+    PyObject **res, Py_ssize_t *respos)
+{
+    PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
+    Py_ssize_t repsize;
+    Py_ssize_t newpos;
+    Py_UNICODE *uni2;
+    /* startpos for collecting unencodable chars */
+    Py_ssize_t collstartpos = *inpos;
+    Py_ssize_t collendpos = *inpos+1;
+    Py_ssize_t collpos;
+    char *encoding = "charmap";
+    char *reason = "character maps to <undefined>";
+    charmapencode_result x;
+
+    /* find all unencodable characters */
+    while (collendpos < size) {
+        PyObject *rep;
+        if (Py_TYPE(mapping) == &EncodingMapType) {
+            int res = encoding_map_lookup(p[collendpos], mapping);
+            if (res != -1)
+                break;
+            ++collendpos;
+            continue;
+        }
+
+        rep = charmapencode_lookup(p[collendpos], mapping);
+        if (rep==NULL)
+            return -1;
+        else if (rep!=Py_None) {
+            Py_DECREF(rep);
+            break;
+        }
+        Py_DECREF(rep);
+        ++collendpos;
+    }
+    /* cache callback name lookup
+     * (if not done yet, i.e. it's the first error) */
+    if (*known_errorHandler==-1) {
+        if ((errors==NULL) || (!strcmp(errors, "strict")))
+            *known_errorHandler = 1;
+        else if (!strcmp(errors, "replace"))
+            *known_errorHandler = 2;
+        else if (!strcmp(errors, "ignore"))
+            *known_errorHandler = 3;
+        else if (!strcmp(errors, "xmlcharrefreplace"))
+            *known_errorHandler = 4;
+        else
+            *known_errorHandler = 0;
+    }
+    switch (*known_errorHandler) {
+    case 1: /* strict */
+        raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+        return -1;
+    case 2: /* replace */
+        for (collpos = collstartpos; collpos<collendpos; ++collpos) {
+            x = charmapencode_output('?', mapping, res, respos);
+            if (x==enc_EXCEPTION) {
+                return -1;
+            }
+            else if (x==enc_FAILED) {
+                raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+                return -1;
+            }
+        }
+        /* fall through */
+    case 3: /* ignore */
+        *inpos = collendpos;
+        break;
+    case 4: /* xmlcharrefreplace */
+        /* generate replacement (temporarily (mis)uses p) */
+        for (collpos = collstartpos; collpos < collendpos; ++collpos) {
+            char buffer[2+29+1+1];
+            char *cp;
+            sprintf(buffer, "&#%d;", (int)p[collpos]);
+            for (cp = buffer; *cp; ++cp) {
+                x = charmapencode_output(*cp, mapping, res, respos);
+                if (x==enc_EXCEPTION)
+                    return -1;
+                else if (x==enc_FAILED) {
+                    raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+                    return -1;
+                }
+            }
+        }
+        *inpos = collendpos;
+        break;
+    default:
+        repunicode = unicode_encode_call_errorhandler(errors, errorHandler,
+                                                      encoding, reason, p, size, exceptionObject,
+                                                      collstartpos, collendpos, &newpos);
+        if (repunicode == NULL)
+            return -1;
+        /* generate replacement  */
+        repsize = PyUnicode_GET_SIZE(repunicode);
+        for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) {
+            x = charmapencode_output(*uni2, mapping, res, respos);
+            if (x==enc_EXCEPTION) {
+                return -1;
+            }
+            else if (x==enc_FAILED) {
+                Py_DECREF(repunicode);
+                raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+                return -1;
+            }
+        }
+        *inpos = newpos;
+        Py_DECREF(repunicode);
+    }
+    return 0;
+}
+
+PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
+                                  Py_ssize_t size,
+                                  PyObject *mapping,
+                                  const char *errors)
+{
+    /* output object */
+    PyObject *res = NULL;
+    /* current input position */
+    Py_ssize_t inpos = 0;
+    /* current output position */
+    Py_ssize_t respos = 0;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace,
+     * 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    /* Default to Latin-1 */
+    if (mapping == NULL)
+        return PyUnicode_EncodeLatin1(p, size, errors);
+
+    /* allocate enough for a simple encoding without
+       replacements, if we need more, we'll resize */
+    res = PyString_FromStringAndSize(NULL, size);
+    if (res == NULL)
+        goto onError;
+    if (size == 0)
+        return res;
+
+    while (inpos<size) {
+        /* try to encode it */
+        charmapencode_result x = charmapencode_output(p[inpos], mapping, &res, &respos);
+        if (x==enc_EXCEPTION) /* error */
+            goto onError;
+        if (x==enc_FAILED) { /* unencodable character */
+            if (charmap_encoding_error(p, size, &inpos, mapping,
+                                       &exc,
+                                       &known_errorHandler, &errorHandler, errors,
+                                       &res, &respos)) {
+                goto onError;
+            }
+        }
+        else
+            /* done with this character => adjust input position */
+            ++inpos;
+    }
+
+    /* Resize if we allocated to much */
+    if (respos<PyString_GET_SIZE(res)) {
+        if (_PyString_Resize(&res, respos))
+            goto onError;
+    }
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return res;
+
+  onError:
+    Py_XDECREF(res);
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return NULL;
+}
+
+PyObject *PyUnicode_AsCharmapString(PyObject *unicode,
+                                    PyObject *mapping)
+{
+    if (!PyUnicode_Check(unicode) || mapping == NULL) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeCharmap(PyUnicode_AS_UNICODE(unicode),
+                                   PyUnicode_GET_SIZE(unicode),
+                                   mapping,
+                                   NULL);
+}
+
+/* create or adjust a UnicodeTranslateError */
+static void make_translate_exception(PyObject **exceptionObject,
+                                     const Py_UNICODE *unicode, Py_ssize_t size,
+                                     Py_ssize_t startpos, Py_ssize_t endpos,
+                                     const char *reason)
+{
+    if (*exceptionObject == NULL) {
+        *exceptionObject = PyUnicodeTranslateError_Create(
+            unicode, size, startpos, endpos, reason);
+    }
+    else {
+        if (PyUnicodeTranslateError_SetStart(*exceptionObject, startpos))
+            goto onError;
+        if (PyUnicodeTranslateError_SetEnd(*exceptionObject, endpos))
+            goto onError;
+        if (PyUnicodeTranslateError_SetReason(*exceptionObject, reason))
+            goto onError;
+        return;
+      onError:
+        Py_DECREF(*exceptionObject);
+        *exceptionObject = NULL;
+    }
+}
+
+/* raises a UnicodeTranslateError */
+static void raise_translate_exception(PyObject **exceptionObject,
+                                      const Py_UNICODE *unicode, Py_ssize_t size,
+                                      Py_ssize_t startpos, Py_ssize_t endpos,
+                                      const char *reason)
+{
+    make_translate_exception(exceptionObject,
+                             unicode, size, startpos, endpos, reason);
+    if (*exceptionObject != NULL)
+        PyCodec_StrictErrors(*exceptionObject);
+}
+
+/* error handling callback helper:
+   build arguments, call the callback and check the arguments,
+   put the result into newpos and return the replacement string, which
+   has to be freed by the caller */
+static PyObject *unicode_translate_call_errorhandler(const char *errors,
+                                                     PyObject **errorHandler,
+                                                     const char *reason,
+                                                     const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject,
+                                                     Py_ssize_t startpos, Py_ssize_t endpos,
+                                                     Py_ssize_t *newpos)
+{
+    static char *argparse = "O!n;translating error handler must return (unicode, int) tuple";
+
+    Py_ssize_t i_newpos;
+    PyObject *restuple;
+    PyObject *resunicode;
+
+    if (*errorHandler == NULL) {
+        *errorHandler = PyCodec_LookupError(errors);
+        if (*errorHandler == NULL)
+            return NULL;
+    }
+
+    make_translate_exception(exceptionObject,
+                             unicode, size, startpos, endpos, reason);
+    if (*exceptionObject == NULL)
+        return NULL;
+
+    restuple = PyObject_CallFunctionObjArgs(
+        *errorHandler, *exceptionObject, NULL);
+    if (restuple == NULL)
+        return NULL;
+    if (!PyTuple_Check(restuple)) {
+        PyErr_SetString(PyExc_TypeError, &argparse[4]);
+        Py_DECREF(restuple);
+        return NULL;
+    }
+    if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type,
+                          &resunicode, &i_newpos)) {
+        Py_DECREF(restuple);
+        return NULL;
+    }
+    if (i_newpos<0)
+        *newpos = size+i_newpos;
+    else
+        *newpos = i_newpos;
+    if (*newpos<0 || *newpos>size) {
+        PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
+        Py_DECREF(restuple);
+        return NULL;
+    }
+    Py_INCREF(resunicode);
+    Py_DECREF(restuple);
+    return resunicode;
+}
+
+/* Lookup the character ch in the mapping and put the result in result,
+   which must be decrefed by the caller.
+   Return 0 on success, -1 on error */
+static
+int charmaptranslate_lookup(Py_UNICODE c, PyObject *mapping, PyObject **result)
+{
+    PyObject *w = PyInt_FromLong((long)c);
+    PyObject *x;
+
+    if (w == NULL)
+        return -1;
+    x = PyObject_GetItem(mapping, w);
+    Py_DECREF(w);
+    if (x == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+            /* No mapping found means: use 1:1 mapping. */
+            PyErr_Clear();
+            *result = NULL;
+            return 0;
+        } else
+            return -1;
+    }
+    else if (x == Py_None) {
+        *result = x;
+        return 0;
+    }
+    else if (PyInt_Check(x)) {
+        long value = PyInt_AS_LONG(x);
+        long max = PyUnicode_GetMax();
+        if (value < 0 || value > max) {
+            PyErr_Format(PyExc_TypeError,
+                         "character mapping must be in range(0x%lx)", max+1);
+            Py_DECREF(x);
+            return -1;
+        }
+        *result = x;
+        return 0;
+    }
+    else if (PyUnicode_Check(x)) {
+        *result = x;
+        return 0;
+    }
+    else {
+        /* wrong return value */
+        PyErr_SetString(PyExc_TypeError,
+                        "character mapping must return integer, None or unicode");
+        Py_DECREF(x);
+        return -1;
+    }
+}
+/* ensure that *outobj is at least requiredsize characters long,
+   if not reallocate and adjust various state variables.
+   Return 0 on success, -1 on error */
+static
+int charmaptranslate_makespace(PyObject **outobj, Py_UNICODE **outp,
+                               Py_ssize_t requiredsize)
+{
+    Py_ssize_t oldsize = PyUnicode_GET_SIZE(*outobj);
+    if (requiredsize > oldsize) {
+        /* remember old output position */
+        Py_ssize_t outpos = *outp-PyUnicode_AS_UNICODE(*outobj);
+        /* exponentially overallocate to minimize reallocations */
+        if (requiredsize < 2 * oldsize)
+            requiredsize = 2 * oldsize;
+        if (PyUnicode_Resize(outobj, requiredsize) < 0)
+            return -1;
+        *outp = PyUnicode_AS_UNICODE(*outobj) + outpos;
+    }
+    return 0;
+}
+/* lookup the character, put the result in the output string and adjust
+   various state variables. Return a new reference to the object that
+   was put in the output buffer in *result, or Py_None, if the mapping was
+   undefined (in which case no character was written).
+   The called must decref result.
+   Return 0 on success, -1 on error. */
+static
+int charmaptranslate_output(const Py_UNICODE *startinp, const Py_UNICODE *curinp,
+                            Py_ssize_t insize, PyObject *mapping, PyObject **outobj, Py_UNICODE **outp,
+                            PyObject **res)
+{
+    if (charmaptranslate_lookup(*curinp, mapping, res))
+        return -1;
+    if (*res==NULL) {
+        /* not found => default to 1:1 mapping */
+        *(*outp)++ = *curinp;
+    }
+    else if (*res==Py_None)
+        ;
+    else if (PyInt_Check(*res)) {
+        /* no overflow check, because we know that the space is enough */
+        *(*outp)++ = (Py_UNICODE)PyInt_AS_LONG(*res);
+    }
+    else if (PyUnicode_Check(*res)) {
+        Py_ssize_t repsize = PyUnicode_GET_SIZE(*res);
+        if (repsize==1) {
+            /* no overflow check, because we know that the space is enough */
+            *(*outp)++ = *PyUnicode_AS_UNICODE(*res);
+        }
+        else if (repsize!=0) {
+            /* more than one character */
+            Py_ssize_t requiredsize = (*outp-PyUnicode_AS_UNICODE(*outobj)) +
+                (insize - (curinp-startinp)) +
+                repsize - 1;
+            if (charmaptranslate_makespace(outobj, outp, requiredsize))
+                return -1;
+            memcpy(*outp, PyUnicode_AS_UNICODE(*res), sizeof(Py_UNICODE)*repsize);
+            *outp += repsize;
+        }
+    }
+    else
+        return -1;
+    return 0;
+}
+
+PyObject *PyUnicode_TranslateCharmap(const Py_UNICODE *p,
+                                     Py_ssize_t size,
+                                     PyObject *mapping,
+                                     const char *errors)
+{
+    /* output object */
+    PyObject *res = NULL;
+    /* pointers to the beginning and end+1 of input */
+    const Py_UNICODE *startp = p;
+    const Py_UNICODE *endp = p + size;
+    /* pointer into the output */
+    Py_UNICODE *str;
+    /* current output position */
+    Py_ssize_t respos = 0;
+    char *reason = "character maps to <undefined>";
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace,
+     * 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    if (mapping == NULL) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+
+    /* allocate enough for a simple 1:1 translation without
+       replacements, if we need more, we'll resize */
+    res = PyUnicode_FromUnicode(NULL, size);
+    if (res == NULL)
+        goto onError;
+    if (size == 0)
+        return res;
+    str = PyUnicode_AS_UNICODE(res);
+
+    while (p<endp) {
+        /* try to encode it */
+        PyObject *x = NULL;
+        if (charmaptranslate_output(startp, p, size, mapping, &res, &str, &x)) {
+            Py_XDECREF(x);
+            goto onError;
+        }
+        Py_XDECREF(x);
+        if (x!=Py_None) /* it worked => adjust input pointer */
+            ++p;
+        else { /* untranslatable character */
+            PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
+            Py_ssize_t repsize;
+            Py_ssize_t newpos;
+            Py_UNICODE *uni2;
+            /* startpos for collecting untranslatable chars */
+            const Py_UNICODE *collstart = p;
+            const Py_UNICODE *collend = p+1;
+            const Py_UNICODE *coll;
+
+            /* find all untranslatable characters */
+            while (collend < endp) {
+                if (charmaptranslate_lookup(*collend, mapping, &x))
+                    goto onError;
+                Py_XDECREF(x);
+                if (x!=Py_None)
+                    break;
+                ++collend;
+            }
+            /* cache callback name lookup
+             * (if not done yet, i.e. it's the first error) */
+            if (known_errorHandler==-1) {
+                if ((errors==NULL) || (!strcmp(errors, "strict")))
+                    known_errorHandler = 1;
+                else if (!strcmp(errors, "replace"))
+                    known_errorHandler = 2;
+                else if (!strcmp(errors, "ignore"))
+                    known_errorHandler = 3;
+                else if (!strcmp(errors, "xmlcharrefreplace"))
+                    known_errorHandler = 4;
+                else
+                    known_errorHandler = 0;
+            }
+            switch (known_errorHandler) {
+            case 1: /* strict */
+                raise_translate_exception(&exc, startp, size, collstart-startp, collend-startp, reason);
+                goto onError;
+            case 2: /* replace */
+                /* No need to check for space, this is a 1:1 replacement */
+                for (coll = collstart; coll<collend; ++coll)
+                    *str++ = '?';
+                /* fall through */
+            case 3: /* ignore */
+                p = collend;
+                break;
+            case 4: /* xmlcharrefreplace */
+                /* generate replacement (temporarily (mis)uses p) */
+                for (p = collstart; p < collend; ++p) {
+                    char buffer[2+29+1+1];
+                    char *cp;
+                    sprintf(buffer, "&#%d;", (int)*p);
+                    if (charmaptranslate_makespace(&res, &str,
+                                                   (str-PyUnicode_AS_UNICODE(res))+strlen(buffer)+(endp-collend)))
+                        goto onError;
+                    for (cp = buffer; *cp; ++cp)
+                        *str++ = *cp;
+                }
+                p = collend;
+                break;
+            default:
+                repunicode = unicode_translate_call_errorhandler(errors, &errorHandler,
+                                                                 reason, startp, size, &exc,
+                                                                 collstart-startp, collend-startp, &newpos);
+                if (repunicode == NULL)
+                    goto onError;
+                /* generate replacement  */
+                repsize = PyUnicode_GET_SIZE(repunicode);
+                if (charmaptranslate_makespace(&res, &str,
+                                               (str-PyUnicode_AS_UNICODE(res))+repsize+(endp-collend))) {
+                    Py_DECREF(repunicode);
+                    goto onError;
+                }
+                for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2)
+                    *str++ = *uni2;
+                p = startp + newpos;
+                Py_DECREF(repunicode);
+            }
+        }
+    }
+    /* Resize if we allocated to much */
+    respos = str-PyUnicode_AS_UNICODE(res);
+    if (respos<PyUnicode_GET_SIZE(res)) {
+        if (PyUnicode_Resize(&res, respos) < 0)
+            goto onError;
+    }
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return res;
+
+  onError:
+    Py_XDECREF(res);
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return NULL;
+}
+
+PyObject *PyUnicode_Translate(PyObject *str,
+                              PyObject *mapping,
+                              const char *errors)
+{
+    PyObject *result;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+        goto onError;
+    result = PyUnicode_TranslateCharmap(PyUnicode_AS_UNICODE(str),
+                                        PyUnicode_GET_SIZE(str),
+                                        mapping,
+                                        errors);
+    Py_DECREF(str);
+    return result;
+
+  onError:
+    Py_XDECREF(str);
+    return NULL;
+}
+
+/* --- Decimal Encoder ---------------------------------------------------- */
+
+int PyUnicode_EncodeDecimal(Py_UNICODE *s,
+                            Py_ssize_t length,
+                            char *output,
+                            const char *errors)
+{
+    Py_UNICODE *p, *end;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    const char *encoding = "decimal";
+    const char *reason = "invalid decimal Unicode string";
+    /* the following variable is used for caching string comparisons
+     * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */
+    int known_errorHandler = -1;
+
+    if (output == NULL) {
+        PyErr_BadArgument();
+        return -1;
+    }
+
+    p = s;
+    end = s + length;
+    while (p < end) {
+        register Py_UNICODE ch = *p;
+        int decimal;
+        PyObject *repunicode;
+        Py_ssize_t repsize;
+        Py_ssize_t newpos;
+        Py_UNICODE *uni2;
+        Py_UNICODE *collstart;
+        Py_UNICODE *collend;
+
+        if (Py_UNICODE_ISSPACE(ch)) {
+            *output++ = ' ';
+            ++p;
+            continue;
+        }
+        decimal = Py_UNICODE_TODECIMAL(ch);
+        if (decimal >= 0) {
+            *output++ = '0' + decimal;
+            ++p;
+            continue;
+        }
+        if (0 < ch && ch < 256) {
+            *output++ = (char)ch;
+            ++p;
+            continue;
+        }
+        /* All other characters are considered unencodable */
+        collstart = p;
+        for (collend = p+1; collend < end; collend++) {
+            if ((0 < *collend && *collend < 256) ||
+                Py_UNICODE_ISSPACE(*collend) ||
+                0 <= Py_UNICODE_TODECIMAL(*collend))
+                break;
+        }
+        /* cache callback name lookup
+         * (if not done yet, i.e. it's the first error) */
+        if (known_errorHandler==-1) {
+            if ((errors==NULL) || (!strcmp(errors, "strict")))
+                known_errorHandler = 1;
+            else if (!strcmp(errors, "replace"))
+                known_errorHandler = 2;
+            else if (!strcmp(errors, "ignore"))
+                known_errorHandler = 3;
+            else if (!strcmp(errors, "xmlcharrefreplace"))
+                known_errorHandler = 4;
+            else
+                known_errorHandler = 0;
+        }
+        switch (known_errorHandler) {
+        case 1: /* strict */
+            raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason);
+            goto onError;
+        case 2: /* replace */
+            for (p = collstart; p < collend; ++p)
+                *output++ = '?';
+            /* fall through */
+        case 3: /* ignore */
+            p = collend;
+            break;
+        case 4: /* xmlcharrefreplace */
+            /* generate replacement (temporarily (mis)uses p) */
+            for (p = collstart; p < collend; ++p)
+                output += sprintf(output, "&#%d;", (int)*p);
+            p = collend;
+            break;
+        default:
+            repunicode = unicode_encode_call_errorhandler(errors, &errorHandler,
+                                                          encoding, reason, s, length, &exc,
+                                                          collstart-s, collend-s, &newpos);
+            if (repunicode == NULL)
+                goto onError;
+            /* generate replacement  */
+            repsize = PyUnicode_GET_SIZE(repunicode);
+            for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) {
+                Py_UNICODE ch = *uni2;
+                if (Py_UNICODE_ISSPACE(ch))
+                    *output++ = ' ';
+                else {
+                    decimal = Py_UNICODE_TODECIMAL(ch);
+                    if (decimal >= 0)
+                        *output++ = '0' + decimal;
+                    else if (0 < ch && ch < 256)
+                        *output++ = (char)ch;
+                    else {
+                        Py_DECREF(repunicode);
+                        raise_encode_exception(&exc, encoding,
+                                               s, length, collstart-s, collend-s, reason);
+                        goto onError;
+                    }
+                }
+            }
+            p = s + newpos;
+            Py_DECREF(repunicode);
+        }
+    }
+    /* 0-terminate the output string */
+    *output++ = '\0';
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return 0;
+
+  onError:
+    Py_XDECREF(exc);
+    Py_XDECREF(errorHandler);
+    return -1;
+}
+
+/* --- Helpers ------------------------------------------------------------ */
+
+#include "stringlib/unicodedefs.h"
+#include "stringlib/fastsearch.h"
+
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+#include "stringlib/split.h"
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len)         \
+    if (end > len)                              \
+        end = len;                              \
+    else if (end < 0) {                         \
+        end += len;                             \
+        if (end < 0)                            \
+            end = 0;                            \
+    }                                           \
+    if (start < 0) {                            \
+        start += len;                           \
+        if (start < 0)                          \
+            start = 0;                          \
+    }
+
+Py_ssize_t PyUnicode_Count(PyObject *str,
+                           PyObject *substr,
+                           Py_ssize_t start,
+                           Py_ssize_t end)
+{
+    Py_ssize_t result;
+    PyUnicodeObject* str_obj;
+    PyUnicodeObject* sub_obj;
+
+    str_obj = (PyUnicodeObject*) PyUnicode_FromObject(str);
+    if (!str_obj)
+        return -1;
+    sub_obj = (PyUnicodeObject*) PyUnicode_FromObject(substr);
+    if (!sub_obj) {
+        Py_DECREF(str_obj);
+        return -1;
+    }
+
+    ADJUST_INDICES(start, end, str_obj->length);
+    result = stringlib_count(
+        str_obj->str + start, end - start, sub_obj->str, sub_obj->length,
+        PY_SSIZE_T_MAX
+        );
+
+    Py_DECREF(sub_obj);
+    Py_DECREF(str_obj);
+
+    return result;
+}
+
+Py_ssize_t PyUnicode_Find(PyObject *str,
+                          PyObject *sub,
+                          Py_ssize_t start,
+                          Py_ssize_t end,
+                          int direction)
+{
+    Py_ssize_t result;
+
+    str = PyUnicode_FromObject(str);
+    if (!str)
+        return -2;
+    sub = PyUnicode_FromObject(sub);
+    if (!sub) {
+        Py_DECREF(str);
+        return -2;
+    }
+
+    if (direction > 0)
+        result = stringlib_find_slice(
+            PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str),
+            PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub),
+            start, end
+            );
+    else
+        result = stringlib_rfind_slice(
+            PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str),
+            PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub),
+            start, end
+            );
+
+    Py_DECREF(str);
+    Py_DECREF(sub);
+
+    return result;
+}
+
+static
+int tailmatch(PyUnicodeObject *self,
+              PyUnicodeObject *substring,
+              Py_ssize_t start,
+              Py_ssize_t end,
+              int direction)
+{
+    if (substring->length == 0)
+        return 1;
+
+    ADJUST_INDICES(start, end, self->length);
+    end -= substring->length;
+    if (end < start)
+        return 0;
+
+    if (direction > 0) {
+        if (Py_UNICODE_MATCH(self, end, substring))
+            return 1;
+    } else {
+        if (Py_UNICODE_MATCH(self, start, substring))
+            return 1;
+    }
+
+    return 0;
+}
+
+Py_ssize_t PyUnicode_Tailmatch(PyObject *str,
+                               PyObject *substr,
+                               Py_ssize_t start,
+                               Py_ssize_t end,
+                               int direction)
+{
+    Py_ssize_t result;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+        return -1;
+    substr = PyUnicode_FromObject(substr);
+    if (substr == NULL) {
+        Py_DECREF(str);
+        return -1;
+    }
+
+    result = tailmatch((PyUnicodeObject *)str,
+                       (PyUnicodeObject *)substr,
+                       start, end, direction);
+    Py_DECREF(str);
+    Py_DECREF(substr);
+    return result;
+}
+
+/* Apply fixfct filter to the Unicode object self and return a
+   reference to the modified object */
+
+static
+PyObject *fixup(PyUnicodeObject *self,
+                int (*fixfct)(PyUnicodeObject *s))
+{
+
+    PyUnicodeObject *u;
+
+    u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+    if (u == NULL)
+        return NULL;
+
+    Py_UNICODE_COPY(u->str, self->str, self->length);
+
+    if (!fixfct(u) && PyUnicode_CheckExact(self)) {
+        /* fixfct should return TRUE if it modified the buffer. If
+           FALSE, return a reference to the original buffer instead
+           (to save space, not time) */
+        Py_INCREF(self);
+        Py_DECREF(u);
+        return (PyObject*) self;
+    }
+    return (PyObject*) u;
+}
+
+static
+int fixupper(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    while (len-- > 0) {
+        register Py_UNICODE ch;
+
+        ch = Py_UNICODE_TOUPPER(*s);
+        if (ch != *s) {
+            status = 1;
+            *s = ch;
+        }
+        s++;
+    }
+
+    return status;
+}
+
+static
+int fixlower(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    while (len-- > 0) {
+        register Py_UNICODE ch;
+
+        ch = Py_UNICODE_TOLOWER(*s);
+        if (ch != *s) {
+            status = 1;
+            *s = ch;
+        }
+        s++;
+    }
+
+    return status;
+}
+
+static
+int fixswapcase(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    while (len-- > 0) {
+        if (Py_UNICODE_ISUPPER(*s)) {
+            *s = Py_UNICODE_TOLOWER(*s);
+            status = 1;
+        } else if (Py_UNICODE_ISLOWER(*s)) {
+            *s = Py_UNICODE_TOUPPER(*s);
+            status = 1;
+        }
+        s++;
+    }
+
+    return status;
+}
+
+static
+int fixcapitalize(PyUnicodeObject *self)
+{
+    Py_ssize_t len = self->length;
+    Py_UNICODE *s = self->str;
+    int status = 0;
+
+    if (len == 0)
+        return 0;
+    if (!Py_UNICODE_ISUPPER(*s)) {
+        *s = Py_UNICODE_TOUPPER(*s);
+        status = 1;
+    }
+    s++;
+    while (--len > 0) {
+        if (!Py_UNICODE_ISLOWER(*s)) {
+            *s = Py_UNICODE_TOLOWER(*s);
+            status = 1;
+        }
+        s++;
+    }
+    return status;
+}
+
+static
+int fixtitle(PyUnicodeObject *self)
+{
+    register Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register Py_UNICODE *e;
+    int previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1) {
+        Py_UNICODE ch = Py_UNICODE_TOTITLE(*p);
+        if (*p != ch) {
+            *p = ch;
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    e = p + PyUnicode_GET_SIZE(self);
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+        register const Py_UNICODE ch = *p;
+
+        if (previous_is_cased)
+            *p = Py_UNICODE_TOLOWER(ch);
+        else
+            *p = Py_UNICODE_TOTITLE(ch);
+
+        if (Py_UNICODE_ISLOWER(ch) ||
+            Py_UNICODE_ISUPPER(ch) ||
+            Py_UNICODE_ISTITLE(ch))
+            previous_is_cased = 1;
+        else
+            previous_is_cased = 0;
+    }
+    return 1;
+}
+
+PyObject *
+PyUnicode_Join(PyObject *separator, PyObject *seq)
+{
+    PyObject *internal_separator = NULL;
+    const Py_UNICODE blank = ' ';
+    const Py_UNICODE *sep = &blank;
+    Py_ssize_t seplen = 1;
+    PyUnicodeObject *res = NULL; /* the result */
+    Py_ssize_t res_alloc = 100;  /* # allocated bytes for string in res */
+    Py_ssize_t res_used;         /* # used bytes */
+    Py_UNICODE *res_p;       /* pointer to free byte in res's string area */
+    PyObject *fseq;          /* PySequence_Fast(seq) */
+    Py_ssize_t seqlen;              /* len(fseq) -- number of items in sequence */
+    PyObject *item;
+    Py_ssize_t i;
+
+    fseq = PySequence_Fast(seq, "");
+    if (fseq == NULL) {
+        return NULL;
+    }
+
+    /* Grrrr.  A codec may be invoked to convert str objects to
+     * Unicode, and so it's possible to call back into Python code
+     * during PyUnicode_FromObject(), and so it's possible for a sick
+     * codec to change the size of fseq (if seq is a list).  Therefore
+     * we have to keep refetching the size -- can't assume seqlen
+     * is invariant.
+     */
+    seqlen = PySequence_Fast_GET_SIZE(fseq);
+    /* If empty sequence, return u"". */
+    if (seqlen == 0) {
+        res = _PyUnicode_New(0);  /* empty sequence; return u"" */
+        goto Done;
+    }
+    /* If singleton sequence with an exact Unicode, return that. */
+    if (seqlen == 1) {
+        item = PySequence_Fast_GET_ITEM(fseq, 0);
+        if (PyUnicode_CheckExact(item)) {
+            Py_INCREF(item);
+            res = (PyUnicodeObject *)item;
+            goto Done;
+        }
+    }
+
+    /* At least two items to join, or one that isn't exact Unicode. */
+    if (seqlen > 1) {
+        /* Set up sep and seplen -- they're needed. */
+        if (separator == NULL) {
+            sep = &blank;
+            seplen = 1;
+        }
+        else {
+            internal_separator = PyUnicode_FromObject(separator);
+            if (internal_separator == NULL)
+                goto onError;
+            sep = PyUnicode_AS_UNICODE(internal_separator);
+            seplen = PyUnicode_GET_SIZE(internal_separator);
+            /* In case PyUnicode_FromObject() mutated seq. */
+            seqlen = PySequence_Fast_GET_SIZE(fseq);
+        }
+    }
+
+    /* Get space. */
+    res = _PyUnicode_New(res_alloc);
+    if (res == NULL)
+        goto onError;
+    res_p = PyUnicode_AS_UNICODE(res);
+    res_used = 0;
+
+    for (i = 0; i < seqlen; ++i) {
+        Py_ssize_t itemlen;
+        Py_ssize_t new_res_used;
+
+        item = PySequence_Fast_GET_ITEM(fseq, i);
+        /* Convert item to Unicode. */
+        if (! PyUnicode_Check(item) && ! PyString_Check(item)) {
+            PyErr_Format(PyExc_TypeError,
+                         "sequence item %zd: expected string or Unicode,"
+                         " %.80s found",
+                         i, Py_TYPE(item)->tp_name);
+            goto onError;
+        }
+        item = PyUnicode_FromObject(item);
+        if (item == NULL)
+            goto onError;
+        /* We own a reference to item from here on. */
+
+        /* In case PyUnicode_FromObject() mutated seq. */
+        seqlen = PySequence_Fast_GET_SIZE(fseq);
+
+        /* Make sure we have enough space for the separator and the item. */
+        itemlen = PyUnicode_GET_SIZE(item);
+        new_res_used = res_used + itemlen;
+        if (new_res_used < 0)
+            goto Overflow;
+        if (i < seqlen - 1) {
+            new_res_used += seplen;
+            if (new_res_used < 0)
+                goto Overflow;
+        }
+        if (new_res_used > res_alloc) {
+            /* double allocated size until it's big enough */
+            do {
+                res_alloc += res_alloc;
+                if (res_alloc <= 0)
+                    goto Overflow;
+            } while (new_res_used > res_alloc);
+            if (_PyUnicode_Resize(&res, res_alloc) < 0) {
+                Py_DECREF(item);
+                goto onError;
+            }
+            res_p = PyUnicode_AS_UNICODE(res) + res_used;
+        }
+
+        /* Copy item, and maybe the separator. */
+        Py_UNICODE_COPY(res_p, PyUnicode_AS_UNICODE(item), itemlen);
+        res_p += itemlen;
+        if (i < seqlen - 1) {
+            Py_UNICODE_COPY(res_p, sep, seplen);
+            res_p += seplen;
+        }
+        Py_DECREF(item);
+        res_used = new_res_used;
+    }
+
+    /* Shrink res to match the used area; this probably can't fail,
+     * but it's cheap to check.
+     */
+    if (_PyUnicode_Resize(&res, res_used) < 0)
+        goto onError;
+
+  Done:
+    Py_XDECREF(internal_separator);
+    Py_DECREF(fseq);
+    return (PyObject *)res;
+
+  Overflow:
+    PyErr_SetString(PyExc_OverflowError,
+                    "join() result is too long for a Python string");
+    Py_DECREF(item);
+    /* fall through */
+
+  onError:
+    Py_XDECREF(internal_separator);
+    Py_DECREF(fseq);
+    Py_XDECREF(res);
+    return NULL;
+}
+
+static
+PyUnicodeObject *pad(PyUnicodeObject *self,
+                     Py_ssize_t left,
+                     Py_ssize_t right,
+                     Py_UNICODE fill)
+{
+    PyUnicodeObject *u;
+
+    if (left < 0)
+        left = 0;
+    if (right < 0)
+        right = 0;
+
+    if (left == 0 && right == 0 && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return self;
+    }
+
+    if (left > PY_SSIZE_T_MAX - self->length ||
+        right > PY_SSIZE_T_MAX - (left + self->length)) {
+        PyErr_SetString(PyExc_OverflowError, "padded string is too long");
+        return NULL;
+    }
+    u = _PyUnicode_New(left + self->length + right);
+    if (u) {
+        if (left)
+            Py_UNICODE_FILL(u->str, fill, left);
+        Py_UNICODE_COPY(u->str + left, self->str, self->length);
+        if (right)
+            Py_UNICODE_FILL(u->str + left + self->length, fill, right);
+    }
+
+    return u;
+}
+
+PyObject *PyUnicode_Splitlines(PyObject *string, int keepends)
+{
+    PyObject *list;
+
+    string = PyUnicode_FromObject(string);
+    if (string == NULL)
+        return NULL;
+
+    list = stringlib_splitlines(
+        (PyObject*) string, PyUnicode_AS_UNICODE(string),
+        PyUnicode_GET_SIZE(string), keepends);
+
+    Py_DECREF(string);
+    return list;
+}
+
+static
+PyObject *split(PyUnicodeObject *self,
+                PyUnicodeObject *substring,
+                Py_ssize_t maxcount)
+{
+    if (maxcount < 0)
+        maxcount = PY_SSIZE_T_MAX;
+
+    if (substring == NULL)
+        return stringlib_split_whitespace(
+            (PyObject*) self,  self->str, self->length, maxcount
+            );
+
+    return stringlib_split(
+        (PyObject*) self,  self->str, self->length,
+        substring->str, substring->length,
+        maxcount
+        );
+}
+
+static
+PyObject *rsplit(PyUnicodeObject *self,
+                 PyUnicodeObject *substring,
+                 Py_ssize_t maxcount)
+{
+    if (maxcount < 0)
+        maxcount = PY_SSIZE_T_MAX;
+
+    if (substring == NULL)
+        return stringlib_rsplit_whitespace(
+            (PyObject*) self,  self->str, self->length, maxcount
+            );
+
+    return stringlib_rsplit(
+        (PyObject*) self,  self->str, self->length,
+        substring->str, substring->length,
+        maxcount
+        );
+}
+
+static
+PyObject *replace(PyUnicodeObject *self,
+                  PyUnicodeObject *str1,
+                  PyUnicodeObject *str2,
+                  Py_ssize_t maxcount)
+{
+    PyUnicodeObject *u;
+
+    if (maxcount < 0)
+        maxcount = PY_SSIZE_T_MAX;
+    else if (maxcount == 0 || self->length == 0)
+        goto nothing;
+
+    if (str1->length == str2->length) {
+        Py_ssize_t i;
+        /* same length */
+        if (str1->length == 0)
+            goto nothing;
+        if (str1->length == 1) {
+            /* replace characters */
+            Py_UNICODE u1, u2;
+            if (!findchar(self->str, self->length, str1->str[0]))
+                goto nothing;
+            u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+            if (!u)
+                return NULL;
+            Py_UNICODE_COPY(u->str, self->str, self->length);
+            u1 = str1->str[0];
+            u2 = str2->str[0];
+            for (i = 0; i < u->length; i++)
+                if (u->str[i] == u1) {
+                    if (--maxcount < 0)
+                        break;
+                    u->str[i] = u2;
+                }
+        } else {
+            i = stringlib_find(
+                self->str, self->length, str1->str, str1->length, 0
+                );
+            if (i < 0)
+                goto nothing;
+            u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+            if (!u)
+                return NULL;
+            Py_UNICODE_COPY(u->str, self->str, self->length);
+
+            /* change everything in-place, starting with this one */
+            Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+            i += str1->length;
+
+            while ( --maxcount > 0) {
+                i = stringlib_find(self->str+i, self->length-i,
+                                   str1->str, str1->length,
+                                   i);
+                if (i == -1)
+                    break;
+                Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+                i += str1->length;
+            }
+        }
+    } else {
+
+        Py_ssize_t n, i, j;
+        Py_ssize_t product, new_size, delta;
+        Py_UNICODE *p;
+
+        /* replace strings */
+        n = stringlib_count(self->str, self->length, str1->str, str1->length,
+                            maxcount);
+        if (n == 0)
+            goto nothing;
+        /* new_size = self->length + n * (str2->length - str1->length)); */
+        delta = (str2->length - str1->length);
+        if (delta == 0) {
+            new_size = self->length;
+        } else {
+            product = n * (str2->length - str1->length);
+            if ((product / (str2->length - str1->length)) != n) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "replace string is too long");
+                return NULL;
+            }
+            new_size = self->length + product;
+            if (new_size < 0) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "replace string is too long");
+                return NULL;
+            }
+        }
+        u = _PyUnicode_New(new_size);
+        if (!u)
+            return NULL;
+        i = 0;
+        p = u->str;
+        if (str1->length > 0) {
+            while (n-- > 0) {
+                /* look for next match */
+                j = stringlib_find(self->str+i, self->length-i,
+                                   str1->str, str1->length,
+                                   i);
+                if (j == -1)
+                    break;
+                else if (j > i) {
+                    /* copy unchanged part [i:j] */
+                    Py_UNICODE_COPY(p, self->str+i, j-i);
+                    p += j - i;
+                }
+                /* copy substitution string */
+                if (str2->length > 0) {
+                    Py_UNICODE_COPY(p, str2->str, str2->length);
+                    p += str2->length;
+                }
+                i = j + str1->length;
+            }
+            if (i < self->length)
+                /* copy tail [i:] */
+                Py_UNICODE_COPY(p, self->str+i, self->length-i);
+        } else {
+            /* interleave */
+            while (n > 0) {
+                Py_UNICODE_COPY(p, str2->str, str2->length);
+                p += str2->length;
+                if (--n <= 0)
+                    break;
+                *p++ = self->str[i++];
+            }
+            Py_UNICODE_COPY(p, self->str+i, self->length-i);
+        }
+    }
+    return (PyObject *) u;
+
+  nothing:
+    /* nothing to replace; return original string (when possible) */
+    if (PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject *) self;
+    }
+    return PyUnicode_FromUnicode(self->str, self->length);
+}
+
+/* --- Unicode Object Methods --------------------------------------------- */
+
+PyDoc_STRVAR(title__doc__,
+             "S.title() -> unicode\n\
+\n\
+Return a titlecased version of S, i.e. words start with title case\n\
+characters, all remaining cased characters have lower case.");
+
+static PyObject*
+unicode_title(PyUnicodeObject *self)
+{
+    return fixup(self, fixtitle);
+}
+
+PyDoc_STRVAR(capitalize__doc__,
+             "S.capitalize() -> unicode\n\
+\n\
+Return a capitalized version of S, i.e. make the first character\n\
+have upper case and the rest lower case.");
+
+static PyObject*
+unicode_capitalize(PyUnicodeObject *self)
+{
+    return fixup(self, fixcapitalize);
+}
+
+#if 0
+PyDoc_STRVAR(capwords__doc__,
+             "S.capwords() -> unicode\n\
+\n\
+Apply .capitalize() to all words in S and return the result with\n\
+normalized whitespace (all whitespace strings are replaced by ' ').");
+
+static PyObject*
+unicode_capwords(PyUnicodeObject *self)
+{
+    PyObject *list;
+    PyObject *item;
+    Py_ssize_t i;
+
+    /* Split into words */
+    list = split(self, NULL, -1);
+    if (!list)
+        return NULL;
+
+    /* Capitalize each word */
+    for (i = 0; i < PyList_GET_SIZE(list); i++) {
+        item = fixup((PyUnicodeObject *)PyList_GET_ITEM(list, i),
+                     fixcapitalize);
+        if (item == NULL)
+            goto onError;
+        Py_DECREF(PyList_GET_ITEM(list, i));
+        PyList_SET_ITEM(list, i, item);
+    }
+
+    /* Join the words to form a new string */
+    item = PyUnicode_Join(NULL, list);
+
+  onError:
+    Py_DECREF(list);
+    return (PyObject *)item;
+}
+#endif
+
+/* Argument converter.  Coerces to a single unicode character */
+
+static int
+convert_uc(PyObject *obj, void *addr)
+{
+    Py_UNICODE *fillcharloc = (Py_UNICODE *)addr;
+    PyObject *uniobj;
+    Py_UNICODE *unistr;
+
+    uniobj = PyUnicode_FromObject(obj);
+    if (uniobj == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "The fill character cannot be converted to Unicode");
+        return 0;
+    }
+    if (PyUnicode_GET_SIZE(uniobj) != 1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "The fill character must be exactly one character long");
+        Py_DECREF(uniobj);
+        return 0;
+    }
+    unistr = PyUnicode_AS_UNICODE(uniobj);
+    *fillcharloc = unistr[0];
+    Py_DECREF(uniobj);
+    return 1;
+}
+
+PyDoc_STRVAR(center__doc__,
+             "S.center(width[, fillchar]) -> unicode\n\
+\n\
+Return S centered in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space)");
+
+static PyObject *
+unicode_center(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t marg, left;
+    Py_ssize_t width;
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|O&:center", &width, convert_uc, &fillchar))
+        return NULL;
+
+    if (self->length >= width && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    marg = width - self->length;
+    left = marg / 2 + (marg & width & 1);
+
+    return (PyObject*) pad(self, left, marg - left, fillchar);
+}
+
+#if 0
+
+/* This code should go into some future Unicode collation support
+   module. The basic comparison should compare ordinals on a naive
+   basis (this is what Java does and thus Jython too). */
+
+/* speedy UTF-16 code point order comparison */
+/* gleaned from: */
+/* http://www-4.ibm.com/software/developer/library/utf16.html?dwzone=unicode */
+
+static short utf16Fixup[32] =
+{
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0x2000, -0x800, -0x800, -0x800, -0x800
+};
+
+static int
+unicode_compare(PyUnicodeObject *str1, PyUnicodeObject *str2)
+{
+    Py_ssize_t len1, len2;
+
+    Py_UNICODE *s1 = str1->str;
+    Py_UNICODE *s2 = str2->str;
+
+    len1 = str1->length;
+    len2 = str2->length;
+
+    while (len1 > 0 && len2 > 0) {
+        Py_UNICODE c1, c2;
+
+        c1 = *s1++;
+        c2 = *s2++;
+
+        if (c1 > (1<<11) * 26)
+            c1 += utf16Fixup[c1>>11];
+        if (c2 > (1<<11) * 26)
+            c2 += utf16Fixup[c2>>11];
+        /* now c1 and c2 are in UTF-32-compatible order */
+
+        if (c1 != c2)
+            return (c1 < c2) ? -1 : 1;
+
+        len1--; len2--;
+    }
+
+    return (len1 < len2) ? -1 : (len1 != len2);
+}
+
+#else
+
+static int
+unicode_compare(PyUnicodeObject *str1, PyUnicodeObject *str2)
+{
+    register Py_ssize_t len1, len2;
+
+    Py_UNICODE *s1 = str1->str;
+    Py_UNICODE *s2 = str2->str;
+
+    len1 = str1->length;
+    len2 = str2->length;
+
+    while (len1 > 0 && len2 > 0) {
+        Py_UNICODE c1, c2;
+
+        c1 = *s1++;
+        c2 = *s2++;
+
+        if (c1 != c2)
+            return (c1 < c2) ? -1 : 1;
+
+        len1--; len2--;
+    }
+
+    return (len1 < len2) ? -1 : (len1 != len2);
+}
+
+#endif
+
+int PyUnicode_Compare(PyObject *left,
+                      PyObject *right)
+{
+    PyUnicodeObject *u = NULL, *v = NULL;
+    int result;
+
+    /* Coerce the two arguments */
+    u = (PyUnicodeObject *)PyUnicode_FromObject(left);
+    if (u == NULL)
+        goto onError;
+    v = (PyUnicodeObject *)PyUnicode_FromObject(right);
+    if (v == NULL)
+        goto onError;
+
+    /* Shortcut for empty or interned objects */
+    if (v == u) {
+        Py_DECREF(u);
+        Py_DECREF(v);
+        return 0;
+    }
+
+    result = unicode_compare(u, v);
+
+    Py_DECREF(u);
+    Py_DECREF(v);
+    return result;
+
+  onError:
+    Py_XDECREF(u);
+    Py_XDECREF(v);
+    return -1;
+}
+
+PyObject *PyUnicode_RichCompare(PyObject *left,
+                                PyObject *right,
+                                int op)
+{
+    int result;
+
+    result = PyUnicode_Compare(left, right);
+    if (result == -1 && PyErr_Occurred())
+        goto onError;
+
+    /* Convert the return value to a Boolean */
+    switch (op) {
+    case Py_EQ:
+        result = (result == 0);
+        break;
+    case Py_NE:
+        result = (result != 0);
+        break;
+    case Py_LE:
+        result = (result <= 0);
+        break;
+    case Py_GE:
+        result = (result >= 0);
+        break;
+    case Py_LT:
+        result = (result == -1);
+        break;
+    case Py_GT:
+        result = (result == 1);
+        break;
+    }
+    return PyBool_FromLong(result);
+
+  onError:
+
+    /* Standard case
+
+       Type errors mean that PyUnicode_FromObject() could not convert
+       one of the arguments (usually the right hand side) to Unicode,
+       ie. we can't handle the comparison request. However, it is
+       possible that the other object knows a comparison method, which
+       is why we return Py_NotImplemented to give the other object a
+       chance.
+
+    */
+    if (PyErr_ExceptionMatches(PyExc_TypeError)) {
+        PyErr_Clear();
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    if (op != Py_EQ && op != Py_NE)
+        return NULL;
+
+    /* Equality comparison.
+
+       This is a special case: we silence any PyExc_UnicodeDecodeError
+       and instead turn it into a PyErr_UnicodeWarning.
+
+    */
+    if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))
+        return NULL;
+    PyErr_Clear();
+    if (PyErr_Warn(PyExc_UnicodeWarning,
+                   (op == Py_EQ) ?
+                   "Unicode equal comparison "
+                   "failed to convert both arguments to Unicode - "
+                   "interpreting them as being unequal" :
+                   "Unicode unequal comparison "
+                   "failed to convert both arguments to Unicode - "
+                   "interpreting them as being unequal"
+            ) < 0)
+        return NULL;
+    result = (op == Py_NE);
+    return PyBool_FromLong(result);
+}
+
+int PyUnicode_Contains(PyObject *container,
+                       PyObject *element)
+{
+    PyObject *str, *sub;
+    int result;
+
+    /* Coerce the two arguments */
+    sub = PyUnicode_FromObject(element);
+    if (!sub) {
+        return -1;
+    }
+
+    str = PyUnicode_FromObject(container);
+    if (!str) {
+        Py_DECREF(sub);
+        return -1;
+    }
+
+    result = stringlib_contains_obj(str, sub);
+
+    Py_DECREF(str);
+    Py_DECREF(sub);
+
+    return result;
+}
+
+/* Concat to string or Unicode object giving a new Unicode object. */
+
+PyObject *PyUnicode_Concat(PyObject *left,
+                           PyObject *right)
+{
+    PyUnicodeObject *u = NULL, *v = NULL, *w;
+
+    /* Coerce the two arguments */
+    u = (PyUnicodeObject *)PyUnicode_FromObject(left);
+    if (u == NULL)
+        goto onError;
+    v = (PyUnicodeObject *)PyUnicode_FromObject(right);
+    if (v == NULL)
+        goto onError;
+
+    /* Shortcuts */
+    if (v == unicode_empty) {
+        Py_DECREF(v);
+        return (PyObject *)u;
+    }
+    if (u == unicode_empty) {
+        Py_DECREF(u);
+        return (PyObject *)v;
+    }
+
+    /* Concat the two Unicode strings */
+    w = _PyUnicode_New(u->length + v->length);
+    if (w == NULL)
+        goto onError;
+    Py_UNICODE_COPY(w->str, u->str, u->length);
+    Py_UNICODE_COPY(w->str + u->length, v->str, v->length);
+
+    Py_DECREF(u);
+    Py_DECREF(v);
+    return (PyObject *)w;
+
+  onError:
+    Py_XDECREF(u);
+    Py_XDECREF(v);
+    return NULL;
+}
+
+PyDoc_STRVAR(count__doc__,
+             "S.count(sub[, start[, end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of substring sub in\n\
+Unicode string S[start:end].  Optional arguments start and end are\n\
+interpreted as in slice notation.");
+
+static PyObject *
+unicode_count(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    PyObject *result;
+
+    if (!stringlib_parse_args_finds_unicode("count", args, &substring,
+                                            &start, &end))
+        return NULL;
+
+    ADJUST_INDICES(start, end, self->length);
+    result = PyInt_FromSsize_t(
+        stringlib_count(self->str + start, end - start,
+                        substring->str, substring->length,
+                        PY_SSIZE_T_MAX)
+        );
+
+    Py_DECREF(substring);
+
+    return result;
+}
+
+PyDoc_STRVAR(encode__doc__,
+             "S.encode([encoding[,errors]]) -> string or unicode\n\
+\n\
+Encodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that can handle UnicodeEncodeErrors.");
+
+static PyObject *
+unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = {"encoding", "errors", 0};
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode",
+                                     kwlist, &encoding, &errors))
+        return NULL;
+    v = PyUnicode_AsEncodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+  onError:
+    return NULL;
+}
+
+PyDoc_STRVAR(decode__doc__,
+             "S.decode([encoding[,errors]]) -> string or unicode\n\
+\n\
+Decodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registered with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+unicode_decode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = {"encoding", "errors", 0};
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode",
+                                     kwlist, &encoding, &errors))
+        return NULL;
+    v = PyUnicode_AsDecodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a string/unicode object "
+                     "(type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        return NULL;
+    }
+    return v;
+
+  onError:
+    return NULL;
+}
+
+PyDoc_STRVAR(expandtabs__doc__,
+             "S.expandtabs([tabsize]) -> unicode\n\
+\n\
+Return a copy of S where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+unicode_expandtabs(PyUnicodeObject *self, PyObject *args)
+{
+    Py_UNICODE *e;
+    Py_UNICODE *p;
+    Py_UNICODE *q;
+    Py_UNICODE *qe;
+    Py_ssize_t i, j, incr;
+    PyUnicodeObject *u;
+    int tabsize = 8;
+
+    if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+        return NULL;
+
+    /* First pass: determine size of output string */
+    i = 0; /* chars up to and including most recent \n or \r */
+    j = 0; /* chars since most recent \n or \r (use in tab calculations) */
+    e = self->str + self->length; /* end of input */
+    for (p = self->str; p < e; p++)
+        if (*p == '\t') {
+            if (tabsize > 0) {
+                incr = tabsize - (j % tabsize); /* cannot overflow */
+                if (j > PY_SSIZE_T_MAX - incr)
+                    goto overflow1;
+                j += incr;
+            }
+        }
+        else {
+            if (j > PY_SSIZE_T_MAX - 1)
+                goto overflow1;
+            j++;
+            if (*p == '\n' || *p == '\r') {
+                if (i > PY_SSIZE_T_MAX - j)
+                    goto overflow1;
+                i += j;
+                j = 0;
+            }
+        }
+
+    if (i > PY_SSIZE_T_MAX - j)
+        goto overflow1;
+
+    /* Second pass: create output string and fill it */
+    u = _PyUnicode_New(i + j);
+    if (!u)
+        return NULL;
+
+    j = 0; /* same as in first pass */
+    q = u->str; /* next output char */
+    qe = u->str + u->length; /* end of output */
+
+    for (p = self->str; p < e; p++)
+        if (*p == '\t') {
+            if (tabsize > 0) {
+                i = tabsize - (j % tabsize);
+                j += i;
+                while (i--) {
+                    if (q >= qe)
+                        goto overflow2;
+                    *q++ = ' ';
+                }
+            }
+        }
+        else {
+            if (q >= qe)
+                goto overflow2;
+            *q++ = *p;
+            j++;
+            if (*p == '\n' || *p == '\r')
+                j = 0;
+        }
+
+    return (PyObject*) u;
+
+  overflow2:
+    Py_DECREF(u);
+  overflow1:
+    PyErr_SetString(PyExc_OverflowError, "new string is too long");
+    return NULL;
+}
+
+PyDoc_STRVAR(find__doc__,
+             "S.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+unicode_find(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *substring;
+    Py_ssize_t start;
+    Py_ssize_t end;
+    Py_ssize_t result;
+
+    if (!stringlib_parse_args_finds_unicode("find", args, &substring,
+                                            &start, &end))
+        return NULL;
+
+    result = stringlib_find_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    return PyInt_FromSsize_t(result);
+}
+
+static PyObject *
+unicode_getitem(PyUnicodeObject *self, Py_ssize_t index)
+{
+    if (index < 0 || index >= self->length) {
+        PyErr_SetString(PyExc_IndexError, "string index out of range");
+        return NULL;
+    }
+
+    return (PyObject*) PyUnicode_FromUnicode(&self->str[index], 1);
+}
+
+static long
+unicode_hash(PyUnicodeObject *self)
+{
+    /* Since Unicode objects compare equal to their ASCII string
+       counterparts, they should use the individual character values
+       as basis for their hash value.  This is needed to assure that
+       strings and Unicode objects behave in the same way as
+       dictionary keys. */
+
+    register Py_ssize_t len;
+    register Py_UNICODE *p;
+    register long x;
+
+#ifdef Py_DEBUG
+    assert(_Py_HashSecret_Initialized);
+#endif
+    if (self->hash != -1)
+        return self->hash;
+    len = PyUnicode_GET_SIZE(self);
+    /*
+      We make the hash of the empty string be 0, rather than using
+      (prefix ^ suffix), since this slightly obfuscates the hash secret
+    */
+    if (len == 0) {
+        self->hash = 0;
+        return 0;
+    }
+    p = PyUnicode_AS_UNICODE(self);
+    x = _Py_HashSecret.prefix;
+    x ^= *p << 7;
+    while (--len >= 0)
+        x = (1000003*x) ^ *p++;
+    x ^= PyUnicode_GET_SIZE(self);
+    x ^= _Py_HashSecret.suffix;
+    if (x == -1)
+        x = -2;
+    self->hash = x;
+    return x;
+}
+
+PyDoc_STRVAR(index__doc__,
+             "S.index(sub [,start [,end]]) -> int\n\
+\n\
+Like S.find() but raise ValueError when the substring is not found.");
+
+static PyObject *
+unicode_index(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t result;
+    PyUnicodeObject *substring;
+    Py_ssize_t start;
+    Py_ssize_t end;
+
+    if (!stringlib_parse_args_finds_unicode("index", args, &substring,
+                                            &start, &end))
+        return NULL;
+
+    result = stringlib_find_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    if (result < 0) {
+        PyErr_SetString(PyExc_ValueError, "substring not found");
+        return NULL;
+    }
+
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(islower__doc__,
+             "S.islower() -> bool\n\
+\n\
+Return True if all cased characters in S are lowercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+unicode_islower(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1)
+        return PyBool_FromLong(Py_UNICODE_ISLOWER(*p));
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+        register const Py_UNICODE ch = *p;
+
+        if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch))
+            return PyBool_FromLong(0);
+        else if (!cased && Py_UNICODE_ISLOWER(ch))
+            cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(isupper__doc__,
+             "S.isupper() -> bool\n\
+\n\
+Return True if all cased characters in S are uppercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+unicode_isupper(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1)
+        return PyBool_FromLong(Py_UNICODE_ISUPPER(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    cased = 0;
+    for (; p < e; p++) {
+        register const Py_UNICODE ch = *p;
+
+        if (Py_UNICODE_ISLOWER(ch) || Py_UNICODE_ISTITLE(ch))
+            return PyBool_FromLong(0);
+        else if (!cased && Py_UNICODE_ISUPPER(ch))
+            cased = 1;
+    }
+    return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(istitle__doc__,
+             "S.istitle() -> bool\n\
+\n\
+Return True if S is a titlecased string and there is at least one\n\
+character in S, i.e. upper- and titlecase characters may only\n\
+follow uncased characters and lowercase characters only cased ones.\n\
+Return False otherwise.");
+
+static PyObject*
+unicode_istitle(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+    int cased, previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1)
+        return PyBool_FromLong((Py_UNICODE_ISTITLE(*p) != 0) ||
+                               (Py_UNICODE_ISUPPER(*p) != 0));
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    cased = 0;
+    previous_is_cased = 0;
+    for (; p < e; p++) {
+        register const Py_UNICODE ch = *p;
+
+        if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) {
+            if (previous_is_cased)
+                return PyBool_FromLong(0);
+            previous_is_cased = 1;
+            cased = 1;
+        }
+        else if (Py_UNICODE_ISLOWER(ch)) {
+            if (!previous_is_cased)
+                return PyBool_FromLong(0);
+            previous_is_cased = 1;
+            cased = 1;
+        }
+        else
+            previous_is_cased = 0;
+    }
+    return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(isspace__doc__,
+             "S.isspace() -> bool\n\
+\n\
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isspace(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+        Py_UNICODE_ISSPACE(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISSPACE(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isalpha__doc__,
+             "S.isalpha() -> bool\n\
+\n\
+Return True if all characters in S are alphabetic\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isalpha(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+        Py_UNICODE_ISALPHA(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISALPHA(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isalnum__doc__,
+             "S.isalnum() -> bool\n\
+\n\
+Return True if all characters in S are alphanumeric\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isalnum(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+        Py_UNICODE_ISALNUM(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISALNUM(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isdecimal__doc__,
+             "S.isdecimal() -> bool\n\
+\n\
+Return True if there are only decimal characters in S,\n\
+False otherwise.");
+
+static PyObject*
+unicode_isdecimal(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+        Py_UNICODE_ISDECIMAL(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISDECIMAL(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isdigit__doc__,
+             "S.isdigit() -> bool\n\
+\n\
+Return True if all characters in S are digits\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isdigit(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+        Py_UNICODE_ISDIGIT(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISDIGIT(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isnumeric__doc__,
+             "S.isnumeric() -> bool\n\
+\n\
+Return True if there are only numeric characters in S,\n\
+False otherwise.");
+
+static PyObject*
+unicode_isnumeric(PyUnicodeObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+        Py_UNICODE_ISNUMERIC(*p))
+        return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+        return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISNUMERIC(*p))
+            return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(join__doc__,
+             "S.join(iterable) -> unicode\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+iterable.  The separator between elements is S.");
+
+static PyObject*
+unicode_join(PyObject *self, PyObject *data)
+{
+    return PyUnicode_Join(self, data);
+}
+
+static Py_ssize_t
+unicode_length(PyUnicodeObject *self)
+{
+    return self->length;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+             "S.ljust(width[, fillchar]) -> int\n\
+\n\
+Return S left-justified in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space).");
+
+static PyObject *
+unicode_ljust(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|O&:ljust", &width, convert_uc, &fillchar))
+        return NULL;
+
+    if (self->length >= width && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return (PyObject*) pad(self, 0, width - self->length, fillchar);
+}
+
+PyDoc_STRVAR(lower__doc__,
+             "S.lower() -> unicode\n\
+\n\
+Return a copy of the string S converted to lowercase.");
+
+static PyObject*
+unicode_lower(PyUnicodeObject *self)
+{
+    return fixup(self, fixlower);
+}
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+/* Arrays indexed by above */
+static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+
+#define STRIPNAME(i) (stripformat[i]+3)
+
+/* externally visible for str.strip(unicode) */
+PyObject *
+_PyUnicode_XStrip(PyUnicodeObject *self, int striptype, PyObject *sepobj)
+{
+    Py_UNICODE *s = PyUnicode_AS_UNICODE(self);
+    Py_ssize_t len = PyUnicode_GET_SIZE(self);
+    Py_UNICODE *sep = PyUnicode_AS_UNICODE(sepobj);
+    Py_ssize_t seplen = PyUnicode_GET_SIZE(sepobj);
+    Py_ssize_t i, j;
+
+    BLOOM_MASK sepmask = make_bloom_mask(sep, seplen);
+
+    i = 0;
+    if (striptype != RIGHTSTRIP) {
+        while (i < len && BLOOM_MEMBER(sepmask, s[i], sep, seplen)) {
+            i++;
+        }
+    }
+
+    j = len;
+    if (striptype != LEFTSTRIP) {
+        do {
+            j--;
+        } while (j >= i && BLOOM_MEMBER(sepmask, s[j], sep, seplen));
+        j++;
+    }
+
+    if (i == 0 && j == len && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*)self;
+    }
+    else
+        return PyUnicode_FromUnicode(s+i, j-i);
+}
+
+
+static PyObject *
+do_strip(PyUnicodeObject *self, int striptype)
+{
+    Py_UNICODE *s = PyUnicode_AS_UNICODE(self);
+    Py_ssize_t len = PyUnicode_GET_SIZE(self), i, j;
+
+    i = 0;
+    if (striptype != RIGHTSTRIP) {
+        while (i < len && Py_UNICODE_ISSPACE(s[i])) {
+            i++;
+        }
+    }
+
+    j = len;
+    if (striptype != LEFTSTRIP) {
+        do {
+            j--;
+        } while (j >= i && Py_UNICODE_ISSPACE(s[j]));
+        j++;
+    }
+
+    if (i == 0 && j == len && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*)self;
+    }
+    else
+        return PyUnicode_FromUnicode(s+i, j-i);
+}
+
+
+static PyObject *
+do_argstrip(PyUnicodeObject *self, int striptype, PyObject *args)
+{
+    PyObject *sep = NULL;
+
+    if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+        return NULL;
+
+    if (sep != NULL && sep != Py_None) {
+        if (PyUnicode_Check(sep))
+            return _PyUnicode_XStrip(self, striptype, sep);
+        else if (PyString_Check(sep)) {
+            PyObject *res;
+            sep = PyUnicode_FromObject(sep);
+            if (sep==NULL)
+                return NULL;
+            res = _PyUnicode_XStrip(self, striptype, sep);
+            Py_DECREF(sep);
+            return res;
+        }
+        else {
+            PyErr_Format(PyExc_TypeError,
+                         "%s arg must be None, unicode or str",
+                         STRIPNAME(striptype));
+            return NULL;
+        }
+    }
+
+    return do_strip(self, striptype);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+             "S.strip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with leading and trailing\n\
+whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_strip(PyUnicodeObject *self, PyObject *args)
+{
+    if (PyTuple_GET_SIZE(args) == 0)
+        return do_strip(self, BOTHSTRIP); /* Common case */
+    else
+        return do_argstrip(self, BOTHSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+             "S.lstrip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with leading whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_lstrip(PyUnicodeObject *self, PyObject *args)
+{
+    if (PyTuple_GET_SIZE(args) == 0)
+        return do_strip(self, LEFTSTRIP); /* Common case */
+    else
+        return do_argstrip(self, LEFTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+             "S.rstrip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with trailing whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_rstrip(PyUnicodeObject *self, PyObject *args)
+{
+    if (PyTuple_GET_SIZE(args) == 0)
+        return do_strip(self, RIGHTSTRIP); /* Common case */
+    else
+        return do_argstrip(self, RIGHTSTRIP, args);
+}
+
+
+static PyObject*
+unicode_repeat(PyUnicodeObject *str, Py_ssize_t len)
+{
+    PyUnicodeObject *u;
+    Py_UNICODE *p;
+    Py_ssize_t nchars;
+    size_t nbytes;
+
+    if (len < 0)
+        len = 0;
+
+    if (len == 1 && PyUnicode_CheckExact(str)) {
+        /* no repeat, return original string */
+        Py_INCREF(str);
+        return (PyObject*) str;
+    }
+
+    /* ensure # of chars needed doesn't overflow int and # of bytes
+     * needed doesn't overflow size_t
+     */
+    nchars = len * str->length;
+    if (len && nchars / len != str->length) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "repeated string is too long");
+        return NULL;
+    }
+    nbytes = (nchars + 1) * sizeof(Py_UNICODE);
+    if (nbytes / sizeof(Py_UNICODE) != (size_t)(nchars + 1)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "repeated string is too long");
+        return NULL;
+    }
+    u = _PyUnicode_New(nchars);
+    if (!u)
+        return NULL;
+
+    p = u->str;
+
+    if (str->length == 1 && len > 0) {
+        Py_UNICODE_FILL(p, str->str[0], len);
+    } else {
+        Py_ssize_t done = 0; /* number of characters copied this far */
+        if (done < nchars) {
+            Py_UNICODE_COPY(p, str->str, str->length);
+            done = str->length;
+        }
+        while (done < nchars) {
+            Py_ssize_t n = (done <= nchars-done) ? done : nchars-done;
+            Py_UNICODE_COPY(p+done, p, n);
+            done += n;
+        }
+    }
+
+    return (PyObject*) u;
+}
+
+PyObject *PyUnicode_Replace(PyObject *obj,
+                            PyObject *subobj,
+                            PyObject *replobj,
+                            Py_ssize_t maxcount)
+{
+    PyObject *self;
+    PyObject *str1;
+    PyObject *str2;
+    PyObject *result;
+
+    self = PyUnicode_FromObject(obj);
+    if (self == NULL)
+        return NULL;
+    str1 = PyUnicode_FromObject(subobj);
+    if (str1 == NULL) {
+        Py_DECREF(self);
+        return NULL;
+    }
+    str2 = PyUnicode_FromObject(replobj);
+    if (str2 == NULL) {
+        Py_DECREF(self);
+        Py_DECREF(str1);
+        return NULL;
+    }
+    result = replace((PyUnicodeObject *)self,
+                     (PyUnicodeObject *)str1,
+                     (PyUnicodeObject *)str2,
+                     maxcount);
+    Py_DECREF(self);
+    Py_DECREF(str1);
+    Py_DECREF(str2);
+    return result;
+}
+
+PyDoc_STRVAR(replace__doc__,
+             "S.replace(old, new[, count]) -> unicode\n\
+\n\
+Return a copy of S with all occurrences of substring\n\
+old replaced by new.  If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject*
+unicode_replace(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *str1;
+    PyUnicodeObject *str2;
+    Py_ssize_t maxcount = -1;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "OO|n:replace", &str1, &str2, &maxcount))
+        return NULL;
+    str1 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str1);
+    if (str1 == NULL)
+        return NULL;
+    str2 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str2);
+    if (str2 == NULL) {
+        Py_DECREF(str1);
+        return NULL;
+    }
+
+    result = replace(self, str1, str2, maxcount);
+
+    Py_DECREF(str1);
+    Py_DECREF(str2);
+    return result;
+}
+
+static
+PyObject *unicode_repr(PyObject *unicode)
+{
+    return unicodeescape_string(PyUnicode_AS_UNICODE(unicode),
+                                PyUnicode_GET_SIZE(unicode),
+                                1);
+}
+
+PyDoc_STRVAR(rfind__doc__,
+             "S.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end].  Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+unicode_rfind(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *substring;
+    Py_ssize_t start;
+    Py_ssize_t end;
+    Py_ssize_t result;
+
+    if (!stringlib_parse_args_finds_unicode("rfind", args, &substring,
+                                            &start, &end))
+        return NULL;
+
+    result = stringlib_rfind_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(rindex__doc__,
+             "S.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like S.rfind() but raise ValueError when the substring is not found.");
+
+static PyObject *
+unicode_rindex(PyUnicodeObject *self, PyObject *args)
+{
+    PyUnicodeObject *substring;
+    Py_ssize_t start;
+    Py_ssize_t end;
+    Py_ssize_t result;
+
+    if (!stringlib_parse_args_finds_unicode("rindex", args, &substring,
+                                            &start, &end))
+        return NULL;
+
+    result = stringlib_rfind_slice(
+        PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+        PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+        start, end
+        );
+
+    Py_DECREF(substring);
+
+    if (result < 0) {
+        PyErr_SetString(PyExc_ValueError, "substring not found");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(rjust__doc__,
+             "S.rjust(width[, fillchar]) -> unicode\n\
+\n\
+Return S right-justified in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space).");
+
+static PyObject *
+unicode_rjust(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|O&:rjust", &width, convert_uc, &fillchar))
+        return NULL;
+
+    if (self->length >= width && PyUnicode_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return (PyObject*) pad(self, width - self->length, 0, fillchar);
+}
+
+static PyObject*
+unicode_slice(PyUnicodeObject *self, Py_ssize_t start, Py_ssize_t end)
+{
+    /* standard clamping */
+    if (start < 0)
+        start = 0;
+    if (end < 0)
+        end = 0;
+    if (end > self->length)
+        end = self->length;
+    if (start == 0 && end == self->length && PyUnicode_CheckExact(self)) {
+        /* full slice, return original string */
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+    if (start > end)
+        start = end;
+    /* copy slice */
+    return (PyObject*) PyUnicode_FromUnicode(self->str + start,
+                                             end - start);
+}
+
+PyObject *PyUnicode_Split(PyObject *s,
+                          PyObject *sep,
+                          Py_ssize_t maxsplit)
+{
+    PyObject *result;
+
+    s = PyUnicode_FromObject(s);
+    if (s == NULL)
+        return NULL;
+    if (sep != NULL) {
+        sep = PyUnicode_FromObject(sep);
+        if (sep == NULL) {
+            Py_DECREF(s);
+            return NULL;
+        }
+    }
+
+    result = split((PyUnicodeObject *)s, (PyUnicodeObject *)sep, maxsplit);
+
+    Py_DECREF(s);
+    Py_XDECREF(sep);
+    return result;
+}
+
+PyDoc_STRVAR(split__doc__,
+             "S.split([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in S, using sep as the\n\
+delimiter string.  If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified or is None, any\n\
+whitespace string is a separator and empty strings are\n\
+removed from the result.");
+
+static PyObject*
+unicode_split(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring = Py_None;
+    Py_ssize_t maxcount = -1;
+
+    if (!PyArg_ParseTuple(args, "|On:split", &substring, &maxcount))
+        return NULL;
+
+    if (substring == Py_None)
+        return split(self, NULL, maxcount);
+    else if (PyUnicode_Check(substring))
+        return split(self, (PyUnicodeObject *)substring, maxcount);
+    else
+        return PyUnicode_Split((PyObject *)self, substring, maxcount);
+}
+
+PyObject *
+PyUnicode_Partition(PyObject *str_in, PyObject *sep_in)
+{
+    PyObject* str_obj;
+    PyObject* sep_obj;
+    PyObject* out;
+
+    str_obj = PyUnicode_FromObject(str_in);
+    if (!str_obj)
+        return NULL;
+    sep_obj = PyUnicode_FromObject(sep_in);
+    if (!sep_obj) {
+        Py_DECREF(str_obj);
+        return NULL;
+    }
+
+    out = stringlib_partition(
+        str_obj, PyUnicode_AS_UNICODE(str_obj), PyUnicode_GET_SIZE(str_obj),
+        sep_obj, PyUnicode_AS_UNICODE(sep_obj), PyUnicode_GET_SIZE(sep_obj)
+        );
+
+    Py_DECREF(sep_obj);
+    Py_DECREF(str_obj);
+
+    return out;
+}
+
+
+PyObject *
+PyUnicode_RPartition(PyObject *str_in, PyObject *sep_in)
+{
+    PyObject* str_obj;
+    PyObject* sep_obj;
+    PyObject* out;
+
+    str_obj = PyUnicode_FromObject(str_in);
+    if (!str_obj)
+        return NULL;
+    sep_obj = PyUnicode_FromObject(sep_in);
+    if (!sep_obj) {
+        Py_DECREF(str_obj);
+        return NULL;
+    }
+
+    out = stringlib_rpartition(
+        str_obj, PyUnicode_AS_UNICODE(str_obj), PyUnicode_GET_SIZE(str_obj),
+        sep_obj, PyUnicode_AS_UNICODE(sep_obj), PyUnicode_GET_SIZE(sep_obj)
+        );
+
+    Py_DECREF(sep_obj);
+    Py_DECREF(str_obj);
+
+    return out;
+}
+
+PyDoc_STRVAR(partition__doc__,
+             "S.partition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, and return the part before it,\n\
+the separator itself, and the part after it.  If the separator is not\n\
+found, return S and two empty strings.");
+
+static PyObject*
+unicode_partition(PyUnicodeObject *self, PyObject *separator)
+{
+    return PyUnicode_Partition((PyObject *)self, separator);
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+             "S.rpartition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, starting at the end of S, and return\n\
+the part before it, the separator itself, and the part after it.  If the\n\
+separator is not found, return two empty strings and S.");
+
+static PyObject*
+unicode_rpartition(PyUnicodeObject *self, PyObject *separator)
+{
+    return PyUnicode_RPartition((PyObject *)self, separator);
+}
+
+PyObject *PyUnicode_RSplit(PyObject *s,
+                           PyObject *sep,
+                           Py_ssize_t maxsplit)
+{
+    PyObject *result;
+
+    s = PyUnicode_FromObject(s);
+    if (s == NULL)
+        return NULL;
+    if (sep != NULL) {
+        sep = PyUnicode_FromObject(sep);
+        if (sep == NULL) {
+            Py_DECREF(s);
+            return NULL;
+        }
+    }
+
+    result = rsplit((PyUnicodeObject *)s, (PyUnicodeObject *)sep, maxsplit);
+
+    Py_DECREF(s);
+    Py_XDECREF(sep);
+    return result;
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+             "S.rsplit([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in S, using sep as the\n\
+delimiter string, starting at the end of the string and\n\
+working to the front.  If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified, any whitespace string\n\
+is a separator.");
+
+static PyObject*
+unicode_rsplit(PyUnicodeObject *self, PyObject *args)
+{
+    PyObject *substring = Py_None;
+    Py_ssize_t maxcount = -1;
+
+    if (!PyArg_ParseTuple(args, "|On:rsplit", &substring, &maxcount))
+        return NULL;
+
+    if (substring == Py_None)
+        return rsplit(self, NULL, maxcount);
+    else if (PyUnicode_Check(substring))
+        return rsplit(self, (PyUnicodeObject *)substring, maxcount);
+    else
+        return PyUnicode_RSplit((PyObject *)self, substring, maxcount);
+}
+
+PyDoc_STRVAR(splitlines__doc__,
+             "S.splitlines(keepends=False) -> list of strings\n\
+\n\
+Return a list of the lines in S, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+unicode_splitlines(PyUnicodeObject *self, PyObject *args)
+{
+    int keepends = 0;
+
+    if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+        return NULL;
+
+    return PyUnicode_Splitlines((PyObject *)self, keepends);
+}
+
+static
+PyObject *unicode_str(PyUnicodeObject *self)
+{
+    return PyUnicode_AsEncodedString((PyObject *)self, NULL, NULL);
+}
+
+PyDoc_STRVAR(swapcase__doc__,
+             "S.swapcase() -> unicode\n\
+\n\
+Return a copy of S with uppercase characters converted to lowercase\n\
+and vice versa.");
+
+static PyObject*
+unicode_swapcase(PyUnicodeObject *self)
+{
+    return fixup(self, fixswapcase);
+}
+
+PyDoc_STRVAR(translate__doc__,
+             "S.translate(table) -> unicode\n\
+\n\
+Return a copy of the string S, where all characters have been mapped\n\
+through the given translation table, which must be a mapping of\n\
+Unicode ordinals to Unicode ordinals, Unicode strings or None.\n\
+Unmapped characters are left untouched. Characters mapped to None\n\
+are deleted.");
+
+static PyObject*
+unicode_translate(PyUnicodeObject *self, PyObject *table)
+{
+    return PyUnicode_TranslateCharmap(self->str,
+                                      self->length,
+                                      table,
+                                      "ignore");
+}
+
+PyDoc_STRVAR(upper__doc__,
+             "S.upper() -> unicode\n\
+\n\
+Return a copy of S converted to uppercase.");
+
+static PyObject*
+unicode_upper(PyUnicodeObject *self)
+{
+    return fixup(self, fixupper);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+             "S.zfill(width) -> unicode\n\
+\n\
+Pad a numeric string S with zeros on the left, to fill a field\n\
+of the specified width. The string S is never truncated.");
+
+static PyObject *
+unicode_zfill(PyUnicodeObject *self, PyObject *args)
+{
+    Py_ssize_t fill;
+    PyUnicodeObject *u;
+
+    Py_ssize_t width;
+    if (!PyArg_ParseTuple(args, "n:zfill", &width))
+        return NULL;
+
+    if (self->length >= width) {
+        if (PyUnicode_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject*) self;
+        }
+        else
+            return PyUnicode_FromUnicode(
+                PyUnicode_AS_UNICODE(self),
+                PyUnicode_GET_SIZE(self)
+                );
+    }
+
+    fill = width - self->length;
+
+    u = pad(self, fill, 0, '0');
+
+    if (u == NULL)
+        return NULL;
+
+    if (u->str[fill] == '+' || u->str[fill] == '-') {
+        /* move sign to beginning of string */
+        u->str[0] = u->str[fill];
+        u->str[fill] = '0';
+    }
+
+    return (PyObject*) u;
+}
+
+#if 0
+static PyObject*
+free_listsize(PyUnicodeObject *self)
+{
+    return PyInt_FromLong(numfree);
+}
+#endif
+
+PyDoc_STRVAR(startswith__doc__,
+             "S.startswith(prefix[, start[, end]]) -> bool\n\
+\n\
+Return True if S starts with the specified prefix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+unicode_startswith(PyUnicodeObject *self,
+                   PyObject *args)
+{
+    PyObject *subobj;
+    PyUnicodeObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    int result;
+
+    if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
+        return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            substring = (PyUnicodeObject *)PyUnicode_FromObject(
+                PyTuple_GET_ITEM(subobj, i));
+            if (substring == NULL)
+                return NULL;
+            result = tailmatch(self, substring, start, end, -1);
+            Py_DECREF(substring);
+            if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        /* nothing matched */
+        Py_RETURN_FALSE;
+    }
+    substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
+    if (substring == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_TypeError))
+            PyErr_Format(PyExc_TypeError, "startswith first arg must be str, "
+                         "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+        return NULL;
+    }
+    result = tailmatch(self, substring, start, end, -1);
+    Py_DECREF(substring);
+    return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(endswith__doc__,
+             "S.endswith(suffix[, start[, end]]) -> bool\n\
+\n\
+Return True if S ends with the specified suffix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+unicode_endswith(PyUnicodeObject *self,
+                 PyObject *args)
+{
+    PyObject *subobj;
+    PyUnicodeObject *substring;
+    Py_ssize_t start = 0;
+    Py_ssize_t end = PY_SSIZE_T_MAX;
+    int result;
+
+    if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
+        return NULL;
+    if (PyTuple_Check(subobj)) {
+        Py_ssize_t i;
+        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+            substring = (PyUnicodeObject *)PyUnicode_FromObject(
+                PyTuple_GET_ITEM(subobj, i));
+            if (substring == NULL)
+                return NULL;
+            result = tailmatch(self, substring, start, end, +1);
+            Py_DECREF(substring);
+            if (result) {
+                Py_RETURN_TRUE;
+            }
+        }
+        Py_RETURN_FALSE;
+    }
+    substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
+    if (substring == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_TypeError))
+            PyErr_Format(PyExc_TypeError, "endswith first arg must be str, "
+                         "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+        return NULL;
+    }
+    result = tailmatch(self, substring, start, end, +1);
+    Py_DECREF(substring);
+    return PyBool_FromLong(result);
+}
+
+
+/* Implements do_string_format, which is unicode because of stringlib */
+#include "stringlib/string_format.h"
+
+PyDoc_STRVAR(format__doc__,
+             "S.format(*args, **kwargs) -> unicode\n\
+\n\
+Return a formatted version of S, using substitutions from args and kwargs.\n\
+The substitutions are identified by braces ('{' and '}').");
+
+static PyObject *
+unicode__format__(PyObject *self, PyObject *args)
+{
+    PyObject *format_spec;
+    PyObject *result = NULL;
+    PyObject *tmp = NULL;
+
+    /* If 2.x, convert format_spec to the same type as value */
+    /* This is to allow things like u''.format('') */
+    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+        goto done;
+    if (!(PyBytes_Check(format_spec) || PyUnicode_Check(format_spec))) {
+        PyErr_Format(PyExc_TypeError, "__format__ arg must be str "
+                     "or unicode, not %s", Py_TYPE(format_spec)->tp_name);
+        goto done;
+    }
+    tmp = PyObject_Unicode(format_spec);
+    if (tmp == NULL)
+        goto done;
+    format_spec = tmp;
+
+    result = _PyUnicode_FormatAdvanced(self,
+                                       PyUnicode_AS_UNICODE(format_spec),
+                                       PyUnicode_GET_SIZE(format_spec));
+  done:
+    Py_XDECREF(tmp);
+    return result;
+}
+
+PyDoc_STRVAR(p_format__doc__,
+             "S.__format__(format_spec) -> unicode\n\
+\n\
+Return a formatted version of S as described by format_spec.");
+
+static PyObject *
+unicode__sizeof__(PyUnicodeObject *v)
+{
+    return PyInt_FromSsize_t(sizeof(PyUnicodeObject) +
+                             sizeof(Py_UNICODE) * (v->length + 1));
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+             "S.__sizeof__() -> size of S in memory, in bytes\n\
+\n\
+");
+
+static PyObject *
+unicode_getnewargs(PyUnicodeObject *v)
+{
+    return Py_BuildValue("(u#)", v->str, v->length);
+}
+
+
+static PyMethodDef unicode_methods[] = {
+    {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
+    {"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__},
+    {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__},
+    {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__},
+    {"join", (PyCFunction) unicode_join, METH_O, join__doc__},
+    {"capitalize", (PyCFunction) unicode_capitalize, METH_NOARGS, capitalize__doc__},
+    {"title", (PyCFunction) unicode_title, METH_NOARGS, title__doc__},
+    {"center", (PyCFunction) unicode_center, METH_VARARGS, center__doc__},
+    {"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__},
+    {"expandtabs", (PyCFunction) unicode_expandtabs, METH_VARARGS, expandtabs__doc__},
+    {"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__},
+    {"partition", (PyCFunction) unicode_partition, METH_O, partition__doc__},
+    {"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__},
+    {"ljust", (PyCFunction) unicode_ljust, METH_VARARGS, ljust__doc__},
+    {"lower", (PyCFunction) unicode_lower, METH_NOARGS, lower__doc__},
+    {"lstrip", (PyCFunction) unicode_lstrip, METH_VARARGS, lstrip__doc__},
+    {"decode", (PyCFunction) unicode_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
+/*  {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS, maketrans__doc__}, */
+    {"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__},
+    {"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__},
+    {"rjust", (PyCFunction) unicode_rjust, METH_VARARGS, rjust__doc__},
+    {"rstrip", (PyCFunction) unicode_rstrip, METH_VARARGS, rstrip__doc__},
+    {"rpartition", (PyCFunction) unicode_rpartition, METH_O, rpartition__doc__},
+    {"splitlines", (PyCFunction) unicode_splitlines, METH_VARARGS, splitlines__doc__},
+    {"strip", (PyCFunction) unicode_strip, METH_VARARGS, strip__doc__},
+    {"swapcase", (PyCFunction) unicode_swapcase, METH_NOARGS, swapcase__doc__},
+    {"translate", (PyCFunction) unicode_translate, METH_O, translate__doc__},
+    {"upper", (PyCFunction) unicode_upper, METH_NOARGS, upper__doc__},
+    {"startswith", (PyCFunction) unicode_startswith, METH_VARARGS, startswith__doc__},
+    {"endswith", (PyCFunction) unicode_endswith, METH_VARARGS, endswith__doc__},
+    {"islower", (PyCFunction) unicode_islower, METH_NOARGS, islower__doc__},
+    {"isupper", (PyCFunction) unicode_isupper, METH_NOARGS, isupper__doc__},
+    {"istitle", (PyCFunction) unicode_istitle, METH_NOARGS, istitle__doc__},
+    {"isspace", (PyCFunction) unicode_isspace, METH_NOARGS, isspace__doc__},
+    {"isdecimal", (PyCFunction) unicode_isdecimal, METH_NOARGS, isdecimal__doc__},
+    {"isdigit", (PyCFunction) unicode_isdigit, METH_NOARGS, isdigit__doc__},
+    {"isnumeric", (PyCFunction) unicode_isnumeric, METH_NOARGS, isnumeric__doc__},
+    {"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
+    {"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
+    {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
+    {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
+    {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
+    {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
+    {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
+    {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
+#if 0
+    {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
+#endif
+
+#if 0
+    /* This one is just used for debugging the implementation. */
+    {"freelistsize", (PyCFunction) free_listsize, METH_NOARGS},
+#endif
+
+    {"__getnewargs__",  (PyCFunction)unicode_getnewargs, METH_NOARGS},
+    {NULL, NULL}
+};
+
+static PyObject *
+unicode_mod(PyObject *v, PyObject *w)
+{
+    if (!PyUnicode_Check(v)) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    return PyUnicode_Format(v, w);
+}
+
+static PyNumberMethods unicode_as_number = {
+    0,              /*nb_add*/
+    0,              /*nb_subtract*/
+    0,              /*nb_multiply*/
+    0,              /*nb_divide*/
+    unicode_mod,            /*nb_remainder*/
+};
+
+static PySequenceMethods unicode_as_sequence = {
+    (lenfunc) unicode_length,       /* sq_length */
+    PyUnicode_Concat,           /* sq_concat */
+    (ssizeargfunc) unicode_repeat,  /* sq_repeat */
+    (ssizeargfunc) unicode_getitem,     /* sq_item */
+    (ssizessizeargfunc) unicode_slice,  /* sq_slice */
+    0,                  /* sq_ass_item */
+    0,                  /* sq_ass_slice */
+    PyUnicode_Contains,         /* sq_contains */
+};
+
+static PyObject*
+unicode_subscript(PyUnicodeObject* self, PyObject* item)
+{
+    if (PyIndex_Check(item)) {
+        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += PyUnicode_GET_SIZE(self);
+        return unicode_getitem(self, i);
+    } else if (PySlice_Check(item)) {
+        Py_ssize_t start, stop, step, slicelength, cur, i;
+        Py_UNICODE* source_buf;
+        Py_UNICODE* result_buf;
+        PyObject* result;
+
+        if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self),
+                                 &start, &stop, &step, &slicelength) < 0) {
+            return NULL;
+        }
+
+        if (slicelength <= 0) {
+            return PyUnicode_FromUnicode(NULL, 0);
+        } else if (start == 0 && step == 1 && slicelength == self->length &&
+                   PyUnicode_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject *)self;
+        } else if (step == 1) {
+            return PyUnicode_FromUnicode(self->str + start, slicelength);
+        } else {
+            source_buf = PyUnicode_AS_UNICODE((PyObject*)self);
+            result_buf = (Py_UNICODE *)PyObject_MALLOC(slicelength*
+                                                       sizeof(Py_UNICODE));
+
+            if (result_buf == NULL)
+                return PyErr_NoMemory();
+
+            for (cur = start, i = 0; i < slicelength; cur += step, i++) {
+                result_buf[i] = source_buf[cur];
+            }
+
+            result = PyUnicode_FromUnicode(result_buf, slicelength);
+            PyObject_FREE(result_buf);
+            return result;
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError, "string indices must be integers");
+        return NULL;
+    }
+}
+
+static PyMappingMethods unicode_as_mapping = {
+    (lenfunc)unicode_length,        /* mp_length */
+    (binaryfunc)unicode_subscript,  /* mp_subscript */
+    (objobjargproc)0,           /* mp_ass_subscript */
+};
+
+static Py_ssize_t
+unicode_buffer_getreadbuf(PyUnicodeObject *self,
+                          Py_ssize_t index,
+                          const void **ptr)
+{
+    if (index != 0) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent unicode segment");
+        return -1;
+    }
+    *ptr = (void *) self->str;
+    return PyUnicode_GET_DATA_SIZE(self);
+}
+
+static Py_ssize_t
+unicode_buffer_getwritebuf(PyUnicodeObject *self, Py_ssize_t index,
+                           const void **ptr)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "cannot use unicode as modifiable buffer");
+    return -1;
+}
+
+static int
+unicode_buffer_getsegcount(PyUnicodeObject *self,
+                           Py_ssize_t *lenp)
+{
+    if (lenp)
+        *lenp = PyUnicode_GET_DATA_SIZE(self);
+    return 1;
+}
+
+static Py_ssize_t
+unicode_buffer_getcharbuf(PyUnicodeObject *self,
+                          Py_ssize_t index,
+                          const void **ptr)
+{
+    PyObject *str;
+
+    if (index != 0) {
+        PyErr_SetString(PyExc_SystemError,
+                        "accessing non-existent unicode segment");
+        return -1;
+    }
+    str = _PyUnicode_AsDefaultEncodedString((PyObject *)self, NULL);
+    if (str == NULL)
+        return -1;
+    *ptr = (void *) PyString_AS_STRING(str);
+    return PyString_GET_SIZE(str);
+}
+
+/* Helpers for PyUnicode_Format() */
+
+static PyObject *
+getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
+{
+    Py_ssize_t argidx = *p_argidx;
+    if (argidx < arglen) {
+        (*p_argidx)++;
+        if (arglen < 0)
+            return args;
+        else
+            return PyTuple_GetItem(args, argidx);
+    }
+    PyErr_SetString(PyExc_TypeError,
+                    "not enough arguments for format string");
+    return NULL;
+}
+
+#define F_LJUST (1<<0)
+#define F_SIGN  (1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT   (1<<3)
+#define F_ZERO  (1<<4)
+
+static Py_ssize_t
+strtounicode(Py_UNICODE *buffer, const char *charbuffer)
+{
+    register Py_ssize_t i;
+    Py_ssize_t len = strlen(charbuffer);
+    for (i = len - 1; i >= 0; i--)
+        buffer[i] = (Py_UNICODE) charbuffer[i];
+
+    return len;
+}
+
+static int
+longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
+{
+    Py_ssize_t result;
+
+    PyOS_snprintf((char *)buffer, len, format, x);
+    result = strtounicode(buffer, (char *)buffer);
+    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+/* XXX To save some code duplication, formatfloat/long/int could have been
+   shared with stringobject.c, converting from 8-bit to Unicode after the
+   formatting is done. */
+
+/* Returns a new reference to a PyUnicode object, or NULL on failure. */
+
+static PyObject *
+formatfloat(PyObject *v, int flags, int prec, int type)
+{
+    char *p;
+    PyObject *result;
+    double x;
+
+    x = PyFloat_AsDouble(v);
+    if (x == -1.0 && PyErr_Occurred())
+        return NULL;
+
+    if (prec < 0)
+        prec = 6;
+
+    p = PyOS_double_to_string(x, type, prec,
+                              (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL);
+    if (p == NULL)
+        return NULL;
+    result = PyUnicode_FromStringAndSize(p, strlen(p));
+    PyMem_Free(p);
+    return result;
+}
+
+static PyObject*
+formatlong(PyObject *val, int flags, int prec, int type)
+{
+    char *buf;
+    int i, len;
+    PyObject *str; /* temporary string object. */
+    PyUnicodeObject *result;
+
+    str = _PyString_FormatLong(val, flags, prec, type, &buf, &len);
+    if (!str)
+        return NULL;
+    result = _PyUnicode_New(len);
+    if (!result) {
+        Py_DECREF(str);
+        return NULL;
+    }
+    for (i = 0; i < len; i++)
+        result->str[i] = buf[i];
+    result->str[len] = 0;
+    Py_DECREF(str);
+    return (PyObject*)result;
+}
+
+static int
+formatint(Py_UNICODE *buf,
+          size_t buflen,
+          int flags,
+          int prec,
+          int type,
+          PyObject *v)
+{
+    /* fmt = '%#.' + `prec` + 'l' + `type`
+     * worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+     *                     + 1 + 1
+     *                   = 24
+     */
+    char fmt[64]; /* plenty big enough! */
+    char *sign;
+    long x;
+
+    x = PyInt_AsLong(v);
+    if (x == -1 && PyErr_Occurred())
+        return -1;
+    if (x < 0 && type == 'u') {
+        type = 'd';
+    }
+    if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
+        sign = "-";
+    else
+        sign = "";
+    if (prec < 0)
+        prec = 1;
+
+    /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
+     * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
+     */
+    if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "formatted integer is too long (precision too large?)");
+        return -1;
+    }
+
+    if ((flags & F_ALT) &&
+        (type == 'x' || type == 'X')) {
+        /* When converting under %#x or %#X, there are a number
+         * of issues that cause pain:
+         * - when 0 is being converted, the C standard leaves off
+         *   the '0x' or '0X', which is inconsistent with other
+         *   %#x/%#X conversions and inconsistent with Python's
+         *   hex() function
+         * - there are platforms that violate the standard and
+         *   convert 0 with the '0x' or '0X'
+         *   (Metrowerks, Compaq Tru64)
+         * - there are platforms that give '0x' when converting
+         *   under %#X, but convert 0 in accordance with the
+         *   standard (OS/2 EMX)
+         *
+         * We can achieve the desired consistency by inserting our
+         * own '0x' or '0X' prefix, and substituting %x/%X in place
+         * of %#x/%#X.
+         *
+         * Note that this is the same approach as used in
+         * formatint() in stringobject.c
+         */
+        PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
+                      sign, type, prec, type);
+    }
+    else {
+        PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
+                      sign, (flags&F_ALT) ? "#" : "",
+                      prec, type);
+    }
+    if (sign[0])
+        return longtounicode(buf, buflen, fmt, -x);
+    else
+        return longtounicode(buf, buflen, fmt, x);
+}
+
+static int
+formatchar(Py_UNICODE *buf,
+           size_t buflen,
+           PyObject *v)
+{
+    PyObject *unistr;
+    char *str;
+    /* presume that the buffer is at least 2 characters long */
+    if (PyUnicode_Check(v)) {
+        if (PyUnicode_GET_SIZE(v) != 1)
+            goto onError;
+        buf[0] = PyUnicode_AS_UNICODE(v)[0];
+    }
+
+    else if (PyString_Check(v)) {
+        if (PyString_GET_SIZE(v) != 1)
+            goto onError;
+        /* #7649: "u'%c' % char" should behave like "u'%s' % char" and fail
+           with a UnicodeDecodeError if 'char' is not decodable with the
+           default encoding (usually ASCII, but it might be something else) */
+        str = PyString_AS_STRING(v);
+        if ((unsigned char)str[0] > 0x7F) {
+            /* the char is not ASCII; try to decode the string using the
+               default encoding and return -1 to let the UnicodeDecodeError
+               be raised if the string can't be decoded */
+            unistr = PyUnicode_Decode(str, 1, NULL, "strict");
+            if (unistr == NULL)
+                return -1;
+            buf[0] = PyUnicode_AS_UNICODE(unistr)[0];
+            Py_DECREF(unistr);
+        }
+        else
+            buf[0] = (Py_UNICODE)str[0];
+    }
+
+    else {
+        /* Integer input truncated to a character */
+        long x;
+        x = PyInt_AsLong(v);
+        if (x == -1 && PyErr_Occurred())
+            goto onError;
+#ifdef Py_UNICODE_WIDE
+        if (x < 0 || x > 0x10ffff) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "%c arg not in range(0x110000) "
+                            "(wide Python build)");
+            return -1;
+        }
+#else
+        if (x < 0 || x > 0xffff) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "%c arg not in range(0x10000) "
+                            "(narrow Python build)");
+            return -1;
+        }
+#endif
+        buf[0] = (Py_UNICODE) x;
+    }
+    buf[1] = '\0';
+    return 1;
+
+  onError:
+    PyErr_SetString(PyExc_TypeError,
+                    "%c requires int or char");
+    return -1;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
+
+   FORMATBUFLEN is the length of the buffer in which the ints &
+   chars are formatted. XXX This is a magic number. Each formatting
+   routine does bounds checking to ensure no overflow, but a better
+   solution may be to malloc a buffer of appropriate size for each
+   format. For now, the current solution is sufficient.
+*/
+#define FORMATBUFLEN (size_t)120
+
+PyObject *PyUnicode_Format(PyObject *format,
+                           PyObject *args)
+{
+    Py_UNICODE *fmt, *res;
+    Py_ssize_t fmtcnt, rescnt, reslen, arglen, argidx;
+    int args_owned = 0;
+    PyUnicodeObject *result = NULL;
+    PyObject *dict = NULL;
+    PyObject *uformat;
+
+    if (format == NULL || args == NULL) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    uformat = PyUnicode_FromObject(format);
+    if (uformat == NULL)
+        return NULL;
+    fmt = PyUnicode_AS_UNICODE(uformat);
+    fmtcnt = PyUnicode_GET_SIZE(uformat);
+
+    reslen = rescnt = fmtcnt + 100;
+    result = _PyUnicode_New(reslen);
+    if (result == NULL)
+        goto onError;
+    res = PyUnicode_AS_UNICODE(result);
+
+    if (PyTuple_Check(args)) {
+        arglen = PyTuple_Size(args);
+        argidx = 0;
+    }
+    else {
+        arglen = -1;
+        argidx = -2;
+    }
+    if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript &&
+        !PyTuple_Check(args) && !PyObject_TypeCheck(args, &PyBaseString_Type))
+        dict = args;
+
+    while (--fmtcnt >= 0) {
+        if (*fmt != '%') {
+            if (--rescnt < 0) {
+                rescnt = fmtcnt + 100;
+                reslen += rescnt;
+                if (_PyUnicode_Resize(&result, reslen) < 0)
+                    goto onError;
+                res = PyUnicode_AS_UNICODE(result) + reslen - rescnt;
+                --rescnt;
+            }
+            *res++ = *fmt++;
+        }
+        else {
+            /* Got a format specifier */
+            int flags = 0;
+            Py_ssize_t width = -1;
+            int prec = -1;
+            Py_UNICODE c = '\0';
+            Py_UNICODE fill;
+            int isnumok;
+            PyObject *v = NULL;
+            PyObject *temp = NULL;
+            Py_UNICODE *pbuf;
+            Py_UNICODE sign;
+            Py_ssize_t len;
+            Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{int,char}() */
+
+            fmt++;
+            if (*fmt == '(') {
+                Py_UNICODE *keystart;
+                Py_ssize_t keylen;
+                PyObject *key;
+                int pcount = 1;
+
+                if (dict == NULL) {
+                    PyErr_SetString(PyExc_TypeError,
+                                    "format requires a mapping");
+                    goto onError;
+                }
+                ++fmt;
+                --fmtcnt;
+                keystart = fmt;
+                /* Skip over balanced parentheses */
+                while (pcount > 0 && --fmtcnt >= 0) {
+                    if (*fmt == ')')
+                        --pcount;
+                    else if (*fmt == '(')
+                        ++pcount;
+                    fmt++;
+                }
+                keylen = fmt - keystart - 1;
+                if (fmtcnt < 0 || pcount > 0) {
+                    PyErr_SetString(PyExc_ValueError,
+                                    "incomplete format key");
+                    goto onError;
+                }
+#if 0
+                /* keys are converted to strings using UTF-8 and
+                   then looked up since Python uses strings to hold
+                   variables names etc. in its namespaces and we
+                   wouldn't want to break common idioms. */
+                key = PyUnicode_EncodeUTF8(keystart,
+                                           keylen,
+                                           NULL);
+#else
+                key = PyUnicode_FromUnicode(keystart, keylen);
+#endif
+                if (key == NULL)
+                    goto onError;
+                if (args_owned) {
+                    Py_DECREF(args);
+                    args_owned = 0;
+                }
+                args = PyObject_GetItem(dict, key);
+                Py_DECREF(key);
+                if (args == NULL) {
+                    goto onError;
+                }
+                args_owned = 1;
+                arglen = -1;
+                argidx = -2;
+            }
+            while (--fmtcnt >= 0) {
+                switch (c = *fmt++) {
+                case '-': flags |= F_LJUST; continue;
+                case '+': flags |= F_SIGN; continue;
+                case ' ': flags |= F_BLANK; continue;
+                case '#': flags |= F_ALT; continue;
+                case '0': flags |= F_ZERO; continue;
+                }
+                break;
+            }
+            if (c == '*') {
+                v = getnextarg(args, arglen, &argidx);
+                if (v == NULL)
+                    goto onError;
+                if (!PyInt_Check(v)) {
+                    PyErr_SetString(PyExc_TypeError,
+                                    "* wants int");
+                    goto onError;
+                }
+                width = PyInt_AsSsize_t(v);
+                if (width == -1 && PyErr_Occurred())
+                    goto onError;
+                if (width < 0) {
+                    flags |= F_LJUST;
+                    width = -width;
+                }
+                if (--fmtcnt >= 0)
+                    c = *fmt++;
+            }
+            else if (c >= '0' && c <= '9') {
+                width = c - '0';
+                while (--fmtcnt >= 0) {
+                    c = *fmt++;
+                    if (c < '0' || c > '9')
+                        break;
+                    if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) {
+                        PyErr_SetString(PyExc_ValueError,
+                                        "width too big");
+                        goto onError;
+                    }
+                    width = width*10 + (c - '0');
+                }
+            }
+            if (c == '.') {
+                prec = 0;
+                if (--fmtcnt >= 0)
+                    c = *fmt++;
+                if (c == '*') {
+                    v = getnextarg(args, arglen, &argidx);
+                    if (v == NULL)
+                        goto onError;
+                    if (!PyInt_Check(v)) {
+                        PyErr_SetString(PyExc_TypeError,
+                                        "* wants int");
+                        goto onError;
+                    }
+                    prec = _PyInt_AsInt(v);
+                    if (prec == -1 && PyErr_Occurred())
+                        goto onError;
+                    if (prec < 0)
+                        prec = 0;
+                    if (--fmtcnt >= 0)
+                        c = *fmt++;
+                }
+                else if (c >= '0' && c <= '9') {
+                    prec = c - '0';
+                    while (--fmtcnt >= 0) {
+                        c = *fmt++;
+                        if (c < '0' || c > '9')
+                            break;
+                        if (prec > (INT_MAX - ((int)c - '0')) / 10) {
+                            PyErr_SetString(PyExc_ValueError,
+                                            "prec too big");
+                            goto onError;
+                        }
+                        prec = prec*10 + (c - '0');
+                    }
+                }
+            } /* prec */
+            if (fmtcnt >= 0) {
+                if (c == 'h' || c == 'l' || c == 'L') {
+                    if (--fmtcnt >= 0)
+                        c = *fmt++;
+                }
+            }
+            if (fmtcnt < 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "incomplete format");
+                goto onError;
+            }
+            if (c != '%') {
+                v = getnextarg(args, arglen, &argidx);
+                if (v == NULL)
+                    goto onError;
+            }
+            sign = 0;
+            fill = ' ';
+            switch (c) {
+
+            case '%':
+                pbuf = formatbuf;
+                /* presume that buffer length is at least 1 */
+                pbuf[0] = '%';
+                len = 1;
+                break;
+
+            case 's':
+            case 'r':
+                if (PyUnicode_CheckExact(v) && c == 's') {
+                    temp = v;
+                    Py_INCREF(temp);
+                }
+                else {
+                    PyObject *unicode;
+                    if (c == 's')
+                        temp = PyObject_Unicode(v);
+                    else
+                        temp = PyObject_Repr(v);
+                    if (temp == NULL)
+                        goto onError;
+                    if (PyUnicode_Check(temp))
+                        /* nothing to do */;
+                    else if (PyString_Check(temp)) {
+                        /* convert to string to Unicode */
+                        unicode = PyUnicode_Decode(PyString_AS_STRING(temp),
+                                                   PyString_GET_SIZE(temp),
+                                                   NULL,
+                                                   "strict");
+                        Py_DECREF(temp);
+                        temp = unicode;
+                        if (temp == NULL)
+                            goto onError;
+                    }
+                    else {
+                        Py_DECREF(temp);
+                        PyErr_SetString(PyExc_TypeError,
+                                        "%s argument has non-string str()");
+                        goto onError;
+                    }
+                }
+                pbuf = PyUnicode_AS_UNICODE(temp);
+                len = PyUnicode_GET_SIZE(temp);
+                if (prec >= 0 && len > prec)
+                    len = prec;
+                break;
+
+            case 'i':
+            case 'd':
+            case 'u':
+            case 'o':
+            case 'x':
+            case 'X':
+                if (c == 'i')
+                    c = 'd';
+                isnumok = 0;
+                if (PyNumber_Check(v)) {
+                    PyObject *iobj=NULL;
+
+                    if (PyInt_Check(v) || (PyLong_Check(v))) {
+                        iobj = v;
+                        Py_INCREF(iobj);
+                    }
+                    else {
+                        iobj = PyNumber_Int(v);
+                        if (iobj==NULL) iobj = PyNumber_Long(v);
+                    }
+                    if (iobj!=NULL) {
+                        if (PyInt_Check(iobj)) {
+                            isnumok = 1;
+                            pbuf = formatbuf;
+                            len = formatint(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE),
+                                            flags, prec, c, iobj);
+                            Py_DECREF(iobj);
+                            if (len < 0)
+                                goto onError;
+                            sign = 1;
+                        }
+                        else if (PyLong_Check(iobj)) {
+                            isnumok = 1;
+                            temp = formatlong(iobj, flags, prec, c);
+                            Py_DECREF(iobj);
+                            if (!temp)
+                                goto onError;
+                            pbuf = PyUnicode_AS_UNICODE(temp);
+                            len = PyUnicode_GET_SIZE(temp);
+                            sign = 1;
+                        }
+                        else {
+                            Py_DECREF(iobj);
+                        }
+                    }
+                }
+                if (!isnumok) {
+                    PyErr_Format(PyExc_TypeError,
+                                 "%%%c format: a number is required, "
+                                 "not %.200s", (char)c, Py_TYPE(v)->tp_name);
+                    goto onError;
+                }
+                if (flags & F_ZERO)
+                    fill = '0';
+                break;
+
+            case 'e':
+            case 'E':
+            case 'f':
+            case 'F':
+            case 'g':
+            case 'G':
+                temp = formatfloat(v, flags, prec, c);
+                if (temp == NULL)
+                    goto onError;
+                pbuf = PyUnicode_AS_UNICODE(temp);
+                len = PyUnicode_GET_SIZE(temp);
+                sign = 1;
+                if (flags & F_ZERO)
+                    fill = '0';
+                break;
+
+            case 'c':
+                pbuf = formatbuf;
+                len = formatchar(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE), v);
+                if (len < 0)
+                    goto onError;
+                break;
+
+            default:
+                PyErr_Format(PyExc_ValueError,
+                             "unsupported format character '%c' (0x%x) "
+                             "at index %zd",
+                             (31<=c && c<=126) ? (char)c : '?',
+                             (int)c,
+                             (Py_ssize_t)(fmt - 1 -
+                                          PyUnicode_AS_UNICODE(uformat)));
+                goto onError;
+            }
+            if (sign) {
+                if (*pbuf == '-' || *pbuf == '+') {
+                    sign = *pbuf++;
+                    len--;
+                }
+                else if (flags & F_SIGN)
+                    sign = '+';
+                else if (flags & F_BLANK)
+                    sign = ' ';
+                else
+                    sign = 0;
+            }
+            if (width < len)
+                width = len;
+            if (rescnt - (sign != 0) < width) {
+                reslen -= rescnt;
+                rescnt = width + fmtcnt + 100;
+                reslen += rescnt;
+                if (reslen < 0) {
+                    Py_XDECREF(temp);
+                    PyErr_NoMemory();
+                    goto onError;
+                }
+                if (_PyUnicode_Resize(&result, reslen) < 0) {
+                    Py_XDECREF(temp);
+                    goto onError;
+                }
+                res = PyUnicode_AS_UNICODE(result)
+                    + reslen - rescnt;
+            }
+            if (sign) {
+                if (fill != ' ')
+                    *res++ = sign;
+                rescnt--;
+                if (width > len)
+                    width--;
+            }
+            if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+                assert(pbuf[0] == '0');
+                assert(pbuf[1] == c);
+                if (fill != ' ') {
+                    *res++ = *pbuf++;
+                    *res++ = *pbuf++;
+                }
+                rescnt -= 2;
+                width -= 2;
+                if (width < 0)
+                    width = 0;
+                len -= 2;
+            }
+            if (width > len && !(flags & F_LJUST)) {
+                do {
+                    --rescnt;
+                    *res++ = fill;
+                } while (--width > len);
+            }
+            if (fill == ' ') {
+                if (sign)
+                    *res++ = sign;
+                if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+                    assert(pbuf[0] == '0');
+                    assert(pbuf[1] == c);
+                    *res++ = *pbuf++;
+                    *res++ = *pbuf++;
+                }
+            }
+            Py_UNICODE_COPY(res, pbuf, len);
+            res += len;
+            rescnt -= len;
+            while (--width >= len) {
+                --rescnt;
+                *res++ = ' ';
+            }
+            if (dict && (argidx < arglen) && c != '%') {
+                PyErr_SetString(PyExc_TypeError,
+                                "not all arguments converted during string formatting");
+                Py_XDECREF(temp);
+                goto onError;
+            }
+            Py_XDECREF(temp);
+        } /* '%' */
+    } /* until end */
+    if (argidx < arglen && !dict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "not all arguments converted during string formatting");
+        goto onError;
+    }
+
+    if (_PyUnicode_Resize(&result, reslen - rescnt) < 0)
+        goto onError;
+    if (args_owned) {
+        Py_DECREF(args);
+    }
+    Py_DECREF(uformat);
+    return (PyObject *)result;
+
+  onError:
+    Py_XDECREF(result);
+    Py_DECREF(uformat);
+    if (args_owned) {
+        Py_DECREF(args);
+    }
+    return NULL;
+}
+
+static PyBufferProcs unicode_as_buffer = {
+    (readbufferproc) unicode_buffer_getreadbuf,
+    (writebufferproc) unicode_buffer_getwritebuf,
+    (segcountproc) unicode_buffer_getsegcount,
+    (charbufferproc) unicode_buffer_getcharbuf,
+};
+
+static PyObject *
+unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *x = NULL;
+    static char *kwlist[] = {"string", "encoding", "errors", 0};
+    char *encoding = NULL;
+    char *errors = NULL;
+
+    if (type != &PyUnicode_Type)
+        return unicode_subtype_new(type, args, kwds);
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:unicode",
+                                     kwlist, &x, &encoding, &errors))
+        return NULL;
+    if (x == NULL)
+        return (PyObject *)_PyUnicode_New(0);
+    if (encoding == NULL && errors == NULL)
+        return PyObject_Unicode(x);
+    else
+        return PyUnicode_FromEncodedObject(x, encoding, errors);
+}
+
+static PyObject *
+unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyUnicodeObject *tmp, *pnew;
+    Py_ssize_t n;
+
+    assert(PyType_IsSubtype(type, &PyUnicode_Type));
+    tmp = (PyUnicodeObject *)unicode_new(&PyUnicode_Type, args, kwds);
+    if (tmp == NULL)
+        return NULL;
+    assert(PyUnicode_Check(tmp));
+    pnew = (PyUnicodeObject *) type->tp_alloc(type, n = tmp->length);
+    if (pnew == NULL) {
+        Py_DECREF(tmp);
+        return NULL;
+    }
+    pnew->str = (Py_UNICODE*) PyObject_MALLOC(sizeof(Py_UNICODE) * (n+1));
+    if (pnew->str == NULL) {
+        _Py_ForgetReference((PyObject *)pnew);
+        PyObject_Del(pnew);
+        Py_DECREF(tmp);
+        return PyErr_NoMemory();
+    }
+    Py_UNICODE_COPY(pnew->str, tmp->str, n+1);
+    pnew->length = n;
+    pnew->hash = tmp->hash;
+    Py_DECREF(tmp);
+    return (PyObject *)pnew;
+}
+
+PyDoc_STRVAR(unicode_doc,
+             "unicode(object='') -> unicode object\n\
+unicode(string[, encoding[, errors]]) -> unicode object\n\
+\n\
+Create a new Unicode object from the given encoded string.\n\
+encoding defaults to the current default string encoding.\n\
+errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.");
+
+PyTypeObject PyUnicode_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "unicode",              /* tp_name */
+    sizeof(PyUnicodeObject),        /* tp_size */
+    0,                  /* tp_itemsize */
+    /* Slots */
+    (destructor)unicode_dealloc,    /* tp_dealloc */
+    0,                  /* tp_print */
+    0,                  /* tp_getattr */
+    0,                  /* tp_setattr */
+    0,                  /* tp_compare */
+    unicode_repr,           /* tp_repr */
+    &unicode_as_number,         /* tp_as_number */
+    &unicode_as_sequence,       /* tp_as_sequence */
+    &unicode_as_mapping,        /* tp_as_mapping */
+    (hashfunc) unicode_hash,        /* tp_hash*/
+    0,                  /* tp_call*/
+    (reprfunc) unicode_str,     /* tp_str */
+    PyObject_GenericGetAttr,        /* tp_getattro */
+    0,                  /* tp_setattro */
+    &unicode_as_buffer,         /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+    Py_TPFLAGS_BASETYPE | Py_TPFLAGS_UNICODE_SUBCLASS,  /* tp_flags */
+    unicode_doc,            /* tp_doc */
+    0,                  /* tp_traverse */
+    0,                  /* tp_clear */
+    PyUnicode_RichCompare,      /* tp_richcompare */
+    0,                  /* tp_weaklistoffset */
+    0,                  /* tp_iter */
+    0,                  /* tp_iternext */
+    unicode_methods,            /* tp_methods */
+    0,                  /* tp_members */
+    0,                  /* tp_getset */
+    &PyBaseString_Type,         /* tp_base */
+    0,                  /* tp_dict */
+    0,                  /* tp_descr_get */
+    0,                  /* tp_descr_set */
+    0,                  /* tp_dictoffset */
+    0,                  /* tp_init */
+    0,                  /* tp_alloc */
+    unicode_new,            /* tp_new */
+    PyObject_Del,           /* tp_free */
+};
+
+/* Initialize the Unicode implementation */
+
+void _PyUnicode_Init(void)
+{
+    /* XXX - move this array to unicodectype.c ? */
+    Py_UNICODE linebreak[] = {
+        0x000A, /* LINE FEED */
+        0x000D, /* CARRIAGE RETURN */
+        0x001C, /* FILE SEPARATOR */
+        0x001D, /* GROUP SEPARATOR */
+        0x001E, /* RECORD SEPARATOR */
+        0x0085, /* NEXT LINE */
+        0x2028, /* LINE SEPARATOR */
+        0x2029, /* PARAGRAPH SEPARATOR */
+    };
+
+    /* Init the implementation */
+    if (!unicode_empty) {
+        unicode_empty = _PyUnicode_New(0);
+        if (!unicode_empty)
+            return;
+    }
+
+    if (PyType_Ready(&PyUnicode_Type) < 0)
+        Py_FatalError("Can't initialize 'unicode'");
+
+    /* initialize the linebreak bloom filter */
+    bloom_linebreak = make_bloom_mask(
+        linebreak, sizeof(linebreak) / sizeof(linebreak[0])
+        );
+
+    PyType_Ready(&EncodingMapType);
+
+    if (PyType_Ready(&PyFieldNameIter_Type) < 0)
+        Py_FatalError("Can't initialize field name iterator type");
+
+    if (PyType_Ready(&PyFormatterIter_Type) < 0)
+        Py_FatalError("Can't initialize formatter iter type");
+}
+
+/* Finalize the Unicode implementation */
+
+int
+PyUnicode_ClearFreeList(void)
+{
+    int freelist_size = numfree;
+    PyUnicodeObject *u;
+
+    for (u = free_list; u != NULL;) {
+        PyUnicodeObject *v = u;
+        u = *(PyUnicodeObject **)u;
+        if (v->str)
+            PyObject_DEL(v->str);
+        Py_XDECREF(v->defenc);
+        PyObject_Del(v);
+        numfree--;
+    }
+    free_list = NULL;
+    assert(numfree == 0);
+    return freelist_size;
+}
+
+void
+_PyUnicode_Fini(void)
+{
+    int i;
+
+    Py_CLEAR(unicode_empty);
+
+    for (i = 0; i < 256; i++)
+        Py_CLEAR(unicode_latin1[i]);
+
+    (void)PyUnicode_ClearFreeList();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Python-2.7.5/Objects/unicodetype_db.h b/Python-2.7.5/Objects/unicodetype_db.h
new file mode 100644
index 0000000..d2ec46b
--- /dev/null
+++ b/Python-2.7.5/Objects/unicodetype_db.h
@@ -0,0 +1,3337 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.6 */
+
+/* a list of unique character type descriptors */
+const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
+    {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 32},
+    {0, 0, 0, 0, 0, 48},
+    {0, 0, 0, 0, 0, 518},
+    {0, 0, 0, 1, 1, 518},
+    {0, 0, 0, 2, 2, 518},
+    {0, 0, 0, 3, 3, 518},
+    {0, 0, 0, 4, 4, 518},
+    {0, 0, 0, 5, 5, 518},
+    {0, 0, 0, 6, 6, 518},
+    {0, 0, 0, 7, 7, 518},
+    {0, 0, 0, 8, 8, 518},
+    {0, 0, 0, 9, 9, 518},
+    {0, 32, 0, 0, 0, 129},
+    {65504, 0, 65504, 0, 0, 9},
+    {0, 0, 0, 0, 0, 9},
+    {0, 0, 0, 0, 2, 516},
+    {0, 0, 0, 0, 3, 516},
+    {743, 0, 743, 0, 0, 9},
+    {0, 0, 0, 0, 1, 516},
+    {0, 0, 0, 0, 0, 512},
+    {121, 0, 121, 0, 0, 9},
+    {0, 1, 0, 0, 0, 129},
+    {65535, 0, 65535, 0, 0, 9},
+    {0, 65337, 0, 0, 0, 129},
+    {65304, 0, 65304, 0, 0, 9},
+    {0, 65415, 0, 0, 0, 129},
+    {65236, 0, 65236, 0, 0, 9},
+    {195, 0, 195, 0, 0, 9},
+    {0, 210, 0, 0, 0, 129},
+    {0, 206, 0, 0, 0, 129},
+    {0, 205, 0, 0, 0, 129},
+    {0, 79, 0, 0, 0, 129},
+    {0, 202, 0, 0, 0, 129},
+    {0, 203, 0, 0, 0, 129},
+    {0, 207, 0, 0, 0, 129},
+    {97, 0, 97, 0, 0, 9},
+    {0, 211, 0, 0, 0, 129},
+    {0, 209, 0, 0, 0, 129},
+    {163, 0, 163, 0, 0, 9},
+    {0, 213, 0, 0, 0, 129},
+    {130, 0, 130, 0, 0, 9},
+    {0, 214, 0, 0, 0, 129},
+    {0, 218, 0, 0, 0, 129},
+    {0, 217, 0, 0, 0, 129},
+    {0, 219, 0, 0, 0, 129},
+    {0, 0, 0, 0, 0, 1},
+    {56, 0, 56, 0, 0, 9},
+    {0, 2, 1, 0, 0, 129},
+    {65535, 1, 0, 0, 0, 65},
+    {65534, 0, 65535, 0, 0, 9},
+    {65457, 0, 65457, 0, 0, 9},
+    {0, 65439, 0, 0, 0, 129},
+    {0, 65480, 0, 0, 0, 129},
+    {0, 65406, 0, 0, 0, 129},
+    {0, 10795, 0, 0, 0, 129},
+    {0, 65373, 0, 0, 0, 129},
+    {0, 10792, 0, 0, 0, 129},
+    {10815, 0, 10815, 0, 0, 9},
+    {0, 65341, 0, 0, 0, 129},
+    {0, 69, 0, 0, 0, 129},
+    {0, 71, 0, 0, 0, 129},
+    {10783, 0, 10783, 0, 0, 9},
+    {10780, 0, 10780, 0, 0, 9},
+    {10782, 0, 10782, 0, 0, 9},
+    {65326, 0, 65326, 0, 0, 9},
+    {65330, 0, 65330, 0, 0, 9},
+    {65331, 0, 65331, 0, 0, 9},
+    {65334, 0, 65334, 0, 0, 9},
+    {65333, 0, 65333, 0, 0, 9},
+    {65329, 0, 65329, 0, 0, 9},
+    {65327, 0, 65327, 0, 0, 9},
+    {65325, 0, 65325, 0, 0, 9},
+    {10743, 0, 10743, 0, 0, 9},
+    {10749, 0, 10749, 0, 0, 9},
+    {65323, 0, 65323, 0, 0, 9},
+    {65322, 0, 65322, 0, 0, 9},
+    {10727, 0, 10727, 0, 0, 9},
+    {65318, 0, 65318, 0, 0, 9},
+    {65467, 0, 65467, 0, 0, 9},
+    {65319, 0, 65319, 0, 0, 9},
+    {65465, 0, 65465, 0, 0, 9},
+    {65317, 0, 65317, 0, 0, 9},
+    {84, 0, 84, 0, 0, 0},
+    {0, 38, 0, 0, 0, 129},
+    {0, 37, 0, 0, 0, 129},
+    {0, 64, 0, 0, 0, 129},
+    {0, 63, 0, 0, 0, 129},
+    {65498, 0, 65498, 0, 0, 9},
+    {65499, 0, 65499, 0, 0, 9},
+    {65505, 0, 65505, 0, 0, 9},
+    {65472, 0, 65472, 0, 0, 9},
+    {65473, 0, 65473, 0, 0, 9},
+    {0, 8, 0, 0, 0, 129},
+    {65474, 0, 65474, 0, 0, 9},
+    {65479, 0, 65479, 0, 0, 9},
+    {0, 0, 0, 0, 0, 129},
+    {65489, 0, 65489, 0, 0, 9},
+    {65482, 0, 65482, 0, 0, 9},
+    {65528, 0, 65528, 0, 0, 9},
+    {65450, 0, 65450, 0, 0, 9},
+    {65456, 0, 65456, 0, 0, 9},
+    {7, 0, 7, 0, 0, 9},
+    {0, 65476, 0, 0, 0, 129},
+    {65440, 0, 65440, 0, 0, 9},
+    {0, 65529, 0, 0, 0, 129},
+    {0, 80, 0, 0, 0, 129},
+    {0, 15, 0, 0, 0, 129},
+    {65521, 0, 65521, 0, 0, 9},
+    {0, 48, 0, 0, 0, 129},
+    {65488, 0, 65488, 0, 0, 9},
+    {0, 7264, 0, 0, 0, 129},
+    {0, 0, 0, 0, 4, 516},
+    {0, 0, 0, 0, 5, 516},
+    {0, 0, 0, 0, 6, 516},
+    {0, 0, 0, 0, 7, 516},
+    {0, 0, 0, 0, 8, 516},
+    {0, 0, 0, 0, 9, 516},
+    {42877, 7545, 42877, 0, 0, 265},
+    {3814, 0, 3814, 0, 0, 9},
+    {65477, 0, 65477, 0, 0, 9},
+    {0, 57921, 0, 0, 0, 129},
+    {8, 0, 8, 0, 0, 9},
+    {0, 65528, 0, 0, 0, 129},
+    {74, 0, 74, 0, 0, 9},
+    {86, 0, 86, 0, 0, 9},
+    {100, 0, 100, 0, 0, 9},
+    {128, 0, 128, 0, 0, 9},
+    {112, 0, 112, 0, 0, 9},
+    {126, 0, 126, 0, 0, 9},
+    {0, 65528, 0, 0, 0, 65},
+    {9, 0, 9, 0, 0, 9},
+    {0, 65462, 0, 0, 0, 129},
+    {0, 65527, 0, 0, 0, 65},
+    {58331, 0, 58331, 0, 0, 9},
+    {0, 65450, 0, 0, 0, 129},
+    {0, 65436, 0, 0, 0, 129},
+    {0, 65424, 0, 0, 0, 129},
+    {0, 65408, 0, 0, 0, 129},
+    {0, 65410, 0, 0, 0, 129},
+    {0, 0, 0, 0, 0, 516},
+    {0, 58019, 0, 0, 0, 129},
+    {0, 57153, 0, 0, 0, 129},
+    {0, 57274, 0, 0, 0, 129},
+    {0, 28, 0, 0, 0, 129},
+    {65508, 0, 65508, 0, 0, 9},
+    {0, 16, 0, 0, 0, 512},
+    {65520, 0, 65520, 0, 0, 512},
+    {0, 26, 0, 0, 0, 0},
+    {65510, 0, 65510, 0, 0, 0},
+    {0, 54793, 0, 0, 0, 129},
+    {0, 61722, 0, 0, 0, 129},
+    {0, 54809, 0, 0, 0, 129},
+    {54741, 0, 54741, 0, 0, 9},
+    {54744, 0, 54744, 0, 0, 9},
+    {0, 54756, 0, 0, 0, 129},
+    {0, 54787, 0, 0, 0, 129},
+    {0, 54753, 0, 0, 0, 129},
+    {0, 54754, 0, 0, 0, 129},
+    {0, 54721, 0, 0, 0, 129},
+    {58272, 0, 58272, 0, 0, 9},
+    {0, 0, 0, 0, 0, 513},
+    {42877, 7545, 42877, 0, 0, 385},
+    {0, 40, 0, 0, 0, 129},
+    {65496, 0, 65496, 0, 0, 9},
+};
+
+/* type indexes */
+#define SHIFT 7
+static unsigned char index1[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
+    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 
+    38, 39, 34, 34, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 
+    53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 65, 66, 67, 64, 
+    64, 64, 68, 69, 70, 64, 64, 64, 64, 64, 64, 71, 17, 72, 73, 74, 75, 76, 
+    77, 64, 78, 79, 80, 81, 82, 83, 84, 64, 64, 85, 86, 34, 34, 34, 34, 34, 
+    34, 87, 34, 34, 34, 34, 34, 88, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 89, 90, 91, 92, 34, 34, 34, 93, 34, 34, 
+    34, 94, 95, 34, 34, 34, 34, 34, 96, 34, 34, 34, 97, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 98, 99, 100, 34, 34, 34, 34, 34, 34, 101, 102, 34, 
+    34, 34, 34, 34, 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34, 
+    101, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 106, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 107, 108, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 109, 110, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 111, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 112, 34, 34, 113, 114, 115, 116, 117, 118, 119, 120, 121, 
+    122, 17, 123, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    124, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 125, 126, 127, 128, 
+    129, 130, 34, 34, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 17, 
+    141, 142, 143, 144, 145, 17, 17, 17, 17, 17, 17, 146, 17, 147, 17, 148, 
+    17, 149, 17, 150, 17, 17, 17, 151, 17, 17, 17, 17, 152, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 153, 17, 154, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 155, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    64, 156, 157, 158, 159, 17, 160, 17, 161, 162, 163, 164, 165, 166, 167, 
+    168, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 169, 170, 171, 172, 
+    173, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 174, 175, 176, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 177, 34, 178, 179, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 180, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 181, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 182, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 183, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 184, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 
+    185, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 34, 180, 34, 34, 186, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    187, 17, 64, 188, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 189, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 
+    64, 64, 64, 64, 64, 189, 
+};
+
+static unsigned char index2[] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 
+    1, 1, 1, 1, 17, 18, 1, 19, 1, 1, 1, 20, 16, 1, 21, 21, 21, 1, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 16, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15, 
+    15, 15, 15, 15, 15, 15, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 25, 26, 23, 24, 23, 24, 23, 24, 16, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 27, 23, 24, 23, 24, 23, 24, 28, 29, 30, 23, 24, 23, 24, 31, 23, 24, 
+    32, 32, 23, 24, 16, 33, 34, 35, 23, 24, 32, 36, 37, 38, 39, 23, 24, 40, 
+    16, 38, 41, 42, 43, 23, 24, 23, 24, 23, 24, 44, 23, 24, 44, 16, 16, 23, 
+    24, 44, 23, 24, 45, 45, 23, 24, 23, 24, 46, 23, 24, 16, 47, 23, 24, 16, 
+    48, 47, 47, 47, 47, 49, 50, 51, 49, 50, 51, 49, 50, 51, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 52, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 49, 50, 51, 23, 
+    24, 53, 54, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 55, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 16, 16, 16, 16, 16, 56, 23, 24, 
+    57, 58, 59, 59, 23, 24, 60, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 63, 64, 65, 66, 67, 16, 68, 68, 16, 69, 16, 70, 16, 16, 16, 16, 68, 
+    16, 16, 71, 16, 16, 16, 16, 72, 73, 16, 74, 16, 16, 16, 73, 16, 75, 76, 
+    16, 16, 77, 16, 16, 16, 16, 16, 16, 16, 78, 16, 16, 79, 16, 16, 79, 16, 
+    16, 16, 16, 79, 80, 81, 81, 82, 16, 16, 16, 16, 16, 83, 16, 47, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 
+    47, 1, 1, 1, 1, 1, 1, 1, 47, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 
+    23, 24, 47, 1, 23, 24, 0, 0, 47, 42, 42, 42, 1, 0, 0, 0, 0, 0, 1, 1, 85, 
+    1, 86, 86, 86, 0, 87, 0, 88, 88, 16, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    89, 90, 90, 90, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 93, 93, 94, 
+    95, 96, 97, 97, 97, 98, 99, 100, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 101, 102, 103, 
+    16, 104, 105, 1, 23, 24, 106, 23, 24, 16, 55, 55, 55, 107, 107, 107, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 102, 102, 102, 102, 102, 102, 102, 102, 102, 
+    102, 102, 102, 102, 102, 102, 102, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 108, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 109, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 
+    110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 
+    110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 
+    110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 47, 1, 1, 1, 1, 1, 1, 0, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 16, 0, 1, 1, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 5, 6, 7, 8, 9, 10, 
+    11, 12, 13, 1, 1, 1, 1, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 1, 1, 1, 1, 
+    1, 1, 1, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 47, 47, 1, 1, 47, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 47, 1, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 47, 47, 1, 1, 1, 1, 47, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 1, 1, 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 1, 1, 1, 47, 1, 1, 1, 
+    1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 47, 1, 
+    1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 
+    47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 
+    1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 47, 47, 0, 47, 47, 47, 1, 
+    1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 47, 1, 1, 21, 21, 21, 21, 
+    21, 21, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 0, 0, 0, 
+    0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 
+    0, 47, 47, 0, 47, 47, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 
+    1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 0, 47, 0, 0, 0, 
+    0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 47, 47, 47, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    47, 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 
+    1, 0, 1, 1, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
+    0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 
+    0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 
+    0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 47, 47, 0, 47, 47, 
+    47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 47, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 0, 47, 47, 47, 47, 47, 47, 0, 0, 
+    0, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, 0, 47, 0, 47, 47, 0, 
+    0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 
+    1, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 47, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 
+    0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 47, 47, 0, 0, 0, 0, 0, 0, 
+    47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 
+    0, 0, 21, 21, 21, 21, 21, 21, 21, 1, 0, 0, 1, 1, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 
+    1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 47, 0, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 1, 1, 1, 1, 
+    1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 0, 0, 1, 1, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 1, 0, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 47, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 0, 
+    0, 0, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 
+    47, 0, 47, 0, 0, 47, 47, 0, 47, 47, 47, 47, 1, 47, 47, 1, 1, 1, 1, 1, 1, 
+    0, 1, 1, 47, 0, 0, 47, 47, 47, 47, 47, 0, 47, 0, 1, 1, 1, 1, 1, 1, 0, 0, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 4, 5, 6, 7, 8, 
+    9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 
+    47, 47, 47, 47, 1, 1, 1, 47, 1, 1, 1, 47, 47, 1, 1, 1, 1, 1, 1, 1, 47, 
+    47, 47, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 1, 1, 1, 1, 1, 1, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 
+    112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 
+    112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 113, 114, 115, 
+    116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 21, 21, 21, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 47, 47, 47, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 47, 1, 1, 1, 1, 47, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 4, 5, 6, 7, 8, 9, 
+    10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 
+    47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 
+    8, 9, 10, 11, 12, 13, 5, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 1, 1, 1, 1, 1, 0, 0, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    47, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 
+    10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
+    0, 0, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 
+    11, 12, 13, 0, 0, 0, 47, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 1, 47, 47, 47, 47, 1, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 47, 119, 16, 16, 16, 120, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 16, 16, 16, 16, 16, 121, 16, 16, 122, 16, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 123, 
+    123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 124, 
+    124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, 124, 124, 124, 124, 0, 
+    0, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 
+    124, 124, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 
+    124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, 124, 
+    124, 124, 124, 0, 0, 16, 123, 16, 123, 16, 123, 16, 123, 0, 124, 0, 124, 
+    0, 124, 0, 124, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 
+    124, 124, 124, 124, 124, 125, 125, 126, 126, 126, 126, 127, 127, 128, 
+    128, 129, 129, 130, 130, 0, 0, 123, 123, 123, 123, 123, 123, 123, 123, 
+    131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 123, 123, 123, 123, 
+    123, 123, 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 123, 123, 
+    123, 123, 123, 123, 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 16, 
+    132, 16, 0, 16, 16, 124, 124, 133, 133, 134, 1, 135, 1, 1, 1, 16, 132, 
+    16, 0, 16, 16, 136, 136, 136, 136, 134, 1, 1, 1, 123, 123, 16, 16, 0, 0, 
+    16, 16, 124, 124, 137, 137, 0, 1, 1, 1, 123, 123, 16, 16, 16, 103, 16, 
+    16, 124, 124, 138, 138, 106, 1, 1, 1, 0, 0, 16, 132, 16, 0, 16, 16, 139, 
+    139, 140, 140, 134, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 141, 47, 0, 0, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 47, 141, 
+    20, 17, 18, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 0, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 97, 1, 1, 1, 1, 97, 1, 1, 
+    16, 97, 97, 97, 16, 16, 97, 97, 97, 16, 1, 97, 1, 1, 1, 97, 97, 97, 97, 
+    97, 1, 1, 1, 1, 1, 1, 97, 1, 142, 1, 97, 1, 143, 144, 97, 97, 1, 16, 97, 
+    97, 145, 97, 16, 47, 47, 47, 47, 16, 1, 1, 16, 16, 97, 97, 1, 1, 1, 1, 1, 
+    97, 16, 16, 16, 16, 1, 1, 1, 1, 146, 1, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 147, 147, 147, 147, 147, 147, 147, 147, 
+    147, 147, 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, 148, 
+    148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 21, 21, 21, 23, 24, 21, 
+    21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 17, 18, 113, 
+    114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 
+    17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 
+    149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 
+    149, 149, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 
+    150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 
+    141, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 17, 18, 113, 114, 115, 
+    116, 117, 118, 21, 141, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 
+    1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 
+    1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 113, 114, 115, 116, 
+    117, 118, 21, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 20, 17, 18, 
+    113, 114, 115, 116, 117, 118, 21, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 
+    110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 
+    110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 
+    110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 
+    111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 0, 
+    23, 24, 151, 152, 153, 154, 155, 23, 24, 23, 24, 23, 24, 156, 157, 158, 
+    159, 16, 23, 24, 16, 23, 24, 16, 16, 16, 16, 16, 16, 47, 160, 160, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 21, 1, 1, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
+    161, 161, 161, 161, 161, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 
+    47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 47, 47, 21, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 1, 1, 21, 21, 
+    21, 47, 47, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 1, 1, 1, 1, 47, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 47, 47, 47, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 1, 1, 21, 21, 21, 21, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 162, 47, 47, 162, 
+    47, 47, 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 
+    162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 162, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 162, 
+    162, 162, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    162, 162, 162, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 162, 162, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 
+    47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 47, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 47, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 16, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 47, 16, 16, 16, 16, 
+    16, 16, 16, 16, 23, 24, 23, 24, 163, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 47, 1, 1, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 
+    47, 47, 47, 47, 47, 1, 47, 47, 47, 1, 47, 47, 47, 47, 1, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 6, 7, 8, 9, 10, 
+    11, 12, 13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 0, 0, 0, 0, 4, 5, 6, 7, 
+    8, 9, 10, 11, 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 1, 1, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 1, 47, 47, 47, 47, 47, 
+    47, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 1, 1, 1, 
+    1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 1, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 1, 47, 1, 1, 1, 47, 47, 1, 1, 47, 47, 47, 47, 
+    47, 1, 1, 47, 1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
+    0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 47, 1, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 0, 47, 47, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 47, 47, 47, 47, 47, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 
+    1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 
+    47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 
+    0, 1, 1, 1, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 21, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21, 
+    47, 47, 47, 47, 47, 47, 47, 47, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 1, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 
+    164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 
+    164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 
+    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 
+    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 
+    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 1, 21, 
+    21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21, 
+    21, 21, 21, 21, 21, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 
+    0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 1, 1, 1, 0, 
+    1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 20, 
+    17, 18, 113, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    21, 21, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 21, 21, 21, 
+    21, 21, 21, 21, 21, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 0, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 21, 21, 21, 21, 21, 
+    21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 
+    16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 97, 0, 97, 97, 0, 0, 97, 0, 0, 97, 97, 0, 0, 97, 97, 97, 97, 0, 
+    97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 0, 16, 0, 16, 16, 16, 16, 
+    16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 0, 97, 97, 
+    97, 97, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 0, 97, 97, 97, 97, 97, 97, 
+    97, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 0, 97, 97, 97, 97, 0, 97, 
+    97, 97, 97, 97, 0, 97, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 0, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 
+    16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 
+    16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 
+    16, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 141, 141, 20, 17, 18, 113, 114, 115, 116, 117, 118, 0, 0, 0, 0, 
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
+    1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 
+    47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
+};
+
+/* Returns the numeric value as double for Unicode characters
+ * having this property, -1.0 otherwise.
+ */
+double _PyUnicode_ToNumeric(Py_UNICODE ch)
+{
+    switch (ch) {
+    case 0x0F33:
+        return (double) -1.0/2.0;
+    case 0x0030:
+    case 0x0660:
+    case 0x06F0:
+    case 0x07C0:
+    case 0x0966:
+    case 0x09E6:
+    case 0x0A66:
+    case 0x0AE6:
+    case 0x0B66:
+    case 0x0BE6:
+    case 0x0C66:
+    case 0x0C78:
+    case 0x0CE6:
+    case 0x0D66:
+    case 0x0E50:
+    case 0x0ED0:
+    case 0x0F20:
+    case 0x1040:
+    case 0x1090:
+    case 0x17E0:
+    case 0x17F0:
+    case 0x1810:
+    case 0x1946:
+    case 0x19D0:
+    case 0x1A80:
+    case 0x1A90:
+    case 0x1B50:
+    case 0x1BB0:
+    case 0x1C40:
+    case 0x1C50:
+    case 0x2070:
+    case 0x2080:
+    case 0x2189:
+    case 0x24EA:
+    case 0x24FF:
+    case 0x3007:
+    case 0x96F6:
+    case 0xA620:
+    case 0xA6EF:
+    case 0xA8D0:
+    case 0xA900:
+    case 0xA9D0:
+    case 0xAA50:
+    case 0xABF0:
+    case 0xF9B2:
+    case 0xFF10:
+#ifdef Py_UNICODE_WIDE
+    case 0x1018A:
+    case 0x104A0:
+    case 0x1D7CE:
+    case 0x1D7D8:
+    case 0x1D7E2:
+    case 0x1D7EC:
+    case 0x1D7F6:
+    case 0x1F100:
+    case 0x1F101:
+#endif
+        return (double) 0.0;
+    case 0x0031:
+    case 0x00B9:
+    case 0x0661:
+    case 0x06F1:
+    case 0x07C1:
+    case 0x0967:
+    case 0x09E7:
+    case 0x0A67:
+    case 0x0AE7:
+    case 0x0B67:
+    case 0x0BE7:
+    case 0x0C67:
+    case 0x0C79:
+    case 0x0C7C:
+    case 0x0CE7:
+    case 0x0D67:
+    case 0x0E51:
+    case 0x0ED1:
+    case 0x0F21:
+    case 0x1041:
+    case 0x1091:
+    case 0x1369:
+    case 0x17E1:
+    case 0x17F1:
+    case 0x1811:
+    case 0x1947:
+    case 0x19D1:
+    case 0x19DA:
+    case 0x1A81:
+    case 0x1A91:
+    case 0x1B51:
+    case 0x1BB1:
+    case 0x1C41:
+    case 0x1C51:
+    case 0x2081:
+    case 0x215F:
+    case 0x2160:
+    case 0x2170:
+    case 0x2460:
+    case 0x2474:
+    case 0x2488:
+    case 0x24F5:
+    case 0x2776:
+    case 0x2780:
+    case 0x278A:
+    case 0x3021:
+    case 0x3192:
+    case 0x3220:
+    case 0x3280:
+    case 0x4E00:
+    case 0x58F1:
+    case 0x58F9:
+    case 0x5E7A:
+    case 0x5F0C:
+    case 0xA621:
+    case 0xA6E6:
+    case 0xA8D1:
+    case 0xA901:
+    case 0xA9D1:
+    case 0xAA51:
+    case 0xABF1:
+    case 0xFF11:
+#ifdef Py_UNICODE_WIDE
+    case 0x10107:
+    case 0x10142:
+    case 0x10158:
+    case 0x10159:
+    case 0x1015A:
+    case 0x10320:
+    case 0x103D1:
+    case 0x104A1:
+    case 0x10858:
+    case 0x10916:
+    case 0x10A40:
+    case 0x10A7D:
+    case 0x10B58:
+    case 0x10B78:
+    case 0x10E60:
+    case 0x12415:
+    case 0x1241E:
+    case 0x1242C:
+    case 0x12434:
+    case 0x1244F:
+    case 0x12458:
+    case 0x1D360:
+    case 0x1D7CF:
+    case 0x1D7D9:
+    case 0x1D7E3:
+    case 0x1D7ED:
+    case 0x1D7F7:
+    case 0x1F102:
+    case 0x2092A:
+#endif
+        return (double) 1.0;
+    case 0x2152:
+        return (double) 1.0/10.0;
+    case 0x09F4:
+    case 0xA833:
+        return (double) 1.0/16.0;
+    case 0x00BD:
+    case 0x0D74:
+    case 0x0F2A:
+    case 0x2CFD:
+    case 0xA831:
+#ifdef Py_UNICODE_WIDE
+    case 0x10141:
+    case 0x10175:
+    case 0x10176:
+    case 0x10E7B:
+#endif
+        return (double) 1.0/2.0;
+    case 0x2153:
+#ifdef Py_UNICODE_WIDE
+    case 0x10E7D:
+    case 0x1245A:
+    case 0x1245D:
+#endif
+        return (double) 1.0/3.0;
+    case 0x00BC:
+    case 0x09F7:
+    case 0x0D73:
+    case 0xA830:
+#ifdef Py_UNICODE_WIDE
+    case 0x10140:
+    case 0x10E7C:
+    case 0x12460:
+    case 0x12462:
+#endif
+        return (double) 1.0/4.0;
+    case 0x2155:
+        return (double) 1.0/5.0;
+    case 0x2159:
+#ifdef Py_UNICODE_WIDE
+    case 0x12461:
+#endif
+        return (double) 1.0/6.0;
+    case 0x2150:
+        return (double) 1.0/7.0;
+    case 0x09F5:
+    case 0x215B:
+    case 0xA834:
+#ifdef Py_UNICODE_WIDE
+    case 0x1245F:
+#endif
+        return (double) 1.0/8.0;
+    case 0x2151:
+        return (double) 1.0/9.0;
+    case 0x0BF0:
+    case 0x0D70:
+    case 0x1372:
+    case 0x2169:
+    case 0x2179:
+    case 0x2469:
+    case 0x247D:
+    case 0x2491:
+    case 0x24FE:
+    case 0x277F:
+    case 0x2789:
+    case 0x2793:
+    case 0x3038:
+    case 0x3229:
+    case 0x3289:
+    case 0x4EC0:
+    case 0x5341:
+    case 0x62FE:
+    case 0xF973:
+    case 0xF9FD:
+#ifdef Py_UNICODE_WIDE
+    case 0x10110:
+    case 0x10149:
+    case 0x10150:
+    case 0x10157:
+    case 0x10160:
+    case 0x10161:
+    case 0x10162:
+    case 0x10163:
+    case 0x10164:
+    case 0x10322:
+    case 0x103D3:
+    case 0x1085B:
+    case 0x10917:
+    case 0x10A44:
+    case 0x10B5C:
+    case 0x10B7C:
+    case 0x10E69:
+    case 0x1D369:
+#endif
+        return (double) 10.0;
+    case 0x0BF1:
+    case 0x0D71:
+    case 0x137B:
+    case 0x216D:
+    case 0x217D:
+    case 0x4F70:
+    case 0x767E:
+    case 0x964C:
+#ifdef Py_UNICODE_WIDE
+    case 0x10119:
+    case 0x1014B:
+    case 0x10152:
+    case 0x1016A:
+    case 0x103D5:
+    case 0x1085D:
+    case 0x10919:
+    case 0x10A46:
+    case 0x10B5E:
+    case 0x10B7E:
+    case 0x10E72:
+#endif
+        return (double) 100.0;
+    case 0x0BF2:
+    case 0x0D72:
+    case 0x216F:
+    case 0x217F:
+    case 0x2180:
+    case 0x4EDF:
+    case 0x5343:
+    case 0x9621:
+#ifdef Py_UNICODE_WIDE
+    case 0x10122:
+    case 0x1014D:
+    case 0x10154:
+    case 0x10171:
+    case 0x1085E:
+    case 0x10A47:
+    case 0x10B5F:
+    case 0x10B7F:
+#endif
+        return (double) 1000.0;
+    case 0x137C:
+    case 0x2182:
+    case 0x4E07:
+    case 0x842C:
+#ifdef Py_UNICODE_WIDE
+    case 0x1012B:
+    case 0x10155:
+    case 0x1085F:
+#endif
+        return (double) 10000.0;
+    case 0x2188:
+        return (double) 100000.0;
+    case 0x4EBF:
+    case 0x5104:
+        return (double) 100000000.0;
+    case 0x5146:
+        return (double) 1000000000000.0;
+    case 0x216A:
+    case 0x217A:
+    case 0x246A:
+    case 0x247E:
+    case 0x2492:
+    case 0x24EB:
+        return (double) 11.0;
+    case 0x0F2F:
+        return (double) 11.0/2.0;
+    case 0x216B:
+    case 0x217B:
+    case 0x246B:
+    case 0x247F:
+    case 0x2493:
+    case 0x24EC:
+        return (double) 12.0;
+    case 0x246C:
+    case 0x2480:
+    case 0x2494:
+    case 0x24ED:
+        return (double) 13.0;
+    case 0x0F30:
+        return (double) 13.0/2.0;
+    case 0x246D:
+    case 0x2481:
+    case 0x2495:
+    case 0x24EE:
+        return (double) 14.0;
+    case 0x246E:
+    case 0x2482:
+    case 0x2496:
+    case 0x24EF:
+        return (double) 15.0;
+    case 0x0F31:
+        return (double) 15.0/2.0;
+    case 0x09F9:
+    case 0x246F:
+    case 0x2483:
+    case 0x2497:
+    case 0x24F0:
+        return (double) 16.0;
+    case 0x16EE:
+    case 0x2470:
+    case 0x2484:
+    case 0x2498:
+    case 0x24F1:
+        return (double) 17.0;
+    case 0x0F32:
+        return (double) 17.0/2.0;
+    case 0x16EF:
+    case 0x2471:
+    case 0x2485:
+    case 0x2499:
+    case 0x24F2:
+        return (double) 18.0;
+    case 0x16F0:
+    case 0x2472:
+    case 0x2486:
+    case 0x249A:
+    case 0x24F3:
+        return (double) 19.0;
+    case 0x0032:
+    case 0x00B2:
+    case 0x0662:
+    case 0x06F2:
+    case 0x07C2:
+    case 0x0968:
+    case 0x09E8:
+    case 0x0A68:
+    case 0x0AE8:
+    case 0x0B68:
+    case 0x0BE8:
+    case 0x0C68:
+    case 0x0C7A:
+    case 0x0C7D:
+    case 0x0CE8:
+    case 0x0D68:
+    case 0x0E52:
+    case 0x0ED2:
+    case 0x0F22:
+    case 0x1042:
+    case 0x1092:
+    case 0x136A:
+    case 0x17E2:
+    case 0x17F2:
+    case 0x1812:
+    case 0x1948:
+    case 0x19D2:
+    case 0x1A82:
+    case 0x1A92:
+    case 0x1B52:
+    case 0x1BB2:
+    case 0x1C42:
+    case 0x1C52:
+    case 0x2082:
+    case 0x2161:
+    case 0x2171:
+    case 0x2461:
+    case 0x2475:
+    case 0x2489:
+    case 0x24F6:
+    case 0x2777:
+    case 0x2781:
+    case 0x278B:
+    case 0x3022:
+    case 0x3193:
+    case 0x3221:
+    case 0x3281:
+    case 0x3483:
+    case 0x4E8C:
+    case 0x5169:
+    case 0x5F0D:
+    case 0x5F10:
+    case 0x8CAE:
+    case 0x8CB3:
+    case 0x8D30:
+    case 0xA622:
+    case 0xA6E7:
+    case 0xA8D2:
+    case 0xA902:
+    case 0xA9D2:
+    case 0xAA52:
+    case 0xABF2:
+    case 0xF978:
+    case 0xFF12:
+#ifdef Py_UNICODE_WIDE
+    case 0x10108:
+    case 0x1015B:
+    case 0x1015C:
+    case 0x1015D:
+    case 0x1015E:
+    case 0x103D2:
+    case 0x104A2:
+    case 0x10859:
+    case 0x1091A:
+    case 0x10A41:
+    case 0x10B59:
+    case 0x10B79:
+    case 0x10E61:
+    case 0x12400:
+    case 0x12416:
+    case 0x1241F:
+    case 0x12423:
+    case 0x1242D:
+    case 0x12435:
+    case 0x1244A:
+    case 0x12450:
+    case 0x12459:
+    case 0x1D361:
+    case 0x1D7D0:
+    case 0x1D7DA:
+    case 0x1D7E4:
+    case 0x1D7EE:
+    case 0x1D7F8:
+    case 0x1F103:
+    case 0x22390:
+#endif
+        return (double) 2.0;
+    case 0x2154:
+#ifdef Py_UNICODE_WIDE
+    case 0x10177:
+    case 0x10E7E:
+    case 0x1245B:
+    case 0x1245E:
+#endif
+        return (double) 2.0/3.0;
+    case 0x2156:
+        return (double) 2.0/5.0;
+    case 0x1373:
+    case 0x2473:
+    case 0x2487:
+    case 0x249B:
+    case 0x24F4:
+    case 0x3039:
+    case 0x5344:
+    case 0x5EFF:
+#ifdef Py_UNICODE_WIDE
+    case 0x10111:
+    case 0x103D4:
+    case 0x1085C:
+    case 0x10918:
+    case 0x10A45:
+    case 0x10B5D:
+    case 0x10B7D:
+    case 0x10E6A:
+    case 0x1D36A:
+#endif
+        return (double) 20.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011A:
+    case 0x10E73:
+        return (double) 200.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10123:
+        return (double) 2000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x1012C:
+        return (double) 20000.0;
+#endif
+    case 0x3251:
+        return (double) 21.0;
+    case 0x3252:
+        return (double) 22.0;
+    case 0x3253:
+        return (double) 23.0;
+    case 0x3254:
+        return (double) 24.0;
+    case 0x3255:
+        return (double) 25.0;
+    case 0x3256:
+        return (double) 26.0;
+    case 0x3257:
+        return (double) 27.0;
+    case 0x3258:
+        return (double) 28.0;
+    case 0x3259:
+        return (double) 29.0;
+    case 0x0033:
+    case 0x00B3:
+    case 0x0663:
+    case 0x06F3:
+    case 0x07C3:
+    case 0x0969:
+    case 0x09E9:
+    case 0x0A69:
+    case 0x0AE9:
+    case 0x0B69:
+    case 0x0BE9:
+    case 0x0C69:
+    case 0x0C7B:
+    case 0x0C7E:
+    case 0x0CE9:
+    case 0x0D69:
+    case 0x0E53:
+    case 0x0ED3:
+    case 0x0F23:
+    case 0x1043:
+    case 0x1093:
+    case 0x136B:
+    case 0x17E3:
+    case 0x17F3:
+    case 0x1813:
+    case 0x1949:
+    case 0x19D3:
+    case 0x1A83:
+    case 0x1A93:
+    case 0x1B53:
+    case 0x1BB3:
+    case 0x1C43:
+    case 0x1C53:
+    case 0x2083:
+    case 0x2162:
+    case 0x2172:
+    case 0x2462:
+    case 0x2476:
+    case 0x248A:
+    case 0x24F7:
+    case 0x2778:
+    case 0x2782:
+    case 0x278C:
+    case 0x3023:
+    case 0x3194:
+    case 0x3222:
+    case 0x3282:
+    case 0x4E09:
+    case 0x4EE8:
+    case 0x53C1:
+    case 0x53C2:
+    case 0x53C3:
+    case 0x53C4:
+    case 0x5F0E:
+    case 0xA623:
+    case 0xA6E8:
+    case 0xA8D3:
+    case 0xA903:
+    case 0xA9D3:
+    case 0xAA53:
+    case 0xABF3:
+    case 0xF96B:
+    case 0xFF13:
+#ifdef Py_UNICODE_WIDE
+    case 0x10109:
+    case 0x104A3:
+    case 0x1085A:
+    case 0x1091B:
+    case 0x10A42:
+    case 0x10B5A:
+    case 0x10B7A:
+    case 0x10E62:
+    case 0x12401:
+    case 0x12408:
+    case 0x12417:
+    case 0x12420:
+    case 0x12424:
+    case 0x12425:
+    case 0x1242E:
+    case 0x1242F:
+    case 0x12436:
+    case 0x12437:
+    case 0x1243A:
+    case 0x1243B:
+    case 0x1244B:
+    case 0x12451:
+    case 0x1D362:
+    case 0x1D7D1:
+    case 0x1D7DB:
+    case 0x1D7E5:
+    case 0x1D7EF:
+    case 0x1D7F9:
+    case 0x1F104:
+    case 0x20AFD:
+    case 0x20B19:
+    case 0x22998:
+    case 0x23B1B:
+#endif
+        return (double) 3.0;
+    case 0x09F6:
+    case 0xA835:
+        return (double) 3.0/16.0;
+    case 0x0F2B:
+        return (double) 3.0/2.0;
+    case 0x00BE:
+    case 0x09F8:
+    case 0x0D75:
+    case 0xA832:
+#ifdef Py_UNICODE_WIDE
+    case 0x10178:
+#endif
+        return (double) 3.0/4.0;
+    case 0x2157:
+        return (double) 3.0/5.0;
+    case 0x215C:
+        return (double) 3.0/8.0;
+    case 0x1374:
+    case 0x303A:
+    case 0x325A:
+    case 0x5345:
+#ifdef Py_UNICODE_WIDE
+    case 0x10112:
+    case 0x10165:
+    case 0x10E6B:
+    case 0x1D36B:
+    case 0x20983:
+#endif
+        return (double) 30.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011B:
+    case 0x1016B:
+    case 0x10E74:
+        return (double) 300.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10124:
+        return (double) 3000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x1012D:
+        return (double) 30000.0;
+#endif
+    case 0x325B:
+        return (double) 31.0;
+    case 0x325C:
+        return (double) 32.0;
+    case 0x325D:
+        return (double) 33.0;
+    case 0x325E:
+        return (double) 34.0;
+    case 0x325F:
+        return (double) 35.0;
+    case 0x32B1:
+        return (double) 36.0;
+    case 0x32B2:
+        return (double) 37.0;
+    case 0x32B3:
+        return (double) 38.0;
+    case 0x32B4:
+        return (double) 39.0;
+    case 0x0034:
+    case 0x0664:
+    case 0x06F4:
+    case 0x07C4:
+    case 0x096A:
+    case 0x09EA:
+    case 0x0A6A:
+    case 0x0AEA:
+    case 0x0B6A:
+    case 0x0BEA:
+    case 0x0C6A:
+    case 0x0CEA:
+    case 0x0D6A:
+    case 0x0E54:
+    case 0x0ED4:
+    case 0x0F24:
+    case 0x1044:
+    case 0x1094:
+    case 0x136C:
+    case 0x17E4:
+    case 0x17F4:
+    case 0x1814:
+    case 0x194A:
+    case 0x19D4:
+    case 0x1A84:
+    case 0x1A94:
+    case 0x1B54:
+    case 0x1BB4:
+    case 0x1C44:
+    case 0x1C54:
+    case 0x2074:
+    case 0x2084:
+    case 0x2163:
+    case 0x2173:
+    case 0x2463:
+    case 0x2477:
+    case 0x248B:
+    case 0x24F8:
+    case 0x2779:
+    case 0x2783:
+    case 0x278D:
+    case 0x3024:
+    case 0x3195:
+    case 0x3223:
+    case 0x3283:
+    case 0x4E96:
+    case 0x56DB:
+    case 0x8086:
+    case 0xA624:
+    case 0xA6E9:
+    case 0xA8D4:
+    case 0xA904:
+    case 0xA9D4:
+    case 0xAA54:
+    case 0xABF4:
+    case 0xFF14:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010A:
+    case 0x104A4:
+    case 0x10A43:
+    case 0x10B5B:
+    case 0x10B7B:
+    case 0x10E63:
+    case 0x12402:
+    case 0x12409:
+    case 0x1240F:
+    case 0x12418:
+    case 0x12421:
+    case 0x12426:
+    case 0x12430:
+    case 0x12438:
+    case 0x1243C:
+    case 0x1243D:
+    case 0x1243E:
+    case 0x1243F:
+    case 0x1244C:
+    case 0x12452:
+    case 0x12453:
+    case 0x1D363:
+    case 0x1D7D2:
+    case 0x1D7DC:
+    case 0x1D7E6:
+    case 0x1D7F0:
+    case 0x1D7FA:
+    case 0x1F105:
+    case 0x20064:
+    case 0x200E2:
+    case 0x2626D:
+#endif
+        return (double) 4.0;
+    case 0x2158:
+        return (double) 4.0/5.0;
+    case 0x1375:
+    case 0x32B5:
+    case 0x534C:
+#ifdef Py_UNICODE_WIDE
+    case 0x10113:
+    case 0x10E6C:
+    case 0x1D36C:
+    case 0x2098C:
+    case 0x2099C:
+#endif
+        return (double) 40.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011C:
+    case 0x10E75:
+        return (double) 400.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10125:
+        return (double) 4000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x1012E:
+        return (double) 40000.0;
+#endif
+    case 0x32B6:
+        return (double) 41.0;
+    case 0x32B7:
+        return (double) 42.0;
+    case 0x32B8:
+        return (double) 43.0;
+    case 0x32B9:
+        return (double) 44.0;
+    case 0x32BA:
+        return (double) 45.0;
+    case 0x32BB:
+        return (double) 46.0;
+    case 0x32BC:
+        return (double) 47.0;
+    case 0x32BD:
+        return (double) 48.0;
+    case 0x32BE:
+        return (double) 49.0;
+    case 0x0035:
+    case 0x0665:
+    case 0x06F5:
+    case 0x07C5:
+    case 0x096B:
+    case 0x09EB:
+    case 0x0A6B:
+    case 0x0AEB:
+    case 0x0B6B:
+    case 0x0BEB:
+    case 0x0C6B:
+    case 0x0CEB:
+    case 0x0D6B:
+    case 0x0E55:
+    case 0x0ED5:
+    case 0x0F25:
+    case 0x1045:
+    case 0x1095:
+    case 0x136D:
+    case 0x17E5:
+    case 0x17F5:
+    case 0x1815:
+    case 0x194B:
+    case 0x19D5:
+    case 0x1A85:
+    case 0x1A95:
+    case 0x1B55:
+    case 0x1BB5:
+    case 0x1C45:
+    case 0x1C55:
+    case 0x2075:
+    case 0x2085:
+    case 0x2164:
+    case 0x2174:
+    case 0x2464:
+    case 0x2478:
+    case 0x248C:
+    case 0x24F9:
+    case 0x277A:
+    case 0x2784:
+    case 0x278E:
+    case 0x3025:
+    case 0x3224:
+    case 0x3284:
+    case 0x3405:
+    case 0x382A:
+    case 0x4E94:
+    case 0x4F0D:
+    case 0xA625:
+    case 0xA6EA:
+    case 0xA8D5:
+    case 0xA905:
+    case 0xA9D5:
+    case 0xAA55:
+    case 0xABF5:
+    case 0xFF15:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010B:
+    case 0x10143:
+    case 0x10148:
+    case 0x1014F:
+    case 0x1015F:
+    case 0x10173:
+    case 0x10321:
+    case 0x104A5:
+    case 0x10E64:
+    case 0x12403:
+    case 0x1240A:
+    case 0x12410:
+    case 0x12419:
+    case 0x12422:
+    case 0x12427:
+    case 0x12431:
+    case 0x12439:
+    case 0x1244D:
+    case 0x12454:
+    case 0x12455:
+    case 0x1D364:
+    case 0x1D7D3:
+    case 0x1D7DD:
+    case 0x1D7E7:
+    case 0x1D7F1:
+    case 0x1D7FB:
+    case 0x1F106:
+    case 0x20121:
+#endif
+        return (double) 5.0;
+    case 0x0F2C:
+        return (double) 5.0/2.0;
+    case 0x215A:
+#ifdef Py_UNICODE_WIDE
+    case 0x1245C:
+#endif
+        return (double) 5.0/6.0;
+    case 0x215D:
+        return (double) 5.0/8.0;
+    case 0x1376:
+    case 0x216C:
+    case 0x217C:
+    case 0x2186:
+    case 0x32BF:
+#ifdef Py_UNICODE_WIDE
+    case 0x10114:
+    case 0x10144:
+    case 0x1014A:
+    case 0x10151:
+    case 0x10166:
+    case 0x10167:
+    case 0x10168:
+    case 0x10169:
+    case 0x10174:
+    case 0x10323:
+    case 0x10A7E:
+    case 0x10E6D:
+    case 0x1D36D:
+#endif
+        return (double) 50.0;
+    case 0x216E:
+    case 0x217E:
+#ifdef Py_UNICODE_WIDE
+    case 0x1011D:
+    case 0x10145:
+    case 0x1014C:
+    case 0x10153:
+    case 0x1016C:
+    case 0x1016D:
+    case 0x1016E:
+    case 0x1016F:
+    case 0x10170:
+    case 0x10E76:
+#endif
+        return (double) 500.0;
+    case 0x2181:
+#ifdef Py_UNICODE_WIDE
+    case 0x10126:
+    case 0x10146:
+    case 0x1014E:
+    case 0x10172:
+#endif
+        return (double) 5000.0;
+    case 0x2187:
+#ifdef Py_UNICODE_WIDE
+    case 0x1012F:
+    case 0x10147:
+    case 0x10156:
+#endif
+        return (double) 50000.0;
+    case 0x0036:
+    case 0x0666:
+    case 0x06F6:
+    case 0x07C6:
+    case 0x096C:
+    case 0x09EC:
+    case 0x0A6C:
+    case 0x0AEC:
+    case 0x0B6C:
+    case 0x0BEC:
+    case 0x0C6C:
+    case 0x0CEC:
+    case 0x0D6C:
+    case 0x0E56:
+    case 0x0ED6:
+    case 0x0F26:
+    case 0x1046:
+    case 0x1096:
+    case 0x136E:
+    case 0x17E6:
+    case 0x17F6:
+    case 0x1816:
+    case 0x194C:
+    case 0x19D6:
+    case 0x1A86:
+    case 0x1A96:
+    case 0x1B56:
+    case 0x1BB6:
+    case 0x1C46:
+    case 0x1C56:
+    case 0x2076:
+    case 0x2086:
+    case 0x2165:
+    case 0x2175:
+    case 0x2185:
+    case 0x2465:
+    case 0x2479:
+    case 0x248D:
+    case 0x24FA:
+    case 0x277B:
+    case 0x2785:
+    case 0x278F:
+    case 0x3026:
+    case 0x3225:
+    case 0x3285:
+    case 0x516D:
+    case 0x9646:
+    case 0x9678:
+    case 0xA626:
+    case 0xA6EB:
+    case 0xA8D6:
+    case 0xA906:
+    case 0xA9D6:
+    case 0xAA56:
+    case 0xABF6:
+    case 0xF9D1:
+    case 0xF9D3:
+    case 0xFF16:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010C:
+    case 0x104A6:
+    case 0x10E65:
+    case 0x12404:
+    case 0x1240B:
+    case 0x12411:
+    case 0x1241A:
+    case 0x12428:
+    case 0x12440:
+    case 0x1244E:
+    case 0x1D365:
+    case 0x1D7D4:
+    case 0x1D7DE:
+    case 0x1D7E8:
+    case 0x1D7F2:
+    case 0x1D7FC:
+    case 0x1F107:
+    case 0x20AEA:
+#endif
+        return (double) 6.0;
+    case 0x1377:
+#ifdef Py_UNICODE_WIDE
+    case 0x10115:
+    case 0x10E6E:
+    case 0x1D36E:
+#endif
+        return (double) 60.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011E:
+    case 0x10E77:
+        return (double) 600.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10127:
+        return (double) 6000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10130:
+        return (double) 60000.0;
+#endif
+    case 0x0037:
+    case 0x0667:
+    case 0x06F7:
+    case 0x07C7:
+    case 0x096D:
+    case 0x09ED:
+    case 0x0A6D:
+    case 0x0AED:
+    case 0x0B6D:
+    case 0x0BED:
+    case 0x0C6D:
+    case 0x0CED:
+    case 0x0D6D:
+    case 0x0E57:
+    case 0x0ED7:
+    case 0x0F27:
+    case 0x1047:
+    case 0x1097:
+    case 0x136F:
+    case 0x17E7:
+    case 0x17F7:
+    case 0x1817:
+    case 0x194D:
+    case 0x19D7:
+    case 0x1A87:
+    case 0x1A97:
+    case 0x1B57:
+    case 0x1BB7:
+    case 0x1C47:
+    case 0x1C57:
+    case 0x2077:
+    case 0x2087:
+    case 0x2166:
+    case 0x2176:
+    case 0x2466:
+    case 0x247A:
+    case 0x248E:
+    case 0x24FB:
+    case 0x277C:
+    case 0x2786:
+    case 0x2790:
+    case 0x3027:
+    case 0x3226:
+    case 0x3286:
+    case 0x3B4D:
+    case 0x4E03:
+    case 0x67D2:
+    case 0x6F06:
+    case 0xA627:
+    case 0xA6EC:
+    case 0xA8D7:
+    case 0xA907:
+    case 0xA9D7:
+    case 0xAA57:
+    case 0xABF7:
+    case 0xFF17:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010D:
+    case 0x104A7:
+    case 0x10E66:
+    case 0x12405:
+    case 0x1240C:
+    case 0x12412:
+    case 0x1241B:
+    case 0x12429:
+    case 0x12441:
+    case 0x12442:
+    case 0x12443:
+    case 0x1D366:
+    case 0x1D7D5:
+    case 0x1D7DF:
+    case 0x1D7E9:
+    case 0x1D7F3:
+    case 0x1D7FD:
+    case 0x1F108:
+    case 0x20001:
+#endif
+        return (double) 7.0;
+    case 0x0F2D:
+        return (double) 7.0/2.0;
+    case 0x215E:
+        return (double) 7.0/8.0;
+    case 0x1378:
+#ifdef Py_UNICODE_WIDE
+    case 0x10116:
+    case 0x10E6F:
+    case 0x1D36F:
+#endif
+        return (double) 70.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x1011F:
+    case 0x10E78:
+        return (double) 700.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10128:
+        return (double) 7000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10131:
+        return (double) 70000.0;
+#endif
+    case 0x0038:
+    case 0x0668:
+    case 0x06F8:
+    case 0x07C8:
+    case 0x096E:
+    case 0x09EE:
+    case 0x0A6E:
+    case 0x0AEE:
+    case 0x0B6E:
+    case 0x0BEE:
+    case 0x0C6E:
+    case 0x0CEE:
+    case 0x0D6E:
+    case 0x0E58:
+    case 0x0ED8:
+    case 0x0F28:
+    case 0x1048:
+    case 0x1098:
+    case 0x1370:
+    case 0x17E8:
+    case 0x17F8:
+    case 0x1818:
+    case 0x194E:
+    case 0x19D8:
+    case 0x1A88:
+    case 0x1A98:
+    case 0x1B58:
+    case 0x1BB8:
+    case 0x1C48:
+    case 0x1C58:
+    case 0x2078:
+    case 0x2088:
+    case 0x2167:
+    case 0x2177:
+    case 0x2467:
+    case 0x247B:
+    case 0x248F:
+    case 0x24FC:
+    case 0x277D:
+    case 0x2787:
+    case 0x2791:
+    case 0x3028:
+    case 0x3227:
+    case 0x3287:
+    case 0x516B:
+    case 0x634C:
+    case 0xA628:
+    case 0xA6ED:
+    case 0xA8D8:
+    case 0xA908:
+    case 0xA9D8:
+    case 0xAA58:
+    case 0xABF8:
+    case 0xFF18:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010E:
+    case 0x104A8:
+    case 0x10E67:
+    case 0x12406:
+    case 0x1240D:
+    case 0x12413:
+    case 0x1241C:
+    case 0x1242A:
+    case 0x12444:
+    case 0x12445:
+    case 0x1D367:
+    case 0x1D7D6:
+    case 0x1D7E0:
+    case 0x1D7EA:
+    case 0x1D7F4:
+    case 0x1D7FE:
+    case 0x1F109:
+#endif
+        return (double) 8.0;
+    case 0x1379:
+#ifdef Py_UNICODE_WIDE
+    case 0x10117:
+    case 0x10E70:
+    case 0x1D370:
+#endif
+        return (double) 80.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x10120:
+    case 0x10E79:
+        return (double) 800.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10129:
+        return (double) 8000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10132:
+        return (double) 80000.0;
+#endif
+    case 0x0039:
+    case 0x0669:
+    case 0x06F9:
+    case 0x07C9:
+    case 0x096F:
+    case 0x09EF:
+    case 0x0A6F:
+    case 0x0AEF:
+    case 0x0B6F:
+    case 0x0BEF:
+    case 0x0C6F:
+    case 0x0CEF:
+    case 0x0D6F:
+    case 0x0E59:
+    case 0x0ED9:
+    case 0x0F29:
+    case 0x1049:
+    case 0x1099:
+    case 0x1371:
+    case 0x17E9:
+    case 0x17F9:
+    case 0x1819:
+    case 0x194F:
+    case 0x19D9:
+    case 0x1A89:
+    case 0x1A99:
+    case 0x1B59:
+    case 0x1BB9:
+    case 0x1C49:
+    case 0x1C59:
+    case 0x2079:
+    case 0x2089:
+    case 0x2168:
+    case 0x2178:
+    case 0x2468:
+    case 0x247C:
+    case 0x2490:
+    case 0x24FD:
+    case 0x277E:
+    case 0x2788:
+    case 0x2792:
+    case 0x3029:
+    case 0x3228:
+    case 0x3288:
+    case 0x4E5D:
+    case 0x5EFE:
+    case 0x7396:
+    case 0xA629:
+    case 0xA6EE:
+    case 0xA8D9:
+    case 0xA909:
+    case 0xA9D9:
+    case 0xAA59:
+    case 0xABF9:
+    case 0xFF19:
+#ifdef Py_UNICODE_WIDE
+    case 0x1010F:
+    case 0x104A9:
+    case 0x10E68:
+    case 0x12407:
+    case 0x1240E:
+    case 0x12414:
+    case 0x1241D:
+    case 0x1242B:
+    case 0x12446:
+    case 0x12447:
+    case 0x12448:
+    case 0x12449:
+    case 0x1D368:
+    case 0x1D7D7:
+    case 0x1D7E1:
+    case 0x1D7EB:
+    case 0x1D7F5:
+    case 0x1D7FF:
+    case 0x1F10A:
+    case 0x2F890:
+#endif
+        return (double) 9.0;
+    case 0x0F2E:
+        return (double) 9.0/2.0;
+    case 0x137A:
+#ifdef Py_UNICODE_WIDE
+    case 0x10118:
+    case 0x10341:
+    case 0x10E71:
+    case 0x1D371:
+#endif
+        return (double) 90.0;
+#ifdef Py_UNICODE_WIDE
+    case 0x10121:
+    case 0x1034A:
+    case 0x10E7A:
+        return (double) 900.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x1012A:
+        return (double) 9000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+    case 0x10133:
+        return (double) 90000.0;
+#endif
+    }
+    return -1.0;
+}
+
+/* Returns 1 for Unicode characters having the bidirectional
+ * type 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise.
+ */
+int _PyUnicode_IsWhitespace(register const Py_UNICODE ch)
+{
+#ifdef WANT_WCTYPE_FUNCTIONS
+    return iswspace(ch);
+#else
+    switch (ch) {
+    case 0x0009:
+    case 0x000A:
+    case 0x000B:
+    case 0x000C:
+    case 0x000D:
+    case 0x001C:
+    case 0x001D:
+    case 0x001E:
+    case 0x001F:
+    case 0x0020:
+    case 0x0085:
+    case 0x00A0:
+    case 0x1680:
+    case 0x180E:
+    case 0x2000:
+    case 0x2001:
+    case 0x2002:
+    case 0x2003:
+    case 0x2004:
+    case 0x2005:
+    case 0x2006:
+    case 0x2007:
+    case 0x2008:
+    case 0x2009:
+    case 0x200A:
+    case 0x2028:
+    case 0x2029:
+    case 0x202F:
+    case 0x205F:
+    case 0x3000:
+        return 1;
+    }
+    return 0;
+#endif
+}
+
+/* Returns 1 for Unicode characters having the line break
+ * property 'BK', 'CR', 'LF' or 'NL' or having bidirectional
+ * type 'B', 0 otherwise.
+ */
+int _PyUnicode_IsLinebreak(register const Py_UNICODE ch)
+{
+    switch (ch) {
+    case 0x000A:
+    case 0x000B:
+    case 0x000C:
+    case 0x000D:
+    case 0x001C:
+    case 0x001D:
+    case 0x001E:
+    case 0x0085:
+    case 0x2028:
+    case 0x2029:
+        return 1;
+    }
+    return 0;
+}
+
diff --git a/Python-2.7.5/Objects/weakrefobject.c b/Python-2.7.5/Objects/weakrefobject.c
new file mode 100644
index 0000000..871c248
--- /dev/null
+++ b/Python-2.7.5/Objects/weakrefobject.c
@@ -0,0 +1,984 @@
+#include "Python.h"
+#include "structmember.h"
+
+
+#define GET_WEAKREFS_LISTPTR(o) \
+        ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
+
+
+Py_ssize_t
+_PyWeakref_GetWeakrefCount(PyWeakReference *head)
+{
+    Py_ssize_t count = 0;
+
+    while (head != NULL) {
+        ++count;
+        head = head->wr_next;
+    }
+    return count;
+}
+
+
+static void
+init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback)
+{
+    self->hash = -1;
+    self->wr_object = ob;
+    Py_XINCREF(callback);
+    self->wr_callback = callback;
+}
+
+static PyWeakReference *
+new_weakref(PyObject *ob, PyObject *callback)
+{
+    PyWeakReference *result;
+
+    result = PyObject_GC_New(PyWeakReference, &_PyWeakref_RefType);
+    if (result) {
+        init_weakref(result, ob, callback);
+        PyObject_GC_Track(result);
+    }
+    return result;
+}
+
+
+/* This function clears the passed-in reference and removes it from the
+ * list of weak references for the referent.  This is the only code that
+ * removes an item from the doubly-linked list of weak references for an
+ * object; it is also responsible for clearing the callback slot.
+ */
+static void
+clear_weakref(PyWeakReference *self)
+{
+    PyObject *callback = self->wr_callback;
+
+    if (self->wr_object != Py_None) {
+        PyWeakReference **list = GET_WEAKREFS_LISTPTR(self->wr_object);
+
+        if (*list == self)
+            /* If 'self' is the end of the list (and thus self->wr_next == NULL)
+               then the weakref list itself (and thus the value of *list) will
+               end up being set to NULL. */
+            *list = self->wr_next;
+        self->wr_object = Py_None;
+        if (self->wr_prev != NULL)
+            self->wr_prev->wr_next = self->wr_next;
+        if (self->wr_next != NULL)
+            self->wr_next->wr_prev = self->wr_prev;
+        self->wr_prev = NULL;
+        self->wr_next = NULL;
+    }
+    if (callback != NULL) {
+        Py_DECREF(callback);
+        self->wr_callback = NULL;
+    }
+}
+
+/* Cyclic gc uses this to *just* clear the passed-in reference, leaving
+ * the callback intact and uncalled.  It must be possible to call self's
+ * tp_dealloc() after calling this, so self has to be left in a sane enough
+ * state for that to work.  We expect tp_dealloc to decref the callback
+ * then.  The reason for not letting clear_weakref() decref the callback
+ * right now is that if the callback goes away, that may in turn trigger
+ * another callback (if a weak reference to the callback exists) -- running
+ * arbitrary Python code in the middle of gc is a disaster.  The convolution
+ * here allows gc to delay triggering such callbacks until the world is in
+ * a sane state again.
+ */
+void
+_PyWeakref_ClearRef(PyWeakReference *self)
+{
+    PyObject *callback;
+
+    assert(self != NULL);
+    assert(PyWeakref_Check(self));
+    /* Preserve and restore the callback around clear_weakref. */
+    callback = self->wr_callback;
+    self->wr_callback = NULL;
+    clear_weakref(self);
+    self->wr_callback = callback;
+}
+
+static void
+weakref_dealloc(PyObject *self)
+{
+    PyObject_GC_UnTrack(self);
+    clear_weakref((PyWeakReference *) self);
+    Py_TYPE(self)->tp_free(self);
+}
+
+
+static int
+gc_traverse(PyWeakReference *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->wr_callback);
+    return 0;
+}
+
+
+static int
+gc_clear(PyWeakReference *self)
+{
+    clear_weakref(self);
+    return 0;
+}
+
+
+static PyObject *
+weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
+{
+    static char *kwlist[] = {NULL};
+
+    if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", kwlist)) {
+        PyObject *object = PyWeakref_GET_OBJECT(self);
+        Py_INCREF(object);
+        return (object);
+    }
+    return NULL;
+}
+
+
+static long
+weakref_hash(PyWeakReference *self)
+{
+    if (self->hash != -1)
+        return self->hash;
+    if (PyWeakref_GET_OBJECT(self) == Py_None) {
+        PyErr_SetString(PyExc_TypeError, "weak object has gone away");
+        return -1;
+    }
+    self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self));
+    return self->hash;
+}
+
+
+static PyObject *
+weakref_repr(PyWeakReference *self)
+{
+    char buffer[256];
+    if (PyWeakref_GET_OBJECT(self) == Py_None) {
+        PyOS_snprintf(buffer, sizeof(buffer), "<weakref at %p; dead>", self);
+    }
+    else {
+        char *name = NULL;
+        PyObject *nameobj = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self),
+                                                   "__name__");
+        if (nameobj == NULL)
+                PyErr_Clear();
+        else if (PyString_Check(nameobj))
+                name = PyString_AS_STRING(nameobj);
+        if (name != NULL) {
+            PyOS_snprintf(buffer, sizeof(buffer),
+                          "<weakref at %p; to '%.50s' at %p (%s)>",
+                          self,
+                          Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name,
+                          PyWeakref_GET_OBJECT(self),
+                          name);
+        }
+        else {
+            PyOS_snprintf(buffer, sizeof(buffer),
+                          "<weakref at %p; to '%.50s' at %p>",
+                          self,
+                          Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name,
+                          PyWeakref_GET_OBJECT(self));
+        }
+        Py_XDECREF(nameobj);
+    }
+    return PyString_FromString(buffer);
+}
+
+/* Weak references only support equality, not ordering. Two weak references
+   are equal if the underlying objects are equal. If the underlying object has
+   gone away, they are equal if they are identical. */
+
+static PyObject *
+weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
+{
+    if ((op != Py_EQ && op != Py_NE) || self->ob_type != other->ob_type) {
+        Py_INCREF(Py_NotImplemented);
+        return Py_NotImplemented;
+    }
+    if (PyWeakref_GET_OBJECT(self) == Py_None
+        || PyWeakref_GET_OBJECT(other) == Py_None) {
+        int res = (self == other);
+        if (op == Py_NE)
+            res = !res;
+        if (res)
+            Py_RETURN_TRUE;
+        else
+            Py_RETURN_FALSE;
+    }
+    return PyObject_RichCompare(PyWeakref_GET_OBJECT(self),
+                                PyWeakref_GET_OBJECT(other), op);
+}
+
+/* Given the head of an object's list of weak references, extract the
+ * two callback-less refs (ref and proxy).  Used to determine if the
+ * shared references exist and to determine the back link for newly
+ * inserted references.
+ */
+static void
+get_basic_refs(PyWeakReference *head,
+               PyWeakReference **refp, PyWeakReference **proxyp)
+{
+    *refp = NULL;
+    *proxyp = NULL;
+
+    if (head != NULL && head->wr_callback == NULL) {
+        /* We need to be careful that the "basic refs" aren't
+           subclasses of the main types.  That complicates this a
+           little. */
+        if (PyWeakref_CheckRefExact(head)) {
+            *refp = head;
+            head = head->wr_next;
+        }
+        if (head != NULL
+            && head->wr_callback == NULL
+            && PyWeakref_CheckProxy(head)) {
+            *proxyp = head;
+            /* head = head->wr_next; */
+        }
+    }
+}
+
+/* Insert 'newref' in the list after 'prev'.  Both must be non-NULL. */
+static void
+insert_after(PyWeakReference *newref, PyWeakReference *prev)
+{
+    newref->wr_prev = prev;
+    newref->wr_next = prev->wr_next;
+    if (prev->wr_next != NULL)
+        prev->wr_next->wr_prev = newref;
+    prev->wr_next = newref;
+}
+
+/* Insert 'newref' at the head of the list; 'list' points to the variable
+ * that stores the head.
+ */
+static void
+insert_head(PyWeakReference *newref, PyWeakReference **list)
+{
+    PyWeakReference *next = *list;
+
+    newref->wr_prev = NULL;
+    newref->wr_next = next;
+    if (next != NULL)
+        next->wr_prev = newref;
+    *list = newref;
+}
+
+static int
+parse_weakref_init_args(char *funcname, PyObject *args, PyObject *kwargs,
+                        PyObject **obp, PyObject **callbackp)
+{
+    /* XXX Should check that kwargs == NULL or is empty. */
+    return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp);
+}
+
+static PyObject *
+weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyWeakReference *self = NULL;
+    PyObject *ob, *callback = NULL;
+
+    if (parse_weakref_init_args("__new__", args, kwargs, &ob, &callback)) {
+        PyWeakReference *ref, *proxy;
+        PyWeakReference **list;
+
+        if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
+            PyErr_Format(PyExc_TypeError,
+                         "cannot create weak reference to '%s' object",
+                         Py_TYPE(ob)->tp_name);
+            return NULL;
+        }
+        if (callback == Py_None)
+            callback = NULL;
+        list = GET_WEAKREFS_LISTPTR(ob);
+        get_basic_refs(*list, &ref, &proxy);
+        if (callback == NULL && type == &_PyWeakref_RefType) {
+            if (ref != NULL) {
+                /* We can re-use an existing reference. */
+                Py_INCREF(ref);
+                return (PyObject *)ref;
+            }
+        }
+        /* We have to create a new reference. */
+        /* Note: the tp_alloc() can trigger cyclic GC, so the weakref
+           list on ob can be mutated.  This means that the ref and
+           proxy pointers we got back earlier may have been collected,
+           so we need to compute these values again before we use
+           them. */
+        self = (PyWeakReference *) (type->tp_alloc(type, 0));
+        if (self != NULL) {
+            init_weakref(self, ob, callback);
+            if (callback == NULL && type == &_PyWeakref_RefType) {
+                insert_head(self, list);
+            }
+            else {
+                PyWeakReference *prev;
+
+                get_basic_refs(*list, &ref, &proxy);
+                prev = (proxy == NULL) ? ref : proxy;
+                if (prev == NULL)
+                    insert_head(self, list);
+                else
+                    insert_after(self, prev);
+            }
+        }
+    }
+    return (PyObject *)self;
+}
+
+static int
+weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    PyObject *tmp;
+
+    if (parse_weakref_init_args("__init__", args, kwargs, &tmp, &tmp))
+        return 0;
+    else
+        return -1;
+}
+
+
+PyTypeObject
+_PyWeakref_RefType = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "weakref",
+    sizeof(PyWeakReference),
+    0,
+    weakref_dealloc,            /*tp_dealloc*/
+    0,                          /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /*tp_compare*/
+    (reprfunc)weakref_repr,     /*tp_repr*/
+    0,                          /*tp_as_number*/
+    0,                          /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    (hashfunc)weakref_hash,     /*tp_hash*/
+    (ternaryfunc)weakref_call,  /*tp_call*/
+    0,                          /*tp_str*/
+    0,                          /*tp_getattro*/
+    0,                          /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_RICHCOMPARE
+        | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
+    0,                          /*tp_doc*/
+    (traverseproc)gc_traverse,  /*tp_traverse*/
+    (inquiry)gc_clear,          /*tp_clear*/
+    (richcmpfunc)weakref_richcompare,   /*tp_richcompare*/
+    0,                          /*tp_weaklistoffset*/
+    0,                          /*tp_iter*/
+    0,                          /*tp_iternext*/
+    0,                          /*tp_methods*/
+    0,                          /*tp_members*/
+    0,                          /*tp_getset*/
+    0,                          /*tp_base*/
+    0,                          /*tp_dict*/
+    0,                          /*tp_descr_get*/
+    0,                          /*tp_descr_set*/
+    0,                          /*tp_dictoffset*/
+    weakref___init__,           /*tp_init*/
+    PyType_GenericAlloc,        /*tp_alloc*/
+    weakref___new__,            /*tp_new*/
+    PyObject_GC_Del,            /*tp_free*/
+};
+
+
+static int
+proxy_checkref(PyWeakReference *proxy)
+{
+    if (PyWeakref_GET_OBJECT(proxy) == Py_None) {
+        PyErr_SetString(PyExc_ReferenceError,
+                        "weakly-referenced object no longer exists");
+        return 0;
+    }
+    return 1;
+}
+
+
+/* If a parameter is a proxy, check that it is still "live" and wrap it,
+ * replacing the original value with the raw object.  Raises ReferenceError
+ * if the param is a dead proxy.
+ */
+#define UNWRAP(o) \
+        if (PyWeakref_CheckProxy(o)) { \
+            if (!proxy_checkref((PyWeakReference *)o)) \
+                return NULL; \
+            o = PyWeakref_GET_OBJECT(o); \
+        }
+
+#define UNWRAP_I(o) \
+        if (PyWeakref_CheckProxy(o)) { \
+            if (!proxy_checkref((PyWeakReference *)o)) \
+                return -1; \
+            o = PyWeakref_GET_OBJECT(o); \
+        }
+
+#define WRAP_UNARY(method, generic) \
+    static PyObject * \
+    method(PyObject *proxy) { \
+        UNWRAP(proxy); \
+        return generic(proxy); \
+    }
+
+#define WRAP_BINARY(method, generic) \
+    static PyObject * \
+    method(PyObject *x, PyObject *y) { \
+        UNWRAP(x); \
+        UNWRAP(y); \
+        return generic(x, y); \
+    }
+
+/* Note that the third arg needs to be checked for NULL since the tp_call
+ * slot can receive NULL for this arg.
+ */
+#define WRAP_TERNARY(method, generic) \
+    static PyObject * \
+    method(PyObject *proxy, PyObject *v, PyObject *w) { \
+        UNWRAP(proxy); \
+        UNWRAP(v); \
+        if (w != NULL) \
+            UNWRAP(w); \
+        return generic(proxy, v, w); \
+    }
+
+#define WRAP_METHOD(method, special) \
+    static PyObject * \
+    method(PyObject *proxy) { \
+            UNWRAP(proxy); \
+                return PyObject_CallMethod(proxy, special, ""); \
+        }
+
+
+/* direct slots */
+
+WRAP_BINARY(proxy_getattr, PyObject_GetAttr)
+WRAP_UNARY(proxy_str, PyObject_Str)
+WRAP_TERNARY(proxy_call, PyEval_CallObjectWithKeywords)
+
+static PyObject *
+proxy_repr(PyWeakReference *proxy)
+{
+    char buf[160];
+    PyOS_snprintf(buf, sizeof(buf),
+                  "<weakproxy at %p to %.100s at %p>", proxy,
+                  Py_TYPE(PyWeakref_GET_OBJECT(proxy))->tp_name,
+                  PyWeakref_GET_OBJECT(proxy));
+    return PyString_FromString(buf);
+}
+
+
+static int
+proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value);
+}
+
+static int
+proxy_compare(PyObject *proxy, PyObject *v)
+{
+    UNWRAP_I(proxy);
+    UNWRAP_I(v);
+    return PyObject_Compare(proxy, v);
+}
+
+/* number slots */
+WRAP_BINARY(proxy_add, PyNumber_Add)
+WRAP_BINARY(proxy_sub, PyNumber_Subtract)
+WRAP_BINARY(proxy_mul, PyNumber_Multiply)
+WRAP_BINARY(proxy_div, PyNumber_Divide)
+WRAP_BINARY(proxy_floor_div, PyNumber_FloorDivide)
+WRAP_BINARY(proxy_true_div, PyNumber_TrueDivide)
+WRAP_BINARY(proxy_mod, PyNumber_Remainder)
+WRAP_BINARY(proxy_divmod, PyNumber_Divmod)
+WRAP_TERNARY(proxy_pow, PyNumber_Power)
+WRAP_UNARY(proxy_neg, PyNumber_Negative)
+WRAP_UNARY(proxy_pos, PyNumber_Positive)
+WRAP_UNARY(proxy_abs, PyNumber_Absolute)
+WRAP_UNARY(proxy_invert, PyNumber_Invert)
+WRAP_BINARY(proxy_lshift, PyNumber_Lshift)
+WRAP_BINARY(proxy_rshift, PyNumber_Rshift)
+WRAP_BINARY(proxy_and, PyNumber_And)
+WRAP_BINARY(proxy_xor, PyNumber_Xor)
+WRAP_BINARY(proxy_or, PyNumber_Or)
+WRAP_UNARY(proxy_int, PyNumber_Int)
+WRAP_UNARY(proxy_long, PyNumber_Long)
+WRAP_UNARY(proxy_float, PyNumber_Float)
+WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd)
+WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract)
+WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply)
+WRAP_BINARY(proxy_idiv, PyNumber_InPlaceDivide)
+WRAP_BINARY(proxy_ifloor_div, PyNumber_InPlaceFloorDivide)
+WRAP_BINARY(proxy_itrue_div, PyNumber_InPlaceTrueDivide)
+WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder)
+WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower)
+WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift)
+WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift)
+WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd)
+WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)
+WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
+WRAP_UNARY(proxy_index, PyNumber_Index)
+
+static int
+proxy_nonzero(PyWeakReference *proxy)
+{
+    PyObject *o = PyWeakref_GET_OBJECT(proxy);
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PyObject_IsTrue(o);
+}
+
+static void
+proxy_dealloc(PyWeakReference *self)
+{
+    if (self->wr_callback != NULL)
+        PyObject_GC_UnTrack((PyObject *)self);
+    clear_weakref(self);
+    PyObject_GC_Del(self);
+}
+
+/* sequence slots */
+
+static PyObject *
+proxy_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j)
+{
+    if (!proxy_checkref(proxy))
+        return NULL;
+    return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j);
+}
+
+static int
+proxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);
+}
+
+static int
+proxy_contains(PyWeakReference *proxy, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value);
+}
+
+
+/* mapping slots */
+
+static Py_ssize_t
+proxy_length(PyWeakReference *proxy)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+    return PyObject_Length(PyWeakref_GET_OBJECT(proxy));
+}
+
+WRAP_BINARY(proxy_getitem, PyObject_GetItem)
+
+static int
+proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value)
+{
+    if (!proxy_checkref(proxy))
+        return -1;
+
+    if (value == NULL)
+        return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key);
+    else
+        return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value);
+}
+
+/* iterator slots */
+
+static PyObject *
+proxy_iter(PyWeakReference *proxy)
+{
+    if (!proxy_checkref(proxy))
+        return NULL;
+    return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy));
+}
+
+static PyObject *
+proxy_iternext(PyWeakReference *proxy)
+{
+    if (!proxy_checkref(proxy))
+        return NULL;
+    return PyIter_Next(PyWeakref_GET_OBJECT(proxy));
+}
+
+
+WRAP_METHOD(proxy_unicode, "__unicode__");
+
+
+static PyMethodDef proxy_methods[] = {
+        {"__unicode__", (PyCFunction)proxy_unicode, METH_NOARGS},
+        {NULL, NULL}
+};
+
+
+static PyNumberMethods proxy_as_number = {
+    proxy_add,              /*nb_add*/
+    proxy_sub,              /*nb_subtract*/
+    proxy_mul,              /*nb_multiply*/
+    proxy_div,              /*nb_divide*/
+    proxy_mod,              /*nb_remainder*/
+    proxy_divmod,           /*nb_divmod*/
+    proxy_pow,              /*nb_power*/
+    proxy_neg,              /*nb_negative*/
+    proxy_pos,              /*nb_positive*/
+    proxy_abs,              /*nb_absolute*/
+    (inquiry)proxy_nonzero, /*nb_nonzero*/
+    proxy_invert,           /*nb_invert*/
+    proxy_lshift,           /*nb_lshift*/
+    proxy_rshift,           /*nb_rshift*/
+    proxy_and,              /*nb_and*/
+    proxy_xor,              /*nb_xor*/
+    proxy_or,               /*nb_or*/
+    0,                      /*nb_coerce*/
+    proxy_int,              /*nb_int*/
+    proxy_long,             /*nb_long*/
+    proxy_float,            /*nb_float*/
+    0,                      /*nb_oct*/
+    0,                      /*nb_hex*/
+    proxy_iadd,             /*nb_inplace_add*/
+    proxy_isub,             /*nb_inplace_subtract*/
+    proxy_imul,             /*nb_inplace_multiply*/
+    proxy_idiv,             /*nb_inplace_divide*/
+    proxy_imod,             /*nb_inplace_remainder*/
+    proxy_ipow,             /*nb_inplace_power*/
+    proxy_ilshift,          /*nb_inplace_lshift*/
+    proxy_irshift,          /*nb_inplace_rshift*/
+    proxy_iand,             /*nb_inplace_and*/
+    proxy_ixor,             /*nb_inplace_xor*/
+    proxy_ior,              /*nb_inplace_or*/
+    proxy_floor_div,        /*nb_floor_divide*/
+    proxy_true_div,         /*nb_true_divide*/
+    proxy_ifloor_div,       /*nb_inplace_floor_divide*/
+    proxy_itrue_div,        /*nb_inplace_true_divide*/
+    proxy_index,            /*nb_index*/
+};
+
+static PySequenceMethods proxy_as_sequence = {
+    (lenfunc)proxy_length,      /*sq_length*/
+    0,                          /*sq_concat*/
+    0,                          /*sq_repeat*/
+    0,                          /*sq_item*/
+    (ssizessizeargfunc)proxy_slice, /*sq_slice*/
+    0,                          /*sq_ass_item*/
+    (ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/
+    (objobjproc)proxy_contains, /* sq_contains */
+};
+
+static PyMappingMethods proxy_as_mapping = {
+    (lenfunc)proxy_length,        /*mp_length*/
+    proxy_getitem,                /*mp_subscript*/
+    (objobjargproc)proxy_setitem, /*mp_ass_subscript*/
+};
+
+
+PyTypeObject
+_PyWeakref_ProxyType = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "weakproxy",
+    sizeof(PyWeakReference),
+    0,
+    /* methods */
+    (destructor)proxy_dealloc,          /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    proxy_compare,                      /* tp_compare */
+    (reprfunc)proxy_repr,               /* tp_repr */
+    &proxy_as_number,                   /* tp_as_number */
+    &proxy_as_sequence,                 /* tp_as_sequence */
+    &proxy_as_mapping,                  /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    0,                                  /* tp_call */
+    proxy_str,                          /* tp_str */
+    proxy_getattr,                      /* tp_getattro */
+    (setattrofunc)proxy_setattr,        /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+    | Py_TPFLAGS_CHECKTYPES,            /* tp_flags */
+    0,                                  /* tp_doc */
+    (traverseproc)gc_traverse,          /* tp_traverse */
+    (inquiry)gc_clear,                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    (getiterfunc)proxy_iter,            /* tp_iter */
+    (iternextfunc)proxy_iternext,       /* tp_iternext */
+        proxy_methods,                      /* tp_methods */
+};
+
+
+PyTypeObject
+_PyWeakref_CallableProxyType = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "weakcallableproxy",
+    sizeof(PyWeakReference),
+    0,
+    /* methods */
+    (destructor)proxy_dealloc,          /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    proxy_compare,                      /* tp_compare */
+    (unaryfunc)proxy_repr,              /* tp_repr */
+    &proxy_as_number,                   /* tp_as_number */
+    &proxy_as_sequence,                 /* tp_as_sequence */
+    &proxy_as_mapping,                  /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    proxy_call,                         /* tp_call */
+    proxy_str,                          /* tp_str */
+    proxy_getattr,                      /* tp_getattro */
+    (setattrofunc)proxy_setattr,        /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+    | Py_TPFLAGS_CHECKTYPES,            /* tp_flags */
+    0,                                  /* tp_doc */
+    (traverseproc)gc_traverse,          /* tp_traverse */
+    (inquiry)gc_clear,                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    (getiterfunc)proxy_iter,            /* tp_iter */
+    (iternextfunc)proxy_iternext,       /* tp_iternext */
+};
+
+
+
+PyObject *
+PyWeakref_NewRef(PyObject *ob, PyObject *callback)
+{
+    PyWeakReference *result = NULL;
+    PyWeakReference **list;
+    PyWeakReference *ref, *proxy;
+
+    if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
+        PyErr_Format(PyExc_TypeError,
+                     "cannot create weak reference to '%s' object",
+                     Py_TYPE(ob)->tp_name);
+        return NULL;
+    }
+    list = GET_WEAKREFS_LISTPTR(ob);
+    get_basic_refs(*list, &ref, &proxy);
+    if (callback == Py_None)
+        callback = NULL;
+    if (callback == NULL)
+        /* return existing weak reference if it exists */
+        result = ref;
+    if (result != NULL)
+        Py_INCREF(result);
+    else {
+        /* Note: new_weakref() can trigger cyclic GC, so the weakref
+           list on ob can be mutated.  This means that the ref and
+           proxy pointers we got back earlier may have been collected,
+           so we need to compute these values again before we use
+           them. */
+        result = new_weakref(ob, callback);
+        if (result != NULL) {
+            get_basic_refs(*list, &ref, &proxy);
+            if (callback == NULL) {
+                if (ref == NULL)
+                    insert_head(result, list);
+                else {
+                    /* Someone else added a ref without a callback
+                       during GC.  Return that one instead of this one
+                       to avoid violating the invariants of the list
+                       of weakrefs for ob. */
+                    Py_DECREF(result);
+                    Py_INCREF(ref);
+                    result = ref;
+                }
+            }
+            else {
+                PyWeakReference *prev;
+
+                prev = (proxy == NULL) ? ref : proxy;
+                if (prev == NULL)
+                    insert_head(result, list);
+                else
+                    insert_after(result, prev);
+            }
+        }
+    }
+    return (PyObject *) result;
+}
+
+
+PyObject *
+PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
+{
+    PyWeakReference *result = NULL;
+    PyWeakReference **list;
+    PyWeakReference *ref, *proxy;
+
+    if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
+        PyErr_Format(PyExc_TypeError,
+                     "cannot create weak reference to '%s' object",
+                     Py_TYPE(ob)->tp_name);
+        return NULL;
+    }
+    list = GET_WEAKREFS_LISTPTR(ob);
+    get_basic_refs(*list, &ref, &proxy);
+    if (callback == Py_None)
+        callback = NULL;
+    if (callback == NULL)
+        /* attempt to return an existing weak reference if it exists */
+        result = proxy;
+    if (result != NULL)
+        Py_INCREF(result);
+    else {
+        /* Note: new_weakref() can trigger cyclic GC, so the weakref
+           list on ob can be mutated.  This means that the ref and
+           proxy pointers we got back earlier may have been collected,
+           so we need to compute these values again before we use
+           them. */
+        result = new_weakref(ob, callback);
+        if (result != NULL) {
+            PyWeakReference *prev;
+
+            if (PyCallable_Check(ob))
+                Py_TYPE(result) = &_PyWeakref_CallableProxyType;
+            else
+                Py_TYPE(result) = &_PyWeakref_ProxyType;
+            get_basic_refs(*list, &ref, &proxy);
+            if (callback == NULL) {
+                if (proxy != NULL) {
+                    /* Someone else added a proxy without a callback
+                       during GC.  Return that one instead of this one
+                       to avoid violating the invariants of the list
+                       of weakrefs for ob. */
+                    Py_DECREF(result);
+                    Py_INCREF(result = proxy);
+                    goto skip_insert;
+                }
+                prev = ref;
+            }
+            else
+                prev = (proxy == NULL) ? ref : proxy;
+
+            if (prev == NULL)
+                insert_head(result, list);
+            else
+                insert_after(result, prev);
+        skip_insert:
+            ;
+        }
+    }
+    return (PyObject *) result;
+}
+
+
+PyObject *
+PyWeakref_GetObject(PyObject *ref)
+{
+    if (ref == NULL || !PyWeakref_Check(ref)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return PyWeakref_GET_OBJECT(ref);
+}
+
+/* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's
+ * handle_weakrefs().
+ */
+static void
+handle_callback(PyWeakReference *ref, PyObject *callback)
+{
+    PyObject *cbresult = PyObject_CallFunctionObjArgs(callback, ref, NULL);
+
+    if (cbresult == NULL)
+        PyErr_WriteUnraisable(callback);
+    else
+        Py_DECREF(cbresult);
+}
+
+/* This function is called by the tp_dealloc handler to clear weak references.
+ *
+ * This iterates through the weak references for 'object' and calls callbacks
+ * for those references which have one.  It returns when all callbacks have
+ * been attempted.
+ */
+void
+PyObject_ClearWeakRefs(PyObject *object)
+{
+    PyWeakReference **list;
+
+    if (object == NULL
+        || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
+        || object->ob_refcnt != 0) {
+        PyErr_BadInternalCall();
+        return;
+    }
+    list = GET_WEAKREFS_LISTPTR(object);
+    /* Remove the callback-less basic and proxy references */
+    if (*list != NULL && (*list)->wr_callback == NULL) {
+        clear_weakref(*list);
+        if (*list != NULL && (*list)->wr_callback == NULL)
+            clear_weakref(*list);
+    }
+    if (*list != NULL) {
+        PyWeakReference *current = *list;
+        Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
+        int restore_error = PyErr_Occurred() ? 1 : 0;
+        PyObject *err_type, *err_value, *err_tb;
+
+        if (restore_error)
+            PyErr_Fetch(&err_type, &err_value, &err_tb);
+        if (count == 1) {
+            PyObject *callback = current->wr_callback;
+
+            current->wr_callback = NULL;
+            clear_weakref(current);
+            if (callback != NULL) {
+                if (current->ob_refcnt > 0)
+                    handle_callback(current, callback);
+                Py_DECREF(callback);
+            }
+        }
+        else {
+            PyObject *tuple;
+            Py_ssize_t i = 0;
+
+            tuple = PyTuple_New(count * 2);
+            if (tuple == NULL) {
+                if (restore_error)
+                    PyErr_Fetch(&err_type, &err_value, &err_tb);
+                return;
+            }
+
+            for (i = 0; i < count; ++i) {
+                PyWeakReference *next = current->wr_next;
+
+                if (current->ob_refcnt > 0)
+                {
+                    Py_INCREF(current);
+                    PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
+                    PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+                }
+                else {
+                    Py_DECREF(current->wr_callback);
+                }
+                current->wr_callback = NULL;
+                clear_weakref(current);
+                current = next;
+            }
+            for (i = 0; i < count; ++i) {
+                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
+
+                /* The tuple may have slots left to NULL */
+                if (callback != NULL) {
+                    PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
+                    handle_callback((PyWeakReference *)item, callback);
+                }
+            }
+            Py_DECREF(tuple);
+        }
+        if (restore_error)
+            PyErr_Restore(err_type, err_value, err_tb);
+    }
+}