diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 6e5df19..0f4d4c3 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -1,2149 +1,1370 @@
-/* PyBytes (bytearray) implementation */
+/* String object implementation */
 
 #define PY_SSIZE_T_CLEAN
+
 #include "Python.h"
-#include "structmember.h"
-#include "bytes_methods.h"
 
-static PyByteArrayObject *nullbytes = NULL;
+#include "formatter_string.h"
 
-void
-PyByteArray_Fini(void)
+#include <ctype.h>
+
+#ifdef COUNT_ALLOCS
+int null_strings, one_strings;
+#endif
+
+static PyBytesObject *characters[UCHAR_MAX + 1];
+static PyBytesObject *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;
+
+/*
+   For both PyBytes_FromString() and PyBytes_FromStringAndSize(), the
+   parameter `size' denotes number of characters to allocate, not counting any
+   null terminating character.
+
+   For PyBytes_FromString(), the parameter `str' points to a null-terminated
+   string containing exactly `size' bytes.
+
+   For PyBytes_FromStringAndSize(), the parameter the parameter `str' is
+   either NULL or else points to a string containing at least `size' bytes.
+   For PyBytes_FromStringAndSize(), the string in the `str' parameter does
+   not have to be null-terminated.  (Therefore it is safe to construct a
+   substring by calling `PyBytes_FromStringAndSize(origstring, substrlen)'.)
+   If `str' is NULL then PyBytes_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 equal to the `size' parameter (for
+   PyBytes_FromStringAndSize()) or the length of the string in the `str'
+   parameter (for PyBytes_FromString()).
+*/
+PyObject *
+PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
 {
-    Py_CLEAR(nullbytes);
+	register PyBytesObject *op;
+	if (size < 0) {
+		PyErr_SetString(PyExc_SystemError,
+		    "Negative size passed to PyBytes_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;
+	}
+
+	/* Inline PyObject_NewVar */
+	op = (PyBytesObject *)PyObject_MALLOC(sizeof(PyBytesObject) + size);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyBytes_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;
+		PyBytes_InternInPlace(&t);
+		op = (PyBytesObject *)t;
+		nullstring = op;
+		Py_INCREF(op);
+	} else if (size == 1 && str != NULL) {
+		PyObject *t = (PyObject *)op;
+		PyBytes_InternInPlace(&t);
+		op = (PyBytesObject *)t;
+		characters[*str & UCHAR_MAX] = op;
+		Py_INCREF(op);
+	}
+	return (PyObject *) op;
 }
 
-int
-PyByteArray_Init(void)
+PyObject *
+PyBytes_FromString(const char *str)
 {
-    nullbytes = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
-    if (nullbytes == NULL)
-        return 0;
-    nullbytes->ob_bytes = NULL;
-    Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0;
-    nullbytes->ob_exports = 0;
-    return 1;
+	register size_t size;
+	register PyBytesObject *op;
+
+	assert(str != NULL);
+	size = strlen(str);
+	if (size > PY_SSIZE_T_MAX) {
+		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 = (PyBytesObject *)PyObject_MALLOC(sizeof(PyBytesObject) + size);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyBytes_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;
+		PyBytes_InternInPlace(&t);
+		op = (PyBytesObject *)t;
+		nullstring = op;
+		Py_INCREF(op);
+	} else if (size == 1) {
+		PyObject *t = (PyObject *)op;
+		PyBytes_InternInPlace(&t);
+		op = (PyBytesObject *)t;
+		characters[*str & UCHAR_MAX] = op;
+		Py_INCREF(op);
+	}
+	return (PyObject *) op;
 }
 
-/* end nullbytes support */
-
-/* Helpers */
-
-static int
-_getbytevalue(PyObject* arg, int *value)
+PyObject *
+PyBytes_FromFormatV(const char *format, va_list vargs)
 {
-    long face_value;
+	va_list count;
+	Py_ssize_t n = 0;
+	const char* f;
+	char *s;
+	PyObject* string;
 
-    if (PyInt_Check(arg)) {
-        face_value = PyInt_AsLong(arg);
-        if (face_value < 0 || face_value >= 256) {
-            PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
-            return 0;
-        }
-    }
-    else if (PyBytes_CheckExact(arg)) {
-        if (Py_SIZE(arg) != 1) {
-            PyErr_SetString(PyExc_ValueError, "string must be of size 1");
-            return 0;
-        }
-        face_value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
-    }
-    else {
-        PyErr_Format(PyExc_TypeError, "an integer or string of size 1 is required");
-        return 0;
+#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 == '%') {
+			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' || *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. */
+				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 = PyBytes_FromStringAndSize(NULL, n);
+	if (!string)
+		return NULL;
+
+	s = PyBytes_AsString(string);
+
+	for (f = format; *f; f++) {
+		if (*f == '%') {
+			const char* p = f++;
+			Py_ssize_t i;
+			int longflag = 0;
+			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 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':
+				if (longflag)
+					sprintf(s, "%ld", va_arg(vargs, long));
+				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));
+				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:
+	_PyBytes_Resize(&string, s - PyBytes_AS_STRING(string));
+	return string;
+}
+
+PyObject *
+PyBytes_FromFormat(const char *format, ...)
+{
+	PyObject* ret;
+	va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+	va_start(vargs, format);
+#else
+	va_start(vargs);
+#endif
+	ret = PyBytes_FromFormatV(format, vargs);
+	va_end(vargs);
+	return ret;
+}
+
+
+PyObject *PyBytes_Decode(const char *s,
+			  Py_ssize_t size,
+			  const char *encoding,
+			  const char *errors)
+{
+    PyObject *v, *str;
+
+    str = PyBytes_FromStringAndSize(s, size);
+    if (str == NULL)
+	return NULL;
+    v = PyBytes_AsDecodedString(str, encoding, errors);
+    Py_DECREF(str);
+    return v;
+}
+
+PyObject *PyBytes_AsDecodedObject(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    if (!PyBytes_Check(str)) {
+        PyErr_BadArgument();
+        goto onError;
     }
 
-    *value = face_value;
-    return 1;
-}
-
-static Py_ssize_t
-bytes_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;
+    if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+	encoding = PyUnicode_GetDefaultEncoding();
+#else
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	goto onError;
+#endif
     }
-    *ptr = (void *)self->ob_bytes;
-    return Py_SIZE(self);
+
+    /* Decode via the codec registry */
+    v = PyCodec_Decode(str, encoding, errors);
+    if (v == NULL)
+        goto onError;
+
+    return v;
+
+ onError:
+    return NULL;
 }
 
-static Py_ssize_t
-bytes_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+PyObject *PyBytes_AsDecodedString(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
 {
-    if ( index != 0 ) {
-        PyErr_SetString(PyExc_SystemError,
-                "accessing non-existent bytes segment");
-        return -1;
+    PyObject *v;
+
+    v = PyBytes_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;
     }
-    *ptr = (void *)self->ob_bytes;
-    return Py_SIZE(self);
-}
-
-static Py_ssize_t
-bytes_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
-{
-    if ( lenp )
-        *lenp = Py_SIZE(self);
-    return 1;
-}
-
-static Py_ssize_t
-bytes_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;
+#endif
+    if (!PyBytes_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;
     }
-    *ptr = self->ob_bytes;
-    return Py_SIZE(self);
+
+    return v;
+
+ onError:
+    return NULL;
 }
 
-static int
-bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
+PyObject *PyBytes_Encode(const char *s,
+			  Py_ssize_t size,
+			  const char *encoding,
+			  const char *errors)
 {
-        int ret;
-        void *ptr;
-        if (view == NULL) {
-                obj->ob_exports++;
-                return 0;
-        }
-        if (obj->ob_bytes == NULL)
-                ptr = "";
-        else
-                ptr = obj->ob_bytes;
-        ret = PyBuffer_FillInfo(view, ptr, Py_SIZE(obj), 0, flags);
-        if (ret >= 0) {
-                obj->ob_exports++;
-        }
-        return ret;
+    PyObject *v, *str;
+
+    str = PyBytes_FromStringAndSize(s, size);
+    if (str == NULL)
+	return NULL;
+    v = PyBytes_AsEncodedString(str, encoding, errors);
+    Py_DECREF(str);
+    return v;
+}
+
+PyObject *PyBytes_AsEncodedObject(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    if (!PyBytes_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 *PyBytes_AsEncodedString(PyObject *str,
+				   const char *encoding,
+				   const char *errors)
+{
+    PyObject *v;
+
+    v = PyBytes_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 (!PyBytes_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
-bytes_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
+string_dealloc(PyObject *op)
 {
-        obj->ob_exports--;
+	switch (PyBytes_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 *PyBytes_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 = PyBytes_FromStringAndSize((char *)NULL, newlen);
+	if (v == NULL)
+		return NULL;
+	p = buf = PyBytes_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(PyBytes_Check(w));
+				r = PyBytes_AS_STRING(w);
+				rn = PyBytes_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;
+			}
+#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 arbitry number of unescaped
+					 UTF-8 bytes may follow. */
+		}
+	}
+	if (p-buf < newlen)
+		_PyBytes_Resize(&v, p - buf);
+	return v;
+  failed:
+	Py_DECREF(v);
+	return NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* object api */
+
 static Py_ssize_t
-_getbuffer(PyObject *obj, Py_buffer *view)
+string_getsize(register PyObject *op)
 {
-    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;
+    	char *s;
+    	Py_ssize_t len;
+	if (PyBytes_AsStringAndSize(op, &s, &len))
+		return -1;
+	return len;
 }
 
-/* Direct API functions */
-
-PyObject *
-PyByteArray_FromObject(PyObject *input)
+static /*const*/ char *
+string_getbuffer(register PyObject *op)
 {
-    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)
-            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;
+    	char *s;
+    	Py_ssize_t len;
+	if (PyBytes_AsStringAndSize(op, &s, &len))
+		return NULL;
+	return s;
 }
 
 Py_ssize_t
-PyByteArray_Size(PyObject *self)
+PyBytes_Size(register PyObject *op)
 {
-    assert(self != NULL);
-    assert(PyByteArray_Check(self));
-
-    return PyByteArray_GET_SIZE(self);
+	if (!PyBytes_Check(op))
+		return string_getsize(op);
+	return Py_SIZE(op);
 }
 
-char  *
-PyByteArray_AsString(PyObject *self)
+/*const*/ char *
+PyBytes_AsString(register PyObject *op)
 {
-    assert(self != NULL);
-    assert(PyByteArray_Check(self));
-
-    return PyByteArray_AS_STRING(self);
+	if (!PyBytes_Check(op))
+		return string_getbuffer(op);
+	return ((PyBytesObject *)op) -> ob_sval;
 }
 
 int
-PyByteArray_Resize(PyObject *self, Py_ssize_t size)
+PyBytes_AsStringAndSize(register PyObject *obj,
+			 register char **s,
+			 register Py_ssize_t *len)
 {
-    void *sval;
-    Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
+	if (s == NULL) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
 
-    assert(self != NULL);
-    assert(PyByteArray_Check(self));
-    assert(size >= 0);
-
-    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;
-    }
-
-    if (((PyByteArrayObject *)self)->ob_exports > 0) {
-            /*
-            fprintf(stderr, "%d: %s", ((PyByteArrayObject *)self)->ob_exports,
-                    ((PyByteArrayObject *)self)->ob_bytes);
-            */
-            PyErr_SetString(PyExc_BufferError,
-                    "Existing exports of data: object cannot be re-sized");
-            return -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) {
-            return 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)
-        PyObject_ReleaseBuffer(a, &va);
-    if (vb.len != -1)
-        PyObject_ReleaseBuffer(b, &vb);
-    return (PyObject *)result;
-}
-
-/* Functions stuffed into the type object */
-
-static Py_ssize_t
-bytes_length(PyByteArrayObject *self)
-{
-    return Py_SIZE(self);
-}
-
-static PyObject *
-bytes_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) {
-        PyObject_ReleaseBuffer(other, &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) {
-        PyObject_ReleaseBuffer(other, &vo);
-        return NULL;
-    }
-    memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
-    PyObject_ReleaseBuffer(other, &vo);
-    Py_INCREF(self);
-    return (PyObject *)self;
-}
-
-static PyObject *
-bytes_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 *
-bytes_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 *
-bytes_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 *
-bytes_subscript(PyByteArrayObject *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 += 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(item)) {
-        Py_ssize_t start, stop, step, slicelength, cur, i;
-        if (PySlice_GetIndicesEx((PySliceObject *)item,
-                                 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
-bytes_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 = bytes_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 bytes 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) {
-            /*
-              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)
-            PyObject_ReleaseBuffer(values, &vbytes);
-    return res;
-}
-
-static int
-bytes_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 bytes_setslice(self, i, i+1, NULL);
-
-    if (!_getbytevalue(value, &ival))
-        return -1;
-
-    self->ob_bytes[i] = ival;
-    return 0;
-}
-
-static int
-bytes_ass_subscript(PyByteArrayObject *self, PyObject *item, PyObject *values)
-{
-    Py_ssize_t start, stop, step, slicelen, needed;
-    char *bytes;
-
-    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 += 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 {
-            Py_ssize_t ival = PyNumber_AsSsize_t(values, PyExc_ValueError);
-            if (ival == -1 && PyErr_Occurred()) {
-                int int_value;
-                /* Also accept str of size 1 in 2.x */
-                PyErr_Clear();
-                if (!_getbytevalue(values, &int_value))
-                    return -1;
-                ival = (int) int_value;
-            } else if (ival < 0 || ival >= 256) {
-                PyErr_SetString(PyExc_ValueError,
-                                "byte must be in range(0, 256)");
-                return -1;
-            }
-            self->ob_bytes[i] = (char)ival;
-            return 0;
-        }
-    }
-    else if (PySlice_Check(item)) {
-        if (PySlice_GetIndicesEx((PySliceObject *)item,
-                                 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)) {
-        /* Make a copy an call this function recursively */
-        int err;
-        values = PyByteArray_FromObject(values);
-        if (values == NULL)
-            return -1;
-        err = bytes_ass_subscript(self, item, 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 (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 */
-            Py_ssize_t cur, i;
-
-            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 >= 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 < 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
-bytes_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:bytes", 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 = bytes_iconcat(self, arg);
-        Py_DECREF(encoded);
-        if (new == NULL)
-            return -1;
-        Py_DECREF(new);
-        return 0;
-    }
-
-    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 = bytes_iconcat(self, encoded);
-        Py_DECREF(encoded);
-        if (new == NULL)
-            return -1;
-        Py_DECREF(new);
-        return 0;
-    }
-
-    /* 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_ValueError);
-    if (count == -1 && PyErr_Occurred())
-        PyErr_Clear();
-    else {
-        if (count < 0) {
-            PyErr_SetString(PyExc_ValueError, "negative count");
-            return -1;
-        }
-        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;
-        PyObject_ReleaseBuffer(arg, &view);
-        return 0;
-    fail:
-        PyObject_ReleaseBuffer(arg, &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;
-        Py_ssize_t 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__) */
-        value = PyNumber_AsSsize_t(item, PyExc_ValueError);
-        Py_DECREF(item);
-        if (value == -1 && PyErr_Occurred())
-            goto error;
-
-        /* Range check */
-        if (value < 0 || value >= 256) {
-            PyErr_SetString(PyExc_ValueError,
-                            "bytes must be in range(0, 256)");
-            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 *
-bytes_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 = 14 + 4 * length;
-    PyObject *v;
-    if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) {
-        PyErr_SetString(PyExc_OverflowError,
-            "bytearray object is too large to make repr");
-        return NULL;
-    }
-    v = PyUnicode_FromUnicode(NULL, newsize);
-    if (v == NULL) {
-        return NULL;
-    }
-    else {
-        register Py_ssize_t i;
-        register Py_UNICODE c;
-        register Py_UNICODE *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 = PyUnicode_AS_UNICODE(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 - PyUnicode_AS_UNICODE(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 - PyUnicode_AS_UNICODE(v)) >= 1);
-        *p++ = quote;
-        while (*quote_postfix) {
-           *p++ = *quote_postfix++;
-        }
-        *p = '\0';
-        if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
-            Py_DECREF(v);
-            return NULL;
-        }
-        return v;
-    }
-}
-
-static PyObject *
-bytes_str(PyObject *op)
-{
-#if 0
-    if (Py_BytesWarningFlag) {
-        if (PyErr_WarnEx(PyExc_BytesWarning,
-                 "str() on a bytearray instance", 1))
-            return NULL;
-    }
-    return bytes_repr((PyByteArrayObject*)op);
+	if (!PyBytes_Check(obj)) {
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(obj)) {
+			obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
+			if (obj == NULL)
+				return -1;
+		}
+		else
 #endif
-    return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
+		{
+			PyErr_Format(PyExc_TypeError,
+				     "expected string or Unicode object, "
+				     "%.200s found", Py_TYPE(obj)->tp_name);
+			return -1;
+		}
+	}
+
+	*s = PyBytes_AS_STRING(obj);
+	if (len != NULL)
+		*len = PyBytes_GET_SIZE(obj);
+	else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected string without null bytes");
+		return -1;
+	}
+	return 0;
 }
 
-static PyObject *
-bytes_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. */
-    if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
-        PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
-        if (Py_BytesWarningFlag && op == Py_EQ) {
-            if (PyErr_WarnEx(PyExc_BytesWarning,
-                            "Comparsion between bytearray and string", 1))
-                return NULL;
-        }
-
-        Py_INCREF(Py_NotImplemented);
-        return Py_NotImplemented;
-    }
-
-    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();
-        PyObject_ReleaseBuffer(self, &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;
-    PyObject_ReleaseBuffer(self, &self_bytes);
-    PyObject_ReleaseBuffer(other, &other_bytes);
-    Py_INCREF(res);
-    return res;
-}
-
-static void
-bytes_dealloc(PyByteArrayObject *self)
-{
-    if (self->ob_bytes != 0) {
-        PyMem_Free(self->ob_bytes);
-    }
-    Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-
 /* -------------------------------------------------------------------- */
 /* Methods */
 
-#define STRINGLIB_CHAR char
-#define STRINGLIB_CMP memcmp
-#define STRINGLIB_LEN PyByteArray_GET_SIZE
-#define STRINGLIB_STR PyByteArray_AS_STRING
-#define STRINGLIB_NEW PyByteArray_FromStringAndSize
-#define STRINGLIB_EMPTY nullbytes
-#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
-#define STRINGLIB_MUTABLE 1
-
+#include "stringlib/stringdefs.h"
 #include "stringlib/fastsearch.h"
+
 #include "stringlib/count.h"
 #include "stringlib/find.h"
 #include "stringlib/partition.h"
-#include "stringlib/ctype.h"
-#include "stringlib/transmogrify.h"
 
+#define _Py_InsertThousandsGrouping _PyBytes_InsertThousandsGrouping
+#include "stringlib/localeutil.h"
 
-/* The following Py_LOCAL_INLINE and Py_LOCAL functions
-were copied from the old char* style string object. */
-
-Py_LOCAL_INLINE(void)
-_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t 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)
-bytes_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 (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
-        _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &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);
-    PyObject_ReleaseBuffer(subobj, &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 s[start,end].  Optional\n\
-arguments start and end are interpreted as in slice notation.\n\
-\n\
-Return -1 on failure.");
-
-static PyObject *
-bytes_find(PyByteArrayObject *self, PyObject *args)
-{
-    Py_ssize_t result = bytes_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 *
-bytes_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 (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
-        _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &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)
-        );
-    PyObject_ReleaseBuffer(sub_obj, &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 *
-bytes_index(PyByteArrayObject *self, PyObject *args)
-{
-    Py_ssize_t result = bytes_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 s[start,end].  Optional\n\
-arguments start and end are interpreted as in slice notation.\n\
-\n\
-Return -1 on failure.");
-
-static PyObject *
-bytes_rfind(PyByteArrayObject *self, PyObject *args)
-{
-    Py_ssize_t result = bytes_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 *
-bytes_rindex(PyByteArrayObject *self, PyObject *args)
-{
-    Py_ssize_t result = bytes_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
-bytes_contains(PyObject *self, PyObject *arg)
+string_print(PyBytesObject *op, FILE *fp, int flags)
 {
-    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);
-        PyObject_ReleaseBuffer(arg, &varg);
-        return pos >= 0;
-    }
-    if (ival < 0 || ival >= 256) {
-        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
-        return -1;
-    }
+	Py_ssize_t i, str_len;
+	char c;
+	int quote;
 
-    return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
+	/* XXX Ought to check for interrupts when writing long strings */
+	if (! PyBytes_CheckExact(op)) {
+		int ret;
+		/* A str subclass may have its own __str__ method. */
+		op = (PyBytesObject *) 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;
 }
 
-
-/* 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)
-_bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
-                 Py_ssize_t end, int direction)
+PyObject *
+PyBytes_Repr(PyObject *obj, int smartquotes)
 {
-    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:
-    PyObject_ReleaseBuffer(substr, &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 *
-bytes_startswith(PyByteArrayObject *self, PyObject *args)
-{
-    Py_ssize_t start = 0;
-    Py_ssize_t end = PY_SSIZE_T_MAX;
-    PyObject *subobj;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
-        _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
-        return NULL;
-    if (PyTuple_Check(subobj)) {
-        Py_ssize_t i;
-        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
-            result = _bytes_tailmatch(self,
-                                      PyTuple_GET_ITEM(subobj, i),
-                                      start, end, -1);
-            if (result == -1)
+	register PyBytesObject* op = (PyBytesObject*) 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;
-            else if (result) {
-                Py_RETURN_TRUE;
-            }
-        }
-        Py_RETURN_FALSE;
-    }
-    result = _bytes_tailmatch(self, subobj, start, end, -1);
-    if (result == -1)
-        return NULL;
-    else
-        return PyBool_FromLong(result);
-}
+	}
+	v = PyBytes_FromStringAndSize((char *)NULL, newsize);
+	if (v == NULL) {
+		return NULL;
+	}
+	else {
+		register Py_ssize_t i;
+		register char c;
+		register char *p;
+		int quote;
 
-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.");
+		/* 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 = PyBytes_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 - PyBytes_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 - PyBytes_AS_STRING(v)) >= 1);
+		*p++ = quote;
+		*p = '\0';
+		_PyBytes_Resize(
+			&v, (p - PyBytes_AS_STRING(v)));
+		return v;
+	}
+}
 
 static PyObject *
-bytes_endswith(PyByteArrayObject *self, PyObject *args)
+string_repr(PyObject *op)
 {
-    Py_ssize_t start = 0;
-    Py_ssize_t end = PY_SSIZE_T_MAX;
-    PyObject *subobj;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
-        _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
-        return NULL;
-    if (PyTuple_Check(subobj)) {
-        Py_ssize_t i;
-        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
-            result = _bytes_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 = _bytes_tailmatch(self, subobj, start, end, +1);
-    if (result == -1)
-        return NULL;
-    else
-        return PyBool_FromLong(result);
+	return PyBytes_Repr(op, 1);
 }
 
-
-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 *
-bytes_translate(PyByteArrayObject *self, PyObject *args)
+string_str(PyObject *s)
 {
-    register char *input, *output;
-    register const char *table;
-    register Py_ssize_t i, c, changed = 0;
-    PyObject *input_obj = (PyObject*)self;
-    const char *output_start;
-    Py_ssize_t inlen;
-    PyObject *result;
-    int trans_table[256];
-    PyObject *tableobj, *delobj = NULL;
-    Py_buffer vtable, vdel;
-
-    if (!PyArg_UnpackTuple(args, "translate", 1, 2,
-                           &tableobj, &delobj))
-          return NULL;
-
-    if (_getbuffer(tableobj, &vtable) < 0)
-        return NULL;
-
-    if (vtable.len != 256) {
-        PyErr_SetString(PyExc_ValueError,
-                        "translation table must be 256 characters long");
-        result = NULL;
-        goto done;
-    }
-
-    if (delobj != NULL) {
-        if (_getbuffer(delobj, &vdel) < 0) {
-            result = NULL;
-            goto done;
-        }
-    }
-    else {
-        vdel.buf = NULL;
-        vdel.len = 0;
-    }
-
-    table = (const char *)vtable.buf;
-    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) {
-        /* 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 || !PyByteArray_CheckExact(input_obj))
-            goto done;
-        Py_DECREF(result);
-        Py_INCREF(input_obj);
-        result = input_obj;
-        goto done;
-    }
-
-    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;
-        changed = 1;
-    }
-    if (!changed && PyByteArray_CheckExact(input_obj)) {
-        Py_DECREF(result);
-        Py_INCREF(input_obj);
-        result = input_obj;
-        goto done;
-    }
-    /* Fix the size of the resulting string */
-    if (inlen > 0)
-        PyByteArray_Resize(result, output - output_start);
-
-done:
-    PyObject_ReleaseBuffer(tableobj, &vtable);
-    if (delobj != NULL)
-        PyObject_ReleaseBuffer(delobj, &vdel);
-    return result;
+	assert(PyBytes_Check(s));
+	if (PyBytes_CheckExact(s)) {
+		Py_INCREF(s);
+		return s;
+	}
+	else {
+		/* Subtype -- return genuine string with the same value. */
+		PyBytesObject *t = (PyBytesObject *) s;
+		return PyBytes_FromStringAndSize(t->ob_sval, Py_SIZE(t));
+	}
 }
 
+static Py_ssize_t
+string_length(PyBytesObject *a)
+{
+	return Py_SIZE(a);
+}
 
-#define FORWARD 1
-#define REVERSE -1
+static PyObject *
+string_concat(register PyBytesObject *a, register PyObject *bb)
+{
+	register Py_ssize_t size;
+	register PyBytesObject *op;
+	if (!PyBytes_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 ((PyBytesObject *)bb)
+	/* Optimize cases with empty left or right operand */
+	if ((Py_SIZE(a) == 0 || Py_SIZE(b) == 0) &&
+	    PyBytes_CheckExact(a) && PyBytes_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);
+	if (size < 0) {
+		PyErr_SetString(PyExc_OverflowError,
+				"strings are too large to concat");
+		return NULL;
+	}
+	  
+	/* Inline PyObject_NewVar */
+	op = (PyBytesObject *)PyObject_MALLOC(sizeof(PyBytesObject) + size);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyBytes_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
+}
 
-/* find and count characters and substrings */
+static PyObject *
+string_repeat(register PyBytesObject *a, register Py_ssize_t n)
+{
+	register Py_ssize_t i;
+	register Py_ssize_t j;
+	register Py_ssize_t size;
+	register PyBytesObject *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) && PyBytes_CheckExact(a)) {
+		Py_INCREF(a);
+		return (PyObject *)a;
+	}
+	nbytes = (size_t)size;
+	if (nbytes + sizeof(PyBytesObject) <= nbytes) {
+		PyErr_SetString(PyExc_OverflowError,
+			"repeated string is too long");
+		return NULL;
+	}
+	op = (PyBytesObject *)
+		PyObject_MALLOC(sizeof(PyBytesObject) + nbytes);
+	if (op == NULL)
+		return PyErr_NoMemory();
+	PyObject_INIT_VAR(op, &PyBytes_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;
+}
 
-#define findchar(target, target_len, c)                         \
-  ((char *)memchr((const void *)(target), c, target_len))
+/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
+
+static PyObject *
+string_slice(register PyBytesObject *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) && PyBytes_CheckExact(a)) {
+		/* It's the same as a */
+		Py_INCREF(a);
+		return (PyObject *)a;
+	}
+	if (j < i)
+		j = i;
+	return PyBytes_FromStringAndSize(a->ob_sval + i, j-i);
+}
+
+static int
+string_contains(PyObject *str_obj, PyObject *sub_obj)
+{
+	if (!PyBytes_CheckExact(sub_obj)) {
+#ifdef Py_USING_UNICODE
+		if (PyUnicode_Check(sub_obj))
+			return PyUnicode_Contains(str_obj, sub_obj);
+#endif
+		if (!PyBytes_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(PyBytesObject *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 = PyBytes_FromStringAndSize(&pchar, 1);
+	else {
+#ifdef COUNT_ALLOCS
+		one_strings++;
+#endif
+		Py_INCREF(v);
+	}
+	return v;
+}
+
+static PyObject*
+string_richcompare(PyBytesObject *a, PyBytesObject *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 (!(PyBytes_Check(a) && PyBytes_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
+_PyBytes_Eq(PyObject *o1, PyObject *o2)
+{
+	PyBytesObject *a = (PyBytesObject*) o1;
+	PyBytesObject *b = (PyBytesObject*) 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(PyBytesObject *a)
+{
+	register Py_ssize_t len;
+	register unsigned char *p;
+	register long x;
+
+	if (a->ob_shash != -1)
+		return a->ob_shash;
+	len = Py_SIZE(a);
+	p = (unsigned char *) a->ob_sval;
+	x = *p << 7;
+	while (--len >= 0)
+		x = (1000003*x) ^ *p++;
+	x ^= Py_SIZE(a);
+	if (x == -1)
+		x = -2;
+	a->ob_shash = x;
+	return x;
+}
+
+static PyObject*
+string_subscript(PyBytesObject* 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 += PyBytes_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,
+				 PyBytes_GET_SIZE(self),
+				 &start, &stop, &step, &slicelength) < 0) {
+			return NULL;
+		}
+
+		if (slicelength <= 0) {
+			return PyBytes_FromStringAndSize("", 0);
+		}
+		else if (start == 0 && step == 1 &&
+			 slicelength == PyBytes_GET_SIZE(self) &&
+			 PyBytes_CheckExact(self)) {
+			Py_INCREF(self);
+			return (PyObject *)self;
+		}
+		else if (step == 1) {
+			return PyBytes_FromStringAndSize(
+				PyBytes_AS_STRING(self) + start,
+				slicelength);
+		}
+		else {
+			source_buf = PyBytes_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 = PyBytes_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(PyBytesObject *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(PyBytesObject *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(PyBytesObject *self, Py_ssize_t *lenp)
+{
+	if ( lenp )
+		*lenp = Py_SIZE(self);
+	return 1;
+}
+
+static Py_ssize_t
+string_buffer_getcharbuf(PyBytesObject *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(PyBytesObject *self, Py_buffer *view, int flags)
+{
+	return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_SIZE(self),
+				 0, 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)
+
 
 /* Don't call if length < 2 */
-#define Py_STRING_MATCH(target, offset, pattern, length)        \
-  (target[offset] == pattern[0] &&                              \
-   target[offset+length-1] == pattern[length-1] &&              \
+#define Py_STRING_MATCH(target, offset, pattern, length)	\
+  (target[offset] == pattern[0] &&				\
+   target[offset+length-1] == pattern[length-1] &&		\
    !memcmp(target+offset+1, pattern+1, length-2) )
 
 
-/* Bytes ops must return a string.  */
-/* If the object is subclass of bytes, create a copy */
-Py_LOCAL(PyByteArrayObject *)
-return_self(PyByteArrayObject *self)
-{
-    if (PyByteArray_CheckExact(self)) {
-        Py_INCREF(self);
-        return (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;
-}
-
-Py_LOCAL(Py_ssize_t)
-findstring(const char *target, Py_ssize_t target_len,
-           const char *pattern, Py_ssize_t pattern_len,
-           Py_ssize_t start,
-           Py_ssize_t end,
-           int direction)
-{
-    if (start < 0) {
-        start += target_len;
-        if (start < 0)
-            start = 0;
-    }
-    if (end > target_len) {
-        end = target_len;
-    } else if (end < 0) {
-        end += target_len;
-        if (end < 0)
-            end = 0;
-    }
-
-    /* zero-length substrings always match at the first attempt */
-    if (pattern_len == 0)
-        return (direction > 0) ? start : end;
-
-    end -= pattern_len;
-
-    if (direction < 0) {
-        for (; end >= start; end--)
-            if (Py_STRING_MATCH(target, end, pattern, pattern_len))
-                return end;
-    } else {
-        for (; start <= end; start++)
-            if (Py_STRING_MATCH(target, start, pattern, pattern_len))
-                return start;
-    }
-    return -1;
-}
-
-Py_LOCAL_INLINE(Py_ssize_t)
-countstring(const char *target, Py_ssize_t target_len,
-            const char *pattern, Py_ssize_t pattern_len,
-            Py_ssize_t start,
-            Py_ssize_t end,
-            int direction, Py_ssize_t maxcount)
-{
-    Py_ssize_t count=0;
-
-    if (start < 0) {
-        start += target_len;
-        if (start < 0)
-            start = 0;
-    }
-    if (end > target_len) {
-        end = target_len;
-    } else if (end < 0) {
-        end += target_len;
-        if (end < 0)
-            end = 0;
-    }
-
-    /* zero-length substrings match everywhere */
-    if (pattern_len == 0 || maxcount == 0) {
-        if (target_len+1 < maxcount)
-            return target_len+1;
-        return maxcount;
-    }
-
-    end -= pattern_len;
-    if (direction < 0) {
-        for (; (end >= start); end--)
-            if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
-                count++;
-                if (--maxcount <= 0) break;
-                end -= pattern_len-1;
-            }
-    } else {
-        for (; (start <= end); start++)
-            if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
-                count++;
-                if (--maxcount <= 0)
-                    break;
-                start += pattern_len-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 = countstring(self_s, self_len,
-                        from_s, from_len,
-                        0, self_len, 1,
-                        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 = findstring(start, end-start,
-                            from_s, from_len,
-                            0, end-start, FORWARD);
-        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 = findstring(self_s, self_len,
-                        from_s, from_len,
-                        0, self_len, FORWARD);
-    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 = findstring(start, end-start,
-                            from_s, from_len,
-                            0, end-start, FORWARD);
-        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 = countstring(self_s, self_len,
-                        from_s, from_len,
-                        0, self_len, FORWARD, 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 = findstring(start, end-start,
-                            from_s, from_len,
-                            0, end-start, FORWARD);
-        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 *
-bytes_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) {
-        PyObject_ReleaseBuffer(from, &vfrom);
-        return NULL;
-    }
-
-    res = (PyObject *)replace((PyByteArrayObject *) self,
-                              vfrom.buf, vfrom.len,
-                              vto.buf, vto.len, count);
-
-    PyObject_ReleaseBuffer(from, &vfrom);
-    PyObject_ReleaseBuffer(to, &vto);
-    return res;
-}
-
-
 /* 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
@@ -2155,1225 +1376,3801 @@
 
 /* 5 splits gives 6 elements */
 #define PREALLOC_SIZE(maxsplit) \
-    (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
+	(maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
 
-#define SPLIT_APPEND(data, left, right)                         \
-    str = PyByteArray_FromStringAndSize((data) + (left),       \
-                                     (right) - (left));     \
-    if (str == NULL)                                        \
-        goto onError;                                   \
-    if (PyList_Append(list, str)) {                         \
-        Py_DECREF(str);                                 \
-        goto onError;                                   \
-    }                                                       \
-    else                                                    \
-        Py_DECREF(str);
+#define SPLIT_APPEND(data, left, right)				\
+	str = PyBytes_FromStringAndSize((data) + (left),	\
+					 (right) - (left));	\
+	if (str == NULL)					\
+		goto onError;					\
+	if (PyList_Append(list, str)) {				\
+		Py_DECREF(str);					\
+		goto onError;					\
+	}							\
+	else							\
+		Py_DECREF(str);
 
-#define SPLIT_ADD(data, left, right) {                          \
-    str = PyByteArray_FromStringAndSize((data) + (left),       \
-                                     (right) - (left));     \
-    if (str == NULL)                                        \
-        goto onError;                                   \
-    if (count < MAX_PREALLOC) {                             \
-        PyList_SET_ITEM(list, count, str);              \
-    } else {                                                \
-        if (PyList_Append(list, str)) {                 \
-            Py_DECREF(str);                         \
-            goto onError;                           \
-        }                                               \
-        else                                            \
-            Py_DECREF(str);                         \
-    }                                                       \
-    count++; }
+#define SPLIT_ADD(data, left, right) {				\
+	str = PyBytes_FromStringAndSize((data) + (left),	\
+					 (right) - (left));	\
+	if (str == NULL)					\
+		goto onError;					\
+	if (count < MAX_PREALLOC) {				\
+		PyList_SET_ITEM(list, count, str);		\
+	} else {						\
+		if (PyList_Append(list, str)) {			\
+			Py_DECREF(str);				\
+			goto onError;				\
+		}						\
+		else						\
+			Py_DECREF(str);				\
+	}							\
+	count++; }
 
 /* Always force the list to the expected size. */
 #define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
 
+#define SKIP_SPACE(s, i, len)    { while (i<len &&  isspace(Py_CHARMASK(s[i]))) i++; }
+#define SKIP_NONSPACE(s, i, len) { while (i<len && !isspace(Py_CHARMASK(s[i]))) i++; }
+#define RSKIP_SPACE(s, i)        { while (i>=0  &&  isspace(Py_CHARMASK(s[i]))) i--; }
+#define RSKIP_NONSPACE(s, i)     { while (i>=0  && !isspace(Py_CHARMASK(s[i]))) i--; }
 
 Py_LOCAL_INLINE(PyObject *)
-split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
+split_whitespace(PyBytesObject *self, Py_ssize_t len, Py_ssize_t maxsplit)
 {
-    register Py_ssize_t i, j, count = 0;
-    PyObject *str;
-    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+	const char *s = PyBytes_AS_STRING(self);
+	Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));
 
-    if (list == NULL)
-        return NULL;
+	if (list == NULL)
+		return NULL;
 
-    i = j = 0;
-    while ((j < len) && (maxcount-- > 0)) {
-        for(; j < len; j++) {
-            /* I found that using memchr makes no difference */
-            if (s[j] == ch) {
-                SPLIT_ADD(s, i, j);
-                i = j = j + 1;
-                break;
-            }
-        }
-    }
-    if (i <= len) {
-        SPLIT_ADD(s, i, len);
-    }
-    FIX_PREALLOC_SIZE(list);
-    return list;
+	i = j = 0;
 
+	while (maxsplit-- > 0) {
+		SKIP_SPACE(s, i, len);
+		if (i==len) break;
+		j = i; i++;
+		SKIP_NONSPACE(s, i, len);
+		if (j == 0 && i == len && PyBytes_CheckExact(self)) {
+			/* No whitespace in self, so just use it as list[0] */
+			Py_INCREF(self);
+			PyList_SET_ITEM(list, 0, (PyObject *)self);
+			count++;
+			break;
+		}
+		SPLIT_ADD(s, j, i);
+	}
+
+	if (i < len) {
+		/* Only occurs when maxsplit was reached */
+		/* Skip any remaining whitespace and copy to end of string */
+		SKIP_SPACE(s, i, len);
+		if (i != len)
+			SPLIT_ADD(s, i, len);
+	}
+	FIX_PREALLOC_SIZE(list);
+	return list;
   onError:
-    Py_DECREF(list);
-    return NULL;
+	Py_DECREF(list);
+	return NULL;
 }
 
-
 Py_LOCAL_INLINE(PyObject *)
-split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
+split_char(PyBytesObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount)
 {
-    register Py_ssize_t i, j, count = 0;
-    PyObject *str;
-    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+	const char *s = PyBytes_AS_STRING(self);
+	register Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
 
-    if (list == NULL)
-        return NULL;
+	if (list == NULL)
+		return NULL;
 
-    for (i = j = 0; i < len; ) {
-        /* find a token */
-        while (i < len && ISSPACE(s[i]))
-            i++;
-        j = i;
-        while (i < len && !ISSPACE(s[i]))
-            i++;
-        if (j < i) {
-            if (maxcount-- <= 0)
-                break;
-            SPLIT_ADD(s, j, i);
-            while (i < len && ISSPACE(s[i]))
-                i++;
-            j = i;
-        }
-    }
-    if (j < len) {
-        SPLIT_ADD(s, j, len);
-    }
-    FIX_PREALLOC_SIZE(list);
-    return list;
+	i = j = 0;
+	while ((j < len) && (maxcount-- > 0)) {
+		for(; j<len; j++) {
+			/* I found that using memchr makes no difference */
+			if (s[j] == ch) {
+				SPLIT_ADD(s, i, j);
+				i = j = j + 1;
+				break;
+			}
+		}
+	}
+	if (i == 0 && count == 0 && PyBytes_CheckExact(self)) {
+		/* ch not in self, so just use self as list[0] */
+		Py_INCREF(self);
+		PyList_SET_ITEM(list, 0, (PyObject *)self);
+		count++;
+	}
+	else if (i <= len) {
+		SPLIT_ADD(s, i, len);
+	}
+	FIX_PREALLOC_SIZE(list);
+	return list;
 
   onError:
-    Py_DECREF(list);
-    return NULL;
+	Py_DECREF(list);
+	return NULL;
 }
 
 PyDoc_STRVAR(split__doc__,
-"B.split([sep[, maxsplit]]) -> list of bytearray\n\
+"S.split([sep [,maxsplit]]) -> list of strings\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.");
+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 *
-bytes_split(PyByteArrayObject *self, PyObject *args)
+string_split(PyBytesObject *self, PyObject *args)
 {
-    Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
-    Py_ssize_t maxsplit = -1, count = 0;
-    const char *s = PyByteArray_AS_STRING(self), *sub;
-    PyObject *list, *str, *subobj = Py_None;
-    Py_buffer vsub;
+	Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j;
+	Py_ssize_t maxsplit = -1, count=0;
+	const char *s = PyBytes_AS_STRING(self), *sub;
+	PyObject *list, *str, *subobj = Py_None;
 #ifdef USE_FAST
-    Py_ssize_t pos;
+	Py_ssize_t pos;
 #endif
 
-    if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
-        return NULL;
-    if (maxsplit < 0)
-        maxsplit = PY_SSIZE_T_MAX;
+	if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
+		return NULL;
+	if (maxsplit < 0)
+		maxsplit = PY_SSIZE_T_MAX;
+	if (subobj == Py_None)
+		return split_whitespace(self, len, maxsplit);
+	if (PyBytes_Check(subobj)) {
+		sub = PyBytes_AS_STRING(subobj);
+		n = PyBytes_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;
 
-    if (subobj == Py_None)
-        return split_whitespace(s, len, maxsplit);
+	if (n == 0) {
+		PyErr_SetString(PyExc_ValueError, "empty separator");
+		return NULL;
+	}
+	else if (n == 1)
+		return split_char(self, len, sub[0], maxsplit);
 
-    if (_getbuffer(subobj, &vsub) < 0)
-        return NULL;
-    sub = vsub.buf;
-    n = vsub.len;
-
-    if (n == 0) {
-        PyErr_SetString(PyExc_ValueError, "empty separator");
-        PyObject_ReleaseBuffer(subobj, &vsub);
-        return NULL;
-    }
-    if (n == 1)
-        return split_char(s, len, sub[0], maxsplit);
-
-    list = PyList_New(PREALLOC_SIZE(maxsplit));
-    if (list == NULL) {
-        PyObject_ReleaseBuffer(subobj, &vsub);
-        return NULL;
-    }
+	list = PyList_New(PREALLOC_SIZE(maxsplit));
+	if (list == NULL)
+		return NULL;
 
 #ifdef USE_FAST
-    i = j = 0;
-    while (maxsplit-- > 0) {
-        pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
-        if (pos < 0)
-                break;
-        j = i+pos;
-        SPLIT_ADD(s, i, j);
-        i = j + n;
-    }
+	i = j = 0;
+	while (maxsplit-- > 0) {
+		pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
+		if (pos < 0)
+			break;
+		j = i+pos;
+		SPLIT_ADD(s, i, j);
+		i = j + n;
+	}
 #else
-    i = j = 0;
-    while ((j+n <= len) && (maxsplit-- > 0)) {
-        for (; j+n <= len; j++) {
-            if (Py_STRING_MATCH(s, j, sub, n)) {
-                SPLIT_ADD(s, i, j);
-                i = j = j + n;
-                break;
-            }
-        }
-    }
+	i = j = 0;
+	while ((j+n <= len) && (maxsplit-- > 0)) {
+		for (; j+n <= len; j++) {
+			if (Py_STRING_MATCH(s, j, sub, n)) {
+				SPLIT_ADD(s, i, j);
+				i = j = j + n;
+				break;
+			}
+		}
+	}
 #endif
-    SPLIT_ADD(s, i, len);
-    FIX_PREALLOC_SIZE(list);
-    PyObject_ReleaseBuffer(subobj, &vsub);
-    return list;
+	SPLIT_ADD(s, i, len);
+	FIX_PREALLOC_SIZE(list);
+	return list;
 
-  onError:
-    Py_DECREF(list);
-    PyObject_ReleaseBuffer(subobj, &vsub);
-    return NULL;
-}
-
-/* stringlib's partition shares nullbytes in some cases.
-   undo this, we don't want the nullbytes to be shared. */
-static PyObject *
-make_nullbytes_unique(PyObject *result)
-{
-    if (result != NULL) {
-        int i;
-        assert(PyTuple_Check(result));
-        assert(PyTuple_GET_SIZE(result) == 3);
-        for (i = 0; i < 3; i++) {
-            if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) {
-                PyObject *new = PyByteArray_FromStringAndSize(NULL, 0);
-                if (new == NULL) {
-                    Py_DECREF(result);
-                    result = NULL;
-                    break;
-                }
-                Py_DECREF(nullbytes);
-                PyTuple_SET_ITEM(result, i, new);
-            }
-        }
-    }
-    return result;
+ onError:
+	Py_DECREF(list);
+	return NULL;
 }
 
 PyDoc_STRVAR(partition__doc__,
-"B.partition(sep) -> (head, sep, tail)\n\
+"S.partition(sep) -> (head, sep, tail)\n\
 \n\
-Searches for the separator sep in B, and returns the part before it,\n\
+Searches for the separator sep in S, 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.");
+found, returns S and two empty strings.");
 
 static PyObject *
-bytes_partition(PyByteArrayObject *self, PyObject *sep_obj)
+string_partition(PyBytesObject *self, PyObject *sep_obj)
 {
-    PyObject *bytesep, *result;
+	const char *sep;
+	Py_ssize_t sep_len;
 
-    bytesep = PyByteArray_FromObject(sep_obj);
-    if (! bytesep)
-        return NULL;
+	if (PyBytes_Check(sep_obj)) {
+		sep = PyBytes_AS_STRING(sep_obj);
+		sep_len = PyBytes_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;
 
-    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 make_nullbytes_unique(result);
+	return stringlib_partition(
+		(PyObject*) self,
+		PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
+		sep_obj, sep, sep_len
+		);
 }
 
 PyDoc_STRVAR(rpartition__doc__,
-"B.rpartition(sep) -> (tail, sep, head)\n\
+"S.rpartition(sep) -> (tail, sep, head)\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.");
+Searches for the separator sep in S, starting at the end of S, and returns\n\
+the part before it, the separator itself, and the part after it.  If the\n\
+separator is not found, returns two empty strings and S.");
 
 static PyObject *
-bytes_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
+string_rpartition(PyBytesObject *self, PyObject *sep_obj)
 {
-    PyObject *bytesep, *result;
+	const char *sep;
+	Py_ssize_t sep_len;
 
-    bytesep = PyByteArray_FromObject(sep_obj);
-    if (! bytesep)
-        return NULL;
+	if (PyBytes_Check(sep_obj)) {
+		sep = PyBytes_AS_STRING(sep_obj);
+		sep_len = PyBytes_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;
 
-    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 make_nullbytes_unique(result);
+	return stringlib_rpartition(
+		(PyObject*) self,
+		PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
+		sep_obj, sep, sep_len
+		);
 }
 
 Py_LOCAL_INLINE(PyObject *)
-rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
+rsplit_whitespace(PyBytesObject *self, Py_ssize_t len, Py_ssize_t maxsplit)
 {
-    register Py_ssize_t i, j, count=0;
-    PyObject *str;
-    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+	const char *s = PyBytes_AS_STRING(self);
+	Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));
 
-    if (list == NULL)
-        return NULL;
+	if (list == NULL)
+		return NULL;
 
-    i = j = len - 1;
-    while ((i >= 0) && (maxcount-- > 0)) {
-        for (; i >= 0; i--) {
-            if (s[i] == ch) {
-                SPLIT_ADD(s, i + 1, j + 1);
-                j = i = i - 1;
-                break;
-            }
-        }
-    }
-    if (j >= -1) {
-        SPLIT_ADD(s, 0, j + 1);
-    }
-    FIX_PREALLOC_SIZE(list);
-    if (PyList_Reverse(list) < 0)
-        goto onError;
+	i = j = len-1;
 
-    return list;
+	while (maxsplit-- > 0) {
+		RSKIP_SPACE(s, i);
+		if (i<0) break;
+		j = i; i--;
+		RSKIP_NONSPACE(s, i);
+		if (j == len-1 && i < 0 && PyBytes_CheckExact(self)) {
+			/* No whitespace in self, so just use it as list[0] */
+			Py_INCREF(self);
+			PyList_SET_ITEM(list, 0, (PyObject *)self);
+			count++;
+			break;
+		}
+		SPLIT_ADD(s, i + 1, j + 1);
+	}
+	if (i >= 0) {
+		/* Only occurs when maxsplit was reached */
+		/* Skip any remaining whitespace and copy to beginning of string */
+		RSKIP_SPACE(s, i);
+		if (i >= 0)
+			SPLIT_ADD(s, 0, i + 1);
 
+	}
+	FIX_PREALLOC_SIZE(list);
+	if (PyList_Reverse(list) < 0)
+		goto onError;
+	return list;
   onError:
-    Py_DECREF(list);
-    return NULL;
+	Py_DECREF(list);
+	return NULL;
 }
 
 Py_LOCAL_INLINE(PyObject *)
-rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
+rsplit_char(PyBytesObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount)
 {
-    register Py_ssize_t i, j, count = 0;
-    PyObject *str;
-    PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+	const char *s = PyBytes_AS_STRING(self);
+	register Py_ssize_t i, j, count=0;
+	PyObject *str;
+	PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
 
-    if (list == NULL)
-        return NULL;
+	if (list == NULL)
+		return NULL;
 
-    for (i = j = len - 1; i >= 0; ) {
-        /* find a token */
-        while (i >= 0 && ISSPACE(s[i]))
-            i--;
-        j = i;
-        while (i >= 0 && !ISSPACE(s[i]))
-            i--;
-        if (j > i) {
-            if (maxcount-- <= 0)
-                break;
-            SPLIT_ADD(s, i + 1, j + 1);
-            while (i >= 0 && ISSPACE(s[i]))
-                i--;
-            j = i;
-        }
-    }
-    if (j >= 0) {
-        SPLIT_ADD(s, 0, j + 1);
-    }
-    FIX_PREALLOC_SIZE(list);
-    if (PyList_Reverse(list) < 0)
-        goto onError;
+	i = j = len - 1;
+	while ((i >= 0) && (maxcount-- > 0)) {
+		for (; i >= 0; i--) {
+			if (s[i] == ch) {
+				SPLIT_ADD(s, i + 1, j + 1);
+				j = i = i - 1;
+				break;
+			}
+		}
+	}
+	if (i < 0 && count == 0 && PyBytes_CheckExact(self)) {
+		/* ch not in self, so just use self as list[0] */
+		Py_INCREF(self);
+		PyList_SET_ITEM(list, 0, (PyObject *)self);
+		count++;
+	}
+	else if (j >= -1) {
+		SPLIT_ADD(s, 0, j + 1);
+	}
+	FIX_PREALLOC_SIZE(list);
+	if (PyList_Reverse(list) < 0)
+		goto onError;
+	return list;
 
-    return list;
-
-  onError:
-    Py_DECREF(list);
-    return NULL;
+ onError:
+	Py_DECREF(list);
+	return NULL;
 }
 
 PyDoc_STRVAR(rsplit__doc__,
-"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
+"S.rsplit([sep [,maxsplit]]) -> list of strings\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.");
+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 *
-bytes_rsplit(PyByteArrayObject *self, PyObject *args)
+string_rsplit(PyBytesObject *self, PyObject *args)
 {
-    Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
-    Py_ssize_t maxsplit = -1, count = 0;
-    const char *s = PyByteArray_AS_STRING(self), *sub;
-    PyObject *list, *str, *subobj = Py_None;
-    Py_buffer vsub;
+	Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j;
+	Py_ssize_t maxsplit = -1, count=0;
+	const char *s, *sub;
+	PyObject *list, *str, *subobj = Py_None;
 
-    if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
-        return NULL;
-    if (maxsplit < 0)
-        maxsplit = PY_SSIZE_T_MAX;
+	if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
+		return NULL;
+	if (maxsplit < 0)
+		maxsplit = PY_SSIZE_T_MAX;
+	if (subobj == Py_None)
+		return rsplit_whitespace(self, len, maxsplit);
+	if (PyBytes_Check(subobj)) {
+		sub = PyBytes_AS_STRING(subobj);
+		n = PyBytes_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;
 
-    if (subobj == Py_None)
-        return rsplit_whitespace(s, len, maxsplit);
+	if (n == 0) {
+		PyErr_SetString(PyExc_ValueError, "empty separator");
+		return NULL;
+	}
+	else if (n == 1)
+		return rsplit_char(self, len, sub[0], maxsplit);
 
-    if (_getbuffer(subobj, &vsub) < 0)
-        return NULL;
-    sub = vsub.buf;
-    n = vsub.len;
+	list = PyList_New(PREALLOC_SIZE(maxsplit));
+	if (list == NULL)
+		return NULL;
 
-    if (n == 0) {
-        PyErr_SetString(PyExc_ValueError, "empty separator");
-        PyObject_ReleaseBuffer(subobj, &vsub);
-        return NULL;
-    }
-    else if (n == 1)
-        return rsplit_char(s, len, sub[0], maxsplit);
+	j = len;
+	i = j - n;
 
-    list = PyList_New(PREALLOC_SIZE(maxsplit));
-    if (list == NULL) {
-        PyObject_ReleaseBuffer(subobj, &vsub);
-        return NULL;
-    }
-
-    j = len;
-    i = j - n;
-
-    while ( (i >= 0) && (maxsplit-- > 0) ) {
-        for (; i>=0; i--) {
-            if (Py_STRING_MATCH(s, i, sub, n)) {
-                SPLIT_ADD(s, i + n, j);
-                j = i;
-                i -= n;
-                break;
-            }
-        }
-    }
-    SPLIT_ADD(s, 0, j);
-    FIX_PREALLOC_SIZE(list);
-    if (PyList_Reverse(list) < 0)
-        goto onError;
-    PyObject_ReleaseBuffer(subobj, &vsub);
-    return list;
+	s = PyBytes_AS_STRING(self);
+	while ( (i >= 0) && (maxsplit-- > 0) ) {
+		for (; i>=0; i--) {
+			if (Py_STRING_MATCH(s, i, sub, n)) {
+				SPLIT_ADD(s, i + n, j);
+				j = i;
+				i -= n;
+				break;
+			}
+		}
+	}
+	SPLIT_ADD(s, 0, j);
+	FIX_PREALLOC_SIZE(list);
+	if (PyList_Reverse(list) < 0)
+		goto onError;
+	return list;
 
 onError:
-    Py_DECREF(list);
-    PyObject_ReleaseBuffer(subobj, &vsub);
+	Py_DECREF(list);
+	return NULL;
+}
+
+
+PyDoc_STRVAR(join__doc__,
+"S.join(sequence) -> string\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+sequence.  The separator between elements is S.");
+
+static PyObject *
+string_join(PyBytesObject *self, PyObject *orig)
+{
+	char *sep = PyBytes_AS_STRING(self);
+	const Py_ssize_t seplen = PyBytes_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 PyBytes_FromString("");
+	}
+	if (seqlen == 1) {
+		item = PySequence_Fast_GET_ITEM(seq, 0);
+		if (PyBytes_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 (!PyBytes_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 += PyBytes_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 = PyBytes_FromStringAndSize((char*)NULL, sz);
+	if (res == NULL) {
+		Py_DECREF(seq);
+		return NULL;
+	}
+
+	/* Catenate everything. */
+	p = PyBytes_AS_STRING(res);
+	for (i = 0; i < seqlen; ++i) {
+		size_t n;
+		item = PySequence_Fast_GET_ITEM(seq, i);
+		n = PyBytes_GET_SIZE(item);
+		Py_MEMCPY(p, PyBytes_AS_STRING(item), n);
+		p += n;
+		if (i < seqlen - 1) {
+			Py_MEMCPY(p, sep, seplen);
+			p += seplen;
+		}
+	}
+
+	Py_DECREF(seq);
+	return res;
+}
+
+PyObject *
+_PyBytes_Join(PyObject *sep, PyObject *x)
+{
+	assert(sep != NULL && PyBytes_Check(sep));
+	assert(x != NULL);
+	return string_join((PyBytesObject *)sep, x);
+}
+
+Py_LOCAL_INLINE(void)
+string_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t 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(PyBytesObject *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;
+	PyObject *obj_start=Py_None, *obj_end=Py_None;
+
+	if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj,
+		&obj_start, &obj_end))
+		return -2;
+	/* 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, &start))
+	        return -2;
+	if (obj_end != Py_None)
+		if (!_PyEval_SliceIndex(obj_end, &end))
+	        return -2;
+
+	if (PyBytes_Check(subobj)) {
+		sub = PyBytes_AS_STRING(subobj);
+		sub_len = PyBytes_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(
+			PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
+			sub, sub_len, start, end);
+	else
+		return stringlib_rfind_slice(
+			PyBytes_AS_STRING(self), PyBytes_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(PyBytesObject *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(PyBytesObject *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(PyBytesObject *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(PyBytesObject *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(PyBytesObject *self, int striptype, PyObject *sepobj)
+{
+	char *s = PyBytes_AS_STRING(self);
+	Py_ssize_t len = PyBytes_GET_SIZE(self);
+	char *sep = PyBytes_AS_STRING(sepobj);
+	Py_ssize_t seplen = PyBytes_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 && PyBytes_CheckExact(self)) {
+		Py_INCREF(self);
+		return (PyObject*)self;
+	}
+	else
+		return PyBytes_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_strip(PyBytesObject *self, int striptype)
+{
+	char *s = PyBytes_AS_STRING(self);
+	Py_ssize_t len = PyBytes_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 && PyBytes_CheckExact(self)) {
+		Py_INCREF(self);
+		return (PyObject*)self;
+	}
+	else
+		return PyBytes_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_argstrip(PyBytesObject *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 (PyBytes_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(PyBytesObject *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(PyBytesObject *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(PyBytesObject *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(PyBytesObject *self)
+{
+	char *s;
+	Py_ssize_t i, n = PyBytes_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyBytes_FromStringAndSize(NULL, n);
+	if (!newobj)
+		return NULL;
+
+	s = PyBytes_AS_STRING(newobj);
+
+	Py_MEMCPY(s, PyBytes_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(PyBytesObject *self)
+{
+	char *s;
+	Py_ssize_t i, n = PyBytes_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyBytes_FromStringAndSize(NULL, n);
+	if (!newobj)
+		return NULL;
+
+	s = PyBytes_AS_STRING(newobj);
+
+	Py_MEMCPY(s, PyBytes_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(PyBytesObject *self)
+{
+	char *s = PyBytes_AS_STRING(self), *s_new;
+	Py_ssize_t i, n = PyBytes_GET_SIZE(self);
+	int previous_is_cased = 0;
+	PyObject *newobj;
+
+	newobj = PyBytes_FromStringAndSize(NULL, n);
+	if (newobj == NULL)
+		return NULL;
+	s_new = PyBytes_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(PyBytesObject *self)
+{
+	char *s = PyBytes_AS_STRING(self), *s_new;
+	Py_ssize_t i, n = PyBytes_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyBytes_FromStringAndSize(NULL, n);
+	if (newobj == NULL)
+		return NULL;
+	s_new = PyBytes_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(PyBytesObject *self, PyObject *args)
+{
+	PyObject *sub_obj;
+	const char *str = PyBytes_AS_STRING(self), *sub;
+	Py_ssize_t sub_len;
+	Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+		return NULL;
+
+	if (PyBytes_Check(sub_obj)) {
+		sub = PyBytes_AS_STRING(sub_obj);
+		sub_len = PyBytes_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;
+
+	string_adjust_indices(&start, &end, PyBytes_GET_SIZE(self));
+
+	return PyInt_FromSsize_t(
+		stringlib_count(str + start, end - start, sub, sub_len)
+		);
+}
+
+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(PyBytesObject *self)
+{
+	char *s = PyBytes_AS_STRING(self), *s_new;
+	Py_ssize_t i, n = PyBytes_GET_SIZE(self);
+	PyObject *newobj;
+
+	newobj = PyBytes_FromStringAndSize(NULL, n);
+	if (newobj == NULL)
+		return NULL;
+	s_new = PyBytes_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.");
+
+static PyObject *
+string_translate(PyBytesObject *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 (PyBytes_Check(tableobj)) {
+		table = PyBytes_AS_STRING(tableobj);
+		tablen = PyBytes_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 (PyBytes_Check(delobj)) {
+			del_table = PyBytes_AS_STRING(delobj);
+			dellen = PyBytes_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 = PyBytes_GET_SIZE(input_obj);
+	result = PyBytes_FromStringAndSize((char *)NULL, inlen);
+	if (result == NULL)
+		return NULL;
+	output_start = output = PyBytes_AsString(result);
+	input = PyBytes_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 || !PyBytes_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 && PyBytes_CheckExact(input_obj)) {
+		Py_DECREF(result);
+		Py_INCREF(input_obj);
+		return input_obj;
+	}
+	/* Fix the size of the resulting string */
+	if (inlen > 0)
+		_PyBytes_Resize(&result, output - output_start);
+	return result;
+}
+
+
+#define FORWARD 1
+#define REVERSE -1
+
+/* 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(PyBytesObject *)
+return_self(PyBytesObject *self)
+{
+	if (PyBytes_CheckExact(self)) {
+		Py_INCREF(self);
+		return self;
+	}
+	return (PyBytesObject *)PyBytes_FromStringAndSize(
+		PyBytes_AS_STRING(self),
+		PyBytes_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;
+}
+
+Py_LOCAL(Py_ssize_t)
+findstring(const char *target, Py_ssize_t target_len,
+	   const char *pattern, Py_ssize_t pattern_len,
+	   Py_ssize_t start,
+	   Py_ssize_t end,
+	   int direction)
+{
+	if (start < 0) {
+		start += target_len;
+		if (start < 0)
+			start = 0;
+	}
+	if (end > target_len) {
+		end = target_len;
+	} else if (end < 0) {
+		end += target_len;
+		if (end < 0)
+			end = 0;
+	}
+
+	/* zero-length substrings always match at the first attempt */
+	if (pattern_len == 0)
+		return (direction > 0) ? start : end;
+
+	end -= pattern_len;
+
+	if (direction < 0) {
+		for (; end >= start; end--)
+			if (Py_STRING_MATCH(target, end, pattern, pattern_len))
+				return end;
+	} else {
+		for (; start <= end; start++)
+			if (Py_STRING_MATCH(target, start, pattern, pattern_len))
+				return start;
+	}
+	return -1;
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countstring(const char *target, Py_ssize_t target_len,
+	    const char *pattern, Py_ssize_t pattern_len,
+	    Py_ssize_t start,
+	    Py_ssize_t end,
+	    int direction, Py_ssize_t maxcount)
+{
+	Py_ssize_t count=0;
+
+	if (start < 0) {
+		start += target_len;
+		if (start < 0)
+			start = 0;
+	}
+	if (end > target_len) {
+		end = target_len;
+	} else if (end < 0) {
+		end += target_len;
+		if (end < 0)
+			end = 0;
+	}
+
+	/* zero-length substrings match everywhere */
+	if (pattern_len == 0 || maxcount == 0) {
+		if (target_len+1 < maxcount)
+			return target_len+1;
+		return maxcount;
+	}
+
+	end -= pattern_len;
+	if (direction < 0) {
+		for (; (end >= start); end--)
+			if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
+				count++;
+				if (--maxcount <= 0) break;
+				end -= pattern_len-1;
+			}
+	} else {
+		for (; (start <= end); start++)
+			if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
+				count++;
+				if (--maxcount <= 0)
+					break;
+				start += pattern_len-1;
+			}
+	}
+	return count;
+}
+
+
+/* Algorithms for different cases of string replacement */
+
+/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
+Py_LOCAL(PyBytesObject *)
+replace_interleave(PyBytesObject *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;
+	PyBytesObject *result;
+
+	self_len = PyBytes_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 = (PyBytesObject *)
+	                 PyBytes_FromStringAndSize(NULL, result_len)) )
+		return NULL;
+
+	self_s = PyBytes_AS_STRING(self);
+	result_s = PyBytes_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(PyBytesObject *)
+replace_delete_single_character(PyBytesObject *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;
+	PyBytesObject *result;
+
+	self_len = PyBytes_GET_SIZE(self);
+	self_s = PyBytes_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 = (PyBytesObject *)
+	                PyBytes_FromStringAndSize(NULL, result_len)) == NULL)
+		return NULL;
+	result_s = PyBytes_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(PyBytesObject *)
+replace_delete_substring(PyBytesObject *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;
+	PyBytesObject *result;
+
+	self_len = PyBytes_GET_SIZE(self);
+	self_s = PyBytes_AS_STRING(self);
+
+	count = countstring(self_s, self_len,
+			    from_s, from_len,
+			    0, self_len, 1,
+			    maxcount);
+
+	if (count == 0) {
+		/* no matches */
+		return return_self(self);
+	}
+
+	result_len = self_len - (count * from_len);
+	assert (result_len>=0);
+
+	if ( (result = (PyBytesObject *)
+	      PyBytes_FromStringAndSize(NULL, result_len)) == NULL )
+		return NULL;
+
+	result_s = PyBytes_AS_STRING(result);
+
+	start = self_s;
+	end = self_s + self_len;
+	while (count-- > 0) {
+		offset = findstring(start, end-start,
+				    from_s, from_len,
+				    0, end-start, FORWARD);
+		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(PyBytesObject *)
+replace_single_character_in_place(PyBytesObject *self,
+				  char from_c, char to_c,
+				  Py_ssize_t maxcount)
+{
+	char *self_s, *result_s, *start, *end, *next;
+	Py_ssize_t self_len;
+	PyBytesObject *result;
+
+	/* The result string will be the same size */
+	self_s = PyBytes_AS_STRING(self);
+	self_len = PyBytes_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 = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len);
+	if (result == NULL)
+		return NULL;
+	result_s = PyBytes_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(PyBytesObject *)
+replace_substring_in_place(PyBytesObject *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;
+	PyBytesObject *result;
+
+	/* The result string will be the same size */
+
+	self_s = PyBytes_AS_STRING(self);
+	self_len = PyBytes_GET_SIZE(self);
+
+	offset = findstring(self_s, self_len,
+			    from_s, from_len,
+			    0, self_len, FORWARD);
+	if (offset == -1) {
+		/* No matches; return the original string */
+		return return_self(self);
+	}
+
+	/* Need to make a new string */
+	result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len);
+	if (result == NULL)
+		return NULL;
+	result_s = PyBytes_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 = findstring(start, end-start,
+				    from_s, from_len,
+				    0, end-start, FORWARD);
+		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(PyBytesObject *)
+replace_single_character(PyBytesObject *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;
+	PyBytesObject *result;
+
+	self_s = PyBytes_AS_STRING(self);
+	self_len = PyBytes_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 = (PyBytesObject *)
+	      PyBytes_FromStringAndSize(NULL, result_len)) == NULL)
+		return NULL;
+	result_s = PyBytes_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(PyBytesObject *)
+replace_substring(PyBytesObject *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;
+	PyBytesObject *result;
+
+	self_s = PyBytes_AS_STRING(self);
+	self_len = PyBytes_GET_SIZE(self);
+
+	count = countstring(self_s, self_len,
+			    from_s, from_len,
+			    0, self_len, FORWARD, 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 = (PyBytesObject *)
+	      PyBytes_FromStringAndSize(NULL, result_len)) == NULL)
+		return NULL;
+	result_s = PyBytes_AS_STRING(result);
+
+	start = self_s;
+	end = self_s + self_len;
+	while (count-- > 0) {
+		offset = findstring(start, end-start,
+				    from_s, from_len,
+				    0, end-start, FORWARD);
+		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(PyBytesObject *)
+replace(PyBytesObject *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 || PyBytes_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 (PyBytes_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(PyBytesObject *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 (PyBytes_Check(from)) {
+		from_s = PyBytes_AS_STRING(from);
+		from_len = PyBytes_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 (PyBytes_Check(to)) {
+		to_s = PyBytes_AS_STRING(to);
+		to_len = PyBytes_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((PyBytesObject *) 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(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
+		  Py_ssize_t end, int direction)
+{
+	Py_ssize_t len = PyBytes_GET_SIZE(self);
+	Py_ssize_t slen;
+	const char* sub;
+	const char* str;
+
+	if (PyBytes_Check(substr)) {
+		sub = PyBytes_AS_STRING(substr);
+		slen = PyBytes_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 = PyBytes_AS_STRING(self);
+
+	string_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(PyBytesObject *self, PyObject *args)
+{
+	Py_ssize_t start = 0;
+	Py_ssize_t end = PY_SSIZE_T_MAX;
+	PyObject *subobj;
+	int result;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &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)
+		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(PyBytesObject *self, PyObject *args)
+{
+	Py_ssize_t start = 0;
+	Py_ssize_t end = PY_SSIZE_T_MAX;
+	PyObject *subobj;
+	int result;
+
+	if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &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)
+		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(PyBytesObject *self, PyObject *args)
+{
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
+
+    if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors))
+        return NULL;
+    v = PyBytes_AsEncodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyBytes_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(reverse__doc__,
-"B.reverse() -> None\n\
+
+PyDoc_STRVAR(decode__doc__,
+"S.decode([encoding[,errors]]) -> object\n\
 \n\
-Reverse the order of the values in B in place.");
-static PyObject *
-bytes_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 *
-bytes_insert(PyByteArrayObject *self, PyObject *args)
-{
-    int value;
-    Py_ssize_t where, n = Py_SIZE(self);
-
-    if (!PyArg_ParseTuple(args, "ni:insert", &where, &value))
-        return NULL;
-
-    if (n == PY_SSIZE_T_MAX) {
-        PyErr_SetString(PyExc_OverflowError,
-                        "cannot add more objects to bytes");
-        return NULL;
-    }
-    if (value < 0 || value >= 256) {
-        PyErr_SetString(PyExc_ValueError,
-                        "byte must be in range(0, 256)");
-        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] = value;
-
-    Py_RETURN_NONE;
-}
-
-PyDoc_STRVAR(append__doc__,
-"B.append(int) -> None\n\
-\n\
-Append a single item to the end of B.");
-static PyObject *
-bytes_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 bytes");
-        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 *
-bytes_extend(PyByteArrayObject *self, PyObject *arg)
-{
-    PyObject *it, *item, *bytes_obj;
-    Py_ssize_t buf_size = 0, len = 0;
-    int value;
-    char *buf;
-
-    /* bytes_setslice code only accepts something supporting PEP 3118. */
-    if (PyObject_CheckBuffer(arg)) {
-        if (bytes_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 abitrary. */
-    buf_size = _PyObject_LengthHint(arg, 32);
-
-    bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
-    if (bytes_obj == NULL)
-        return NULL;
-    buf = PyByteArray_AS_STRING(bytes_obj);
-
-    while ((item = PyIter_Next(it)) != NULL) {
-        if (! _getbytevalue(item, &value)) {
-            Py_DECREF(item);
-            Py_DECREF(it);
-            Py_DECREF(bytes_obj);
-            return NULL;
-        }
-        buf[len++] = value;
-        Py_DECREF(item);
-
-        if (len >= buf_size) {
-            buf_size = len + (len >> 1) + 1;
-            if (PyByteArray_Resize((PyObject *)bytes_obj, buf_size) < 0) {
-                Py_DECREF(it);
-                Py_DECREF(bytes_obj);
-                return NULL;
-            }
-            /* Recompute the `buf' pointer, since the resizing operation may
-               have invalidated it. */
-            buf = PyByteArray_AS_STRING(bytes_obj);
-        }
-    }
-    Py_DECREF(it);
-
-    /* Resize down to exact size. */
-    if (PyByteArray_Resize((PyObject *)bytes_obj, len) < 0) {
-        Py_DECREF(bytes_obj);
-        return NULL;
-    }
-
-    if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), bytes_obj) == -1)
-        return NULL;
-    Py_DECREF(bytes_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 give, will pop the last value.");
-static PyObject *
-bytes_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_OverflowError,
-                        "cannot pop an empty bytes");
-        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;
-    }
-
-    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(value);
-}
-
-PyDoc_STRVAR(remove__doc__,
-"B.remove(int) -> None\n\
-\n\
-Remove the first occurance of a value in B.");
-static PyObject *
-bytes_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 bytes");
-        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 *
-bytes_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)
-        PyObject_ReleaseBuffer(arg, &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 *
-bytes_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)
-        PyObject_ReleaseBuffer(arg, &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 *
-bytes_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)
-        PyObject_ReleaseBuffer(arg, &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\
+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\
+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 registerd with codecs.register_error that is\n\
 able to handle UnicodeDecodeErrors.");
 
 static PyObject *
-bytes_decode(PyObject *self, PyObject *args)
+string_decode(PyBytesObject *self, PyObject *args)
 {
-    const char *encoding = NULL;
-    const char *errors = NULL;
+    char *encoding = NULL;
+    char *errors = NULL;
+    PyObject *v;
 
     if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
         return NULL;
-    if (encoding == NULL)
-        encoding = PyUnicode_GetDefaultEncoding();
-    return PyCodec_Decode(self, encoding, errors);
-}
-
-PyDoc_STRVAR(alloc_doc,
-"B.__alloc__() -> int\n\
-\n\
-Returns the number of bytes actually allocated.");
-
-static PyObject *
-bytes_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 *
-bytes_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)
+    v = PyBytes_AsDecodedObject((PyObject *)self, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyBytes_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;
-    n = PySequence_Fast_GET_SIZE(seq);
-    items = PySequence_Fast_ITEMS(seq);
+    }
+    return v;
 
-    /* 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;
+ 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(PyBytesObject *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 = PyBytes_AS_STRING(self) + PyBytes_GET_SIZE(self); /* end of input */
+    for (p = PyBytes_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 > 0)
-            totalsize += mysize;
-        totalsize += Py_SIZE(obj);
-        if (totalsize < 0) {
-            PyErr_NoMemory();
-            goto error;
+
+    if (i > PY_SSIZE_T_MAX - j)
+	goto overflow1;
+
+    /* Second pass: create output string and fill it */
+    u = PyBytes_FromStringAndSize(NULL, i + j);
+    if (!u)
+        return NULL;
+
+    j = 0; /* same as in first pass */
+    q = PyBytes_AS_STRING(u); /* next output char */
+    qe = PyBytes_AS_STRING(u) + PyBytes_GET_SIZE(u); /* end of output */
+
+    for (p = PyBytes_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(PyBytesObject *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 && PyBytes_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject *)self;
     }
 
-    /* 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);
+    u = PyBytes_FromStringAndSize(NULL,
+				   left + PyBytes_GET_SIZE(self) + right);
+    if (u) {
+        if (left)
+            memset(PyBytes_AS_STRING(u), fill, left);
+        Py_MEMCPY(PyBytes_AS_STRING(u) + left,
+	       PyBytes_AS_STRING(self),
+	       PyBytes_GET_SIZE(self));
+        if (right)
+            memset(PyBytes_AS_STRING(u) + left + PyBytes_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(PyBytesObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
+        return NULL;
+
+    if (PyBytes_GET_SIZE(self) >= width && PyBytes_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return pad(self, 0, width - PyBytes_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(PyBytesObject *self, PyObject *args)
+{
+    Py_ssize_t width;
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
+        return NULL;
+
+    if (PyBytes_GET_SIZE(self) >= width && PyBytes_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    return pad(self, width - PyBytes_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(PyBytesObject *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 (PyBytes_GET_SIZE(self) >= width && PyBytes_CheckExact(self)) {
+        Py_INCREF(self);
+        return (PyObject*) self;
+    }
+
+    marg = width - PyBytes_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(PyBytesObject *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 (PyBytes_GET_SIZE(self) >= width) {
+        if (PyBytes_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject*) self;
+        }
         else
-           buf = PyBytes_AS_STRING(obj);
-        if (i) {
-            memcpy(dest, self->ob_bytes, mysize);
-            dest += mysize;
-        }
-        memcpy(dest, buf, size);
-        dest += size;
+            return PyBytes_FromStringAndSize(
+                PyBytes_AS_STRING(self),
+                PyBytes_GET_SIZE(self)
+            );
     }
 
-    /* Done */
-    Py_DECREF(seq);
-    return result;
+    fill = width - PyBytes_GET_SIZE(self);
 
-    /* Error handling */
-  error:
-    Py_DECREF(seq);
-    return NULL;
+    s = pad(self, fill, 0, '0');
+
+    if (s == NULL)
+        return NULL;
+
+    p = PyBytes_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(fromhex_doc,
-"bytearray.fromhex(string) -> bytearray\n\
+PyDoc_STRVAR(isspace__doc__,
+"S.isspace() -> bool\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').");
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
 
-static int
-hex_digit_to_int(Py_UNICODE c)
+static PyObject*
+string_isspace(PyBytesObject *self)
 {
-    if (c >= 128)
-        return -1;
-    if (ISDIGIT(c))
-        return c - '0';
-    else {
-        if (ISUPPER(c))
-            c = TOLOWER(c);
-        if (c >= 'a' && c <= 'f')
-            return c - 'a' + 10;
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1 &&
+	isspace(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!isspace(*p))
+	    return PyBool_FromLong(0);
     }
-    return -1;
+    return PyBool_FromLong(1);
 }
 
-static PyObject *
-bytes_fromhex(PyObject *cls, PyObject *args)
+
+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(PyBytesObject *self)
 {
-    PyObject *newbytes, *hexobj;
-    char *buf;
-    Py_UNICODE *hex;
-    Py_ssize_t hexlen, byteslen, i, j;
-    int top, bot;
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
 
-    if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
-        return NULL;
-    assert(PyUnicode_Check(hexobj));
-    hexlen = PyUnicode_GET_SIZE(hexobj);
-    hex = PyUnicode_AS_UNICODE(hexobj);
-    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;
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1 &&
+	isalpha(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!isalpha(*p))
+	    return PyBool_FromLong(0);
     }
-    if (PyByteArray_Resize(newbytes, j) < 0)
-        goto error;
-    return newbytes;
+    return PyBool_FromLong(1);
+}
 
-  error:
-    Py_DECREF(newbytes);
+
+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(PyBytesObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1 &&
+	isalnum(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_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(PyBytesObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
+
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1 &&
+	isdigit(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_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(PyBytesObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1)
+	return PyBool_FromLong(islower(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_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(PyBytesObject *self)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
+    int cased;
+
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1)
+	return PyBool_FromLong(isupper(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_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(PyBytesObject *self, PyObject *uncased)
+{
+    register const unsigned char *p
+        = (unsigned char *) PyBytes_AS_STRING(self);
+    register const unsigned char *e;
+    int cased, previous_is_cased;
+
+    /* Shortcut for single character strings */
+    if (PyBytes_GET_SIZE(self) == 1)
+	return PyBool_FromLong(isupper(*p) != 0);
+
+    /* Special case for empty strings */
+    if (PyBytes_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyBytes_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]) -> 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(PyBytesObject *self, PyObject *args)
+{
+    register Py_ssize_t i;
+    register Py_ssize_t j;
+    Py_ssize_t len;
+    int keepends = 0;
+    PyObject *list;
+    PyObject *str;
+    char *data;
+
+    if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+        return NULL;
+
+    data = PyBytes_AS_STRING(self);
+    len = PyBytes_GET_SIZE(self);
+
+    /* 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.*/
+
+    list = PyList_New(0);
+    if (!list)
+        goto onError;
+
+    for (i = j = 0; i < len; ) {
+	Py_ssize_t eol;
+
+	/* Find a line and append it */
+	while (i < len && data[i] != '\n' && data[i] != '\r')
+	    i++;
+
+	/* Skip the line break reading CRLF as one line break */
+	eol = i;
+	if (i < len) {
+	    if (data[i] == '\r' && i + 1 < len &&
+		data[i+1] == '\n')
+		i += 2;
+	    else
+		i++;
+	    if (keepends)
+		eol = i;
+	}
+	SPLIT_APPEND(data, j, eol);
+	j = i;
+    }
+    if (j < len) {
+	SPLIT_APPEND(data, j, len);
+    }
+
+    return list;
+
+ onError:
+    Py_XDECREF(list);
     return NULL;
 }
 
-PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+#undef SPLIT_APPEND
+#undef SPLIT_ADD
+#undef MAX_PREALLOC
+#undef PREALLOC_SIZE
 
 static PyObject *
-bytes_reduce(PyByteArrayObject *self)
+string_getnewargs(PyBytesObject *v)
 {
-    PyObject *latin1, *dict;
-    if (self->ob_bytes)
-        latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
-                                        Py_SIZE(self), NULL);
-    else
-        latin1 = PyUnicode_FromString("");
-
-    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);
+	return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v));
 }
 
-static PySequenceMethods bytes_as_sequence = {
-    (lenfunc)bytes_length,              /* sq_length */
-    (binaryfunc)PyByteArray_Concat,         /* sq_concat */
-    (ssizeargfunc)bytes_repeat,         /* sq_repeat */
-    (ssizeargfunc)bytes_getitem,        /* sq_item */
-    0,                                  /* sq_slice */
-    (ssizeobjargproc)bytes_setitem,     /* sq_ass_item */
-    0,                                  /* sq_ass_slice */
-    (objobjproc)bytes_contains,         /* sq_contains */
-    (binaryfunc)bytes_iconcat,          /* sq_inplace_concat */
-    (ssizeargfunc)bytes_irepeat,        /* sq_inplace_repeat */
-};
 
-static PyMappingMethods bytes_as_mapping = {
-    (lenfunc)bytes_length,
-    (binaryfunc)bytes_subscript,
-    (objobjargproc)bytes_ass_subscript,
-};
+#include "stringlib/string_format.h"
 
-static PyBufferProcs bytes_as_buffer = {
-    (readbufferproc)bytes_buffer_getreadbuf,
-    (writebufferproc)bytes_buffer_getwritebuf,
-    (segcountproc)bytes_buffer_getsegcount,
-    (charbufferproc)bytes_buffer_getcharbuf,
-    (getbufferproc)bytes_getbuffer,
-    (releasebufferproc)bytes_releasebuffer,
-};
+PyDoc_STRVAR(format__doc__,
+"S.format(*args, **kwargs) -> unicode\n\
+\n\
+");
 
+PyDoc_STRVAR(p_format__doc__,
+"S.__format__(format_spec) -> unicode\n\
+\n\
+");
+
+
 static PyMethodDef
-bytes_methods[] = {
-    {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc},
-    {"__reduce__", (PyCFunction)bytes_reduce, METH_NOARGS, reduce_doc},
-    {"append", (PyCFunction)bytes_append, METH_O, append__doc__},
-    {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
-     _Py_capitalize__doc__},
-    {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
-    {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__},
-    {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc},
-    {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__},
-    {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
-     expandtabs__doc__},
-    {"extend", (PyCFunction)bytes_extend, METH_O, extend__doc__},
-    {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__},
-    {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS,
-     fromhex_doc},
-    {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__},
-    {"insert", (PyCFunction)bytes_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)bytes_join, METH_O, join_doc},
-    {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
-    {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
-    {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__},
-    {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__},
-    {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__},
-    {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__},
-    {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__},
-    {"reverse", (PyCFunction)bytes_reverse, METH_NOARGS, reverse__doc__},
-    {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__},
-    {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__},
-    {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
-    {"rpartition", (PyCFunction)bytes_rpartition, METH_O, rpartition__doc__},
-    {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__},
-    {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__},
-    {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__},
-    {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
-     splitlines__doc__},
-    {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS ,
-     startswith__doc__},
-    {"strip", (PyCFunction)bytes_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)bytes_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(bytes_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 *bytes_iter(PyObject *seq);
-
-PyTypeObject PyByteArray_Type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "bytearray",
-    sizeof(PyByteArrayObject),
-    0,
-    (destructor)bytes_dealloc,          /* tp_dealloc */
-    0,                                  /* tp_print */
-    0,                                  /* tp_getattr */
-    0,                                  /* tp_setattr */
-    0,                                  /* tp_compare */
-    (reprfunc)bytes_repr,               /* tp_repr */
-    0,                                  /* tp_as_number */
-    &bytes_as_sequence,                 /* tp_as_sequence */
-    &bytes_as_mapping,                  /* tp_as_mapping */
-    0,                                  /* tp_hash */
-    0,                                  /* tp_call */
-    bytes_str,                          /* tp_str */
-    PyObject_GenericGetAttr,            /* tp_getattro */
-    0,                                  /* tp_setattro */
-    &bytes_as_buffer,                   /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
-    Py_TPFLAGS_HAVE_NEWBUFFER,          /* tp_flags */
-    bytes_doc,                          /* tp_doc */
-    0,                                  /* tp_traverse */
-    0,                                  /* tp_clear */
-    (richcmpfunc)bytes_richcompare,     /* tp_richcompare */
-    0,                                  /* tp_weaklistoffset */
-    bytes_iter,                         /* tp_iter */
-    0,                                  /* tp_iternext */
-    bytes_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)bytes_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
-bytesiter_dealloc(bytesiterobject *it)
-{
-    _PyObject_GC_UNTRACK(it);
-    Py_XDECREF(it->it_seq);
-    PyObject_GC_Del(it);
-}
-
-static int
-bytesiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
-{
-    Py_VISIT(it->it_seq);
-    return 0;
-}
-
-static PyObject *
-bytesiter_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 *
-bytesiter_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 bytesiter_methods[] = {
-    {"__length_hint__", (PyCFunction)bytesiter_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)bytesiter_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)bytesiter_traverse,  /* tp_traverse */
-    0,                                 /* tp_clear */
-    0,                                 /* tp_richcompare */
-    0,                                 /* tp_weaklistoffset */
-    PyObject_SelfIter,                 /* tp_iter */
-    (iternextfunc)bytesiter_next,      /* tp_iternext */
-    bytesiter_methods,                 /* tp_methods */
-    0,
+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, encode__doc__},
+	{"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__},
+	{"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS,
+	 expandtabs__doc__},
+	{"splitlines", (PyCFunction)string_splitlines, METH_VARARGS,
+	 splitlines__doc__},
+	{"__getnewargs__",	(PyCFunction)string_getnewargs,	METH_NOARGS},
+	{NULL,     NULL}		     /* sentinel */
 };
 
 static PyObject *
-bytes_iter(PyObject *seq)
-{
-    bytesiterobject *it;
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 
-    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;
+static PyObject *
+string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *x = NULL;
+	static char *kwlist[] = {"object", 0};
+
+	if (type != &PyBytes_Type)
+		return str_subtype_new(type, args, kwds);
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
+		return NULL;
+	if (x == NULL)
+		return PyBytes_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, &PyBytes_Type));
+	tmp = string_new(&PyBytes_Type, args, kwds);
+	if (tmp == NULL)
+		return NULL;
+	assert(PyBytes_CheckExact(tmp));
+	n = PyBytes_GET_SIZE(tmp);
+	pnew = type->tp_alloc(type, n);
+	if (pnew != NULL) {
+		Py_MEMCPY(PyBytes_AS_STRING(pnew), PyBytes_AS_STRING(tmp), n+1);
+		((PyBytesObject *)pnew)->ob_shash =
+			((PyBytesObject *)tmp)->ob_shash;
+		((PyBytesObject *)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 (!PyBytes_Check(v)) {
+		Py_INCREF(Py_NotImplemented);
+		return Py_NotImplemented;
+	}
+	return PyBytes_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 PyBytes_Type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"str",
+	sizeof(PyBytesObject),
+	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
+PyBytes_Concat(register PyObject **pv, register PyObject *w)
+{
+	register PyObject *v;
+	if (*pv == NULL)
+		return;
+	if (w == NULL || !PyBytes_Check(*pv)) {
+		Py_DECREF(*pv);
+		*pv = NULL;
+		return;
+	}
+	v = string_concat((PyBytesObject *) *pv, w);
+	Py_DECREF(*pv);
+	*pv = v;
+}
+
+void
+PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w)
+{
+	PyBytes_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
+_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+	register PyObject *v;
+	register PyBytesObject *sv;
+	v = *pv;
+	if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0 ||
+	    PyBytes_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, sizeof(PyBytesObject) + newsize);
+	if (*pv == NULL) {
+		PyObject_Del(v);
+		PyErr_NoMemory();
+		return -1;
+	}
+	_Py_NewReference(*pv);
+	sv = (PyBytesObject *) *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)
+
+Py_LOCAL_INLINE(int)
+formatfloat(char *buf, size_t buflen, int flags,
+            int prec, int type, PyObject *v)
+{
+	/* fmt = '%#.' + `prec` + `type`
+	   worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/
+	char fmt[20];
+	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 -1;
+	}
+	if (prec < 0)
+		prec = 6;
+	if (type == 'f' && fabs(x)/1e25 >= 1e25)
+		type = 'g';
+	/* Worst case length calc to ensure no buffer overrun:
+
+	   'g' formats:
+	     fmt = %#.<prec>g
+	     buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
+	        for any double rep.)
+	     len = 1 + prec + 1 + 2 + 5 = 9 + prec
+
+	   'f' formats:
+	     buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
+	     len = 1 + 50 + 1 + prec = 52 + prec
+
+	   If prec=0 the effective precision is 1 (the leading digit is
+	   always given), therefore increase the length by one.
+
+	*/
+	if (((type == 'g' || type == 'G') &&
+              buflen <= (size_t)10 + (size_t)prec) ||
+	    (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
+		PyErr_SetString(PyExc_OverflowError,
+			"formatted float is too long (precision too large?)");
+		return -1;
+	}
+	PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c",
+		      (flags&F_ALT) ? "#" : "",
+		      prec, type);
+        PyOS_ascii_formatd(buf, buflen, fmt, x);
+	return (int)strlen(buf);
+}
+
+/* _PyBytes_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*
+_PyBytes_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 = PyBytes_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 = PyBytes_Size(result);
+	if (llen > INT_MAX) {
+		PyErr_SetString(PyExc_ValueError, "string too large in _PyBytes_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 = PyBytes_FromStringAndSize(NULL,
+					numnondigits + prec);
+		char *b1;
+		if (!r1) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		b1 = PyBytes_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 = PyBytes_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 (PyBytes_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 floats, 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 *
+PyBytes_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 || !PyBytes_Check(format) || args == NULL) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	orig_args = args;
+	fmt = PyBytes_AS_STRING(format);
+	fmtcnt = PyBytes_GET_SIZE(format);
+	reslen = rescnt = fmtcnt + 100;
+	result = PyBytes_FromStringAndSize((char *)NULL, reslen);
+	if (result == NULL)
+		return NULL;
+	res = PyBytes_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 && !PyTuple_Check(args) &&
+	    !PyObject_TypeCheck(args, &PyBaseString_Type))
+		dict = args;
+	while (--fmtcnt >= 0) {
+		if (*fmt != '%') {
+			if (--rescnt < 0) {
+				rescnt = fmtcnt + 100;
+				reslen += rescnt;
+				if (_PyBytes_Resize(&result, reslen) < 0)
+					return NULL;
+				res = PyBytes_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{float,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 = PyBytes_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_AsLong(v);
+				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*10) / 10 != width) {
+						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_AsLong(v);
+					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*10) / 10 != prec) {
+							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 (!PyBytes_Check(temp)) {
+					PyErr_SetString(PyExc_TypeError,
+					  "%s argument has non-string str()");
+					Py_DECREF(temp);
+					goto error;
+				}
+				pbuf = PyBytes_AS_STRING(temp);
+				len = PyBytes_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),
+									flags, prec, c, iobj);
+							Py_DECREF(iobj);
+							if (len < 0)
+								goto error;
+							sign = 1;
+						}
+						else if (PyLong_Check(iobj)) {
+							int ilen;
+							
+							isnumok = 1;
+							temp = _PyBytes_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':
+				if (c == 'F')
+					c = 'f';
+				pbuf = formatbuf;
+				len = formatfloat(pbuf, sizeof(formatbuf),
+						  flags, prec, c, v);
+				if (len < 0)
+					goto error;
+				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 -
+					       PyBytes_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 (_PyBytes_Resize(&result, reslen) < 0) {
+					Py_XDECREF(temp);
+					return NULL;
+				}
+				res = PyBytes_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);
+	}
+	_PyBytes_Resize(&result, reslen - rescnt);
+	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 - PyBytes_AS_STRING(result);
+	if (_PyBytes_Resize(&result, rescnt))
+		goto error;
+	fmtcnt = PyBytes_GET_SIZE(format) - \
+		 (fmt - PyBytes_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
+PyBytes_InternInPlace(PyObject **p)
+{
+	register PyBytesObject *s = (PyBytesObject *)(*p);
+	PyObject *t;
+	if (s == NULL || !PyBytes_Check(s))
+		Py_FatalError("PyBytes_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 (!PyBytes_CheckExact(s))
+		return;
+	if (PyBytes_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;
+	PyBytes_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL;
+}
+
+void
+PyBytes_InternImmortal(PyObject **p)
+{
+	PyBytes_InternInPlace(p);
+	if (PyBytes_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) {
+		PyBytes_CHECK_INTERNED(*p) = SSTATE_INTERNED_IMMORTAL;
+		Py_INCREF(*p);
+	}
+}
+
+
+PyObject *
+PyBytes_InternFromString(const char *cp)
+{
+	PyObject *s = PyBytes_FromString(cp);
+	if (s == NULL)
+		return NULL;
+	PyBytes_InternInPlace(&s);
+	return s;
+}
+
+void
+PyBytes_Fini(void)
+{
+	int i;
+	for (i = 0; i < UCHAR_MAX + 1; i++) {
+		Py_XDECREF(characters[i]);
+		characters[i] = NULL;
+	}
+	Py_XDECREF(nullstring);
+	nullstring = NULL;
+}
+
+void _Py_ReleaseInternedStrings(void)
+{
+	PyObject *keys;
+	PyBytesObject *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 = (PyBytesObject *) 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_DECREF(interned);
+	interned = NULL;
 }
