Index: /trunk/src/libs/xpcom18a4/python/Makefile.kmk
===================================================================
--- /trunk/src/libs/xpcom18a4/python/Makefile.kmk	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/Makefile.kmk	(revision 59809)
@@ -5,5 +5,5 @@
 
 #
-# Copyright (C) 2009-2015 Oracle Corporation
+# Copyright (C) 2009-2016 Oracle Corporation
 #
 # This file is part of VirtualBox Open Source Edition (OSE), as
@@ -27,12 +27,8 @@
 #
 # List of supported Python versions, defining a number of
-# VBOX_PYTHON[25|26|27|DEF]_[INC|LIB] variables which get picked up below.
+# VBOX_PYTHON[26|27|31|32|33|34|35|DEF]_[INC|LIB] variables
+# which get picked up below.
 #
 ifeq ($(KBUILD_TARGET),darwin) # Relatively predictable, don't script.
- ifeq ($(KBUILD_TARGET_ARCH),x86)
-  VBOX_PYTHON25_INC = $(VBOX_PATH_MACOSX_SDK)/usr/include/python2.5
-  VBOX_PYTHON25_LIB = $(VBOX_PATH_MACOSX_SDK)/usr/lib/libpython2.5.dylib
-  VBOX_PYTHON25_LIB_X86 = $(VBOX_PYTHON25_LIB)
- endif
  if  !defined(VBOX_WITHOUT_VBOXPYTHON_FOR_OSX_10_6) \
   && (   !defined(VBOX_OSE) \
@@ -49,4 +45,5 @@
   VBOX_PYTHON27_LIB_X86 = $(VBOX_PYTHON27_LIB)
  endif
+ # No Python 3.x yet as part of OSX versions including El Capitan, 10.11.
 
 else
@@ -115,63 +112,4 @@
 
 
-ifdef VBOX_PYTHON23_INC
-#
-# Python 2.3 version
-#
-DLLS += VBoxPython2_3
-VBoxPython2_3_EXTENDS    = VBoxPythonBase
-VBoxPython2_3_EXTENDS_BY = appending
-VBoxPython2_3_TEMPLATE   = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin",OSX104,)
-VBoxPython2_3_INCS       = $(VBOX_PYTHON23_INC)
-VBoxPython2_3_LIBS       = $(VBOX_PYTHON23_LIB)
-
- ifdef VBOX_WITH_32_ON_64_MAIN_API
-DLLS += VBoxPython2_3_x86
-VBoxPython2_3_x86_EXTENDS    = VBoxPythonBase_x86
-VBoxPython2_3_x86_EXTENDS_BY = appending
-VBoxPython2_3_x86_TEMPLATE   = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin",OSX104,-x86)
-VBoxPython2_3_x86_INCS       = $(VBOX_PYTHON23_INC)
-VBoxPython2_3_x86_LIBS       = $(VBOX_PYTHON23_LIB_X86)
- endif
-endif
-
-ifdef VBOX_PYTHON24_INC
-#
-# Python 2.4 version
-#
-DLLS += VBoxPython2_4
-VBoxPython2_4_EXTENDS    = VBoxPythonBase
-VBoxPython2_4_EXTENDS_BY = appending
-VBoxPython2_4_INCS       = $(VBOX_PYTHON24_INC)
-VBoxPython2_4_LIBS       = $(VBOX_PYTHON24_LIB)
-
- ifdef VBOX_WITH_32_ON_64_MAIN_API
-DLLS += VBoxPython2_4_x86
-VBoxPython2_4_x86_EXTENDS    = VBoxPythonBase_x86
-VBoxPython2_4_x86_EXTENDS_BY = appending
-VBoxPython2_4_x86_INCS       = $(VBOX_PYTHON24_INC)
-VBoxPython2_4_x86_LIBS       = $(VBOX_PYTHON24_LIB_X86)
- endif
-endif
-
-ifdef VBOX_PYTHON25_INC
-#
-# Python 2.5 version
-#
-DLLS += VBoxPython2_5
-VBoxPython2_5_EXTENDS    = VBoxPythonBase
-VBoxPython2_5_EXTENDS_BY = appending
-VBoxPython2_5_INCS       = $(VBOX_PYTHON25_INC)
-VBoxPython2_5_LIBS       = $(VBOX_PYTHON25_LIB)
-
- ifdef VBOX_WITH_32_ON_64_MAIN_API
-DLLS += VBoxPython2_5_x86
-VBoxPython2_5_x86_EXTENDS    = VBoxPythonBase_x86
-VBoxPython2_5_x86_EXTENDS_BY = appending
-VBoxPython2_5_x86_INCS       = $(VBOX_PYTHON25_INC)
-VBoxPython2_5_x86_LIBS       = $(VBOX_PYTHON25_LIB_X86)
- endif
-endif
-
 ifdef VBOX_PYTHON26_INC
 #
@@ -213,4 +151,109 @@
 VBoxPython2_7_x86_INCS       = $(VBOX_PYTHON27_INC)
 VBoxPython2_7_x86_LIBS       = $(VBOX_PYTHON27_LIB_X86)
+ endif
+endif
+
+ifdef VBOX_PYTHON31_INC
+#
+# Python 3.1 version
+#
+DLLS += VBoxPython3_1
+VBoxPython3_1_EXTENDS    = VBoxPythonBase
+VBoxPython3_1_EXTENDS_BY = appending
+VBoxPython3_1_TEMPLATE   = XPCOM
+VBoxPython3_1_INCS       = $(VBOX_PYTHON31_INC)
+VBoxPython3_1_LIBS       = $(VBOX_PYTHON31_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+DLLS += VBoxPython3_1_x86
+VBoxPython3_1_x86_EXTENDS    = VBoxPythonBase_x86
+VBoxPython3_1_x86_EXTENDS_BY = appending
+VBoxPython3_1_x86_TEMPLATE   = XPCOM
+VBoxPython3_1_x86_INCS       = $(VBOX_PYTHON31_INC)
+VBoxPython3_1_x86_LIBS       = $(VBOX_PYTHON31_LIB_X86)
+ endif
+endif
+
+ifdef VBOX_PYTHON32_INC
+#
+# Python 3.2 version
+#
+DLLS += VBoxPython3_2
+VBoxPython3_2_EXTENDS    = VBoxPythonBase
+VBoxPython3_2_EXTENDS_BY = appending
+VBoxPython3_2_TEMPLATE   = XPCOM
+VBoxPython3_2_INCS       = $(VBOX_PYTHON32_INC)
+VBoxPython3_2_LIBS       = $(VBOX_PYTHON32_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+DLLS += VBoxPython3_2_x86
+VBoxPython3_2_x86_EXTENDS    = VBoxPythonBase_x86
+VBoxPython3_2_x86_EXTENDS_BY = appending
+VBoxPython3_2_x86_TEMPLATE   = XPCOM
+VBoxPython3_2_x86_INCS       = $(VBOX_PYTHON32_INC)
+VBoxPython3_2_x86_LIBS       = $(VBOX_PYTHON32_LIB_X86)
+ endif
+endif
+
+ifdef VBOX_PYTHON33_INC
+#
+# Python 3.3 version
+#
+DLLS += VBoxPython3_3
+VBoxPython3_3_EXTENDS    = VBoxPythonBase
+VBoxPython3_3_EXTENDS_BY = appending
+VBoxPython3_3_TEMPLATE   = XPCOM
+VBoxPython3_3_INCS       = $(VBOX_PYTHON33_INC)
+VBoxPython3_3_LIBS       = $(VBOX_PYTHON33_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+DLLS += VBoxPython3_3_x86
+VBoxPython3_3_x86_EXTENDS    = VBoxPythonBase_x86
+VBoxPython3_3_x86_EXTENDS_BY = appending
+VBoxPython3_3_x86_TEMPLATE   = XPCOM
+VBoxPython3_3_x86_INCS       = $(VBOX_PYTHON33_INC)
+VBoxPython3_3_x86_LIBS       = $(VBOX_PYTHON33_LIB_X86)
+ endif
+endif
+
+ifdef VBOX_PYTHON34_INC
+#
+# Python 3.4 version
+#
+DLLS += VBoxPython3_4
+VBoxPython3_4_EXTENDS    = VBoxPythonBase
+VBoxPython3_4_EXTENDS_BY = appending
+VBoxPython3_4_TEMPLATE   = XPCOM
+VBoxPython3_4_INCS       = $(VBOX_PYTHON34_INC)
+VBoxPython3_4_LIBS       = $(VBOX_PYTHON34_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+DLLS += VBoxPython3_4_x86
+VBoxPython3_4_x86_EXTENDS    = VBoxPythonBase_x86
+VBoxPython3_4_x86_EXTENDS_BY = appending
+VBoxPython3_4_x86_TEMPLATE   = XPCOM
+VBoxPython3_4_x86_INCS       = $(VBOX_PYTHON34_INC)
+VBoxPython3_4_x86_LIBS       = $(VBOX_PYTHON34_LIB_X86)
+ endif
+endif
+
+ifdef VBOX_PYTHON35_INC
+#
+# Python 3.5 version
+#
+DLLS += VBoxPython3_5
+VBoxPython3_5_EXTENDS    = VBoxPythonBase
+VBoxPython3_5_EXTENDS_BY = appending
+VBoxPython3_5_TEMPLATE   = XPCOM
+VBoxPython3_5_INCS       = $(VBOX_PYTHON35_INC)
+VBoxPython3_5_LIBS       = $(VBOX_PYTHON35_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+DLLS += VBoxPython3_5_x86
+VBoxPython3_5_x86_EXTENDS    = VBoxPythonBase_x86
+VBoxPython3_5_x86_EXTENDS_BY = appending
+VBoxPython3_5_x86_TEMPLATE   = XPCOM
+VBoxPython3_5_x86_INCS       = $(VBOX_PYTHON35_INC)
+VBoxPython3_5_x86_LIBS       = $(VBOX_PYTHON35_LIB_X86)
  endif
 endif
Index: /trunk/src/libs/xpcom18a4/python/gen_python_deps.py
===================================================================
--- /trunk/src/libs/xpcom18a4/python/gen_python_deps.py	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/gen_python_deps.py	(revision 59809)
@@ -2,5 +2,5 @@
 
 """
-Copyright (C) 2009-2013 Oracle Corporation
+Copyright (C) 2009-2016 Oracle Corporation
 
 This file is part of VirtualBox Open Source Edition (OSE), as
@@ -14,6 +14,7 @@
 
 import os,sys
+from distutils.version import StrictVersion
 
-versions = ["2.3", "2.4", "2.5", "2.6", "2.7",]
+versions = ["2.6", "2.7", "3.1", "3.2", "3.3", "3.4", "3.5"]
 prefixes = ["/usr", "/usr/local", "/opt", "/opt/local"]
 known = {}
@@ -41,10 +42,10 @@
 
 def print_vars(vers, known, sep, bitness_magic):
-    print "VBOX_PYTHON%s_INC=%s%s" %(vers, known[0], sep)
+    print("VBOX_PYTHON%s_INC=%s%s" %(vers, known[0], sep))
     if bitness_magic > 0:
-        print "VBOX_PYTHON%s_LIB=%s%s" %(vers, known[2], sep)
-        print "VBOX_PYTHON%s_LIB_X86=%s%s" %(vers, known[1], sep)
+        print("VBOX_PYTHON%s_LIB=%s%s" %(vers, known[2], sep))
+        print("VBOX_PYTHON%s_LIB_X86=%s%s" %(vers, known[1], sep))
     else:
-        print "VBOX_PYTHON%s_LIB=%s%s" %(vers, known[1], sep)
+        print("VBOX_PYTHON%s_LIB=%s%s" %(vers, known[1], sep))
 
 
@@ -91,4 +92,6 @@
 
     for v in versions:
+        if StrictVersion(v) < StrictVersion('2.6'):
+            continue
         for p in prefixes:
             c = checkPair(p, v, dllpre, dllsuff, bitness_magic)
@@ -96,5 +99,5 @@
                 known[v] = c
                 break
-    keys = known.keys()
+    keys = list(known.keys())
     # we want default to be the lowest versioned Python
     keys.sort()
Index: /trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp	(revision 59809)
@@ -111,9 +111,17 @@
 	c += "('%s', ";
 	// Pull a trick to ensure a valid string - use Python repr!
+#if PY_MAJOR_VERSION <= 2
 	PyObject *obMessage = PyString_FromString(pszMessageText);
+#else
+	PyObject *obMessage = PyUnicode_FromString(pszMessageText);
+#endif
 	if (obMessage) {
 		PyObject *repr = PyObject_Repr(obMessage);
 		if (repr) {
+#if PY_MAJOR_VERSION <= 2
 			c += PyString_AsString(repr);
+#else
+			c += PyUnicode_AsUTF8(repr);
+#endif
 			Py_DECREF(repr);
 		}
@@ -193,5 +201,9 @@
 	PyObject *temp = PyObject_Str(exc_typ);
 	if (temp) {
+#if PY_MAJOR_VERSION <= 2
 		streamout += PyString_AsString(temp);
+#else
+		streamout += PyUnicode_AsUTF8(temp);
+#endif
 		Py_DECREF(temp);
 	} else
@@ -201,5 +213,9 @@
 		temp = PyObject_Str(exc_val);
 		if (temp) {
+#if PY_MAJOR_VERSION <= 2
 			streamout += PyString_AsString(temp);
+#else
+			streamout += PyUnicode_AsUTF8(temp);
+#endif
 			Py_DECREF(temp);
 		} else
@@ -355,4 +371,5 @@
 	PyObject *obResult = NULL;
 
+#if PY_MAJOR_VERSION <= 2
 	/* Import the modules we need - cStringIO and traceback */
 	modStringIO = PyImport_ImportModule("cStringIO");
@@ -370,4 +387,21 @@
 	if (obStringIO==NULL)
 		TRACEBACK_FETCH_ERROR("cStringIO.StringIO() failed\n");
+#else
+	/* Import the modules we need - io and traceback */
+	modStringIO = PyImport_ImportModule("io");
+	if (modStringIO==NULL)
+		TRACEBACK_FETCH_ERROR("cant import io\n");
+
+	modTB = PyImport_ImportModule("traceback");
+	if (modTB==NULL)
+		TRACEBACK_FETCH_ERROR("cant import traceback\n");
+	/* Construct a StringIO object */
+	obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
+	if (obFuncStringIO==NULL)
+		TRACEBACK_FETCH_ERROR("cant find io.StringIO\n");
+	obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
+	if (obStringIO==NULL)
+		TRACEBACK_FETCH_ERROR("io.StringIO() failed\n");
+#endif
 	/* Get the traceback.print_exception function, and call it. */
 	obFuncTB = PyObject_GetAttrString(modTB, "print_tb");
@@ -396,9 +430,17 @@
 
 	/* And it should be a string all ready to go - duplicate it. */
+#if PY_MAJOR_VERSION <= 2
 	if (!PyString_Check(obResult))
+#else
+	if (!PyUnicode_Check(obResult))
+#endif
 			TRACEBACK_FETCH_ERROR("getvalue() did not return a string\n");
 
 	{ // a temp scope so I can use temp locals.
+#if PY_MAJOR_VERSION <= 2
 	char *tempResult = PyString_AsString(obResult);
+#else
+	char *tempResult = PyUnicode_AsUTF8(obResult);
+#endif
 	result = (char *)PyMem_Malloc(strlen(tempResult)+1);
 	if (result==NULL)
Index: /trunk/src/libs/xpcom18a4/python/src/PyGBase.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyGBase.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyGBase.cpp	(revision 59809)
@@ -67,5 +67,5 @@
 PRBool CheckDefaultGateway(PyObject *real_inst, REFNSIID iid, nsISupports **ret_gateway);
 
-/*static*/ nsresult 
+/*static*/ nsresult
 PyG_Base::CreateNew(PyObject *pPyInstance, const nsIID &iid, void **ppResult)
 {
@@ -115,5 +115,9 @@
 	}
 	else
+#if PY_MAJOR_VERSION <= 2
 		szRepr = PyString_AsString(r);
+#else
+		szRepr = PyUnicode_AsUTF8(r);
+#endif
 	if (szRepr==NULL) szRepr = "";
 	int reprOffset = *szRepr=='<' ? 1 : 0;
@@ -185,5 +189,5 @@
 	if (iid.Equals(NS_GET_IID(nsISupportsWeakReference)))
 		return (nsISupportsWeakReference *)this;
-	if (iid.Equals(NS_GET_IID(nsIInternalPython))) 
+	if (iid.Equals(NS_GET_IID(nsIInternalPython)))
 		return (nsISupports *)(nsIInternalPython *)this;
 	return NULL;
@@ -192,5 +196,5 @@
 // Call back into Python, passing a Python instance, and get back
 // an interface object that wraps the instance.
-/*static*/ PRBool 
+/*static*/ PRBool
 PyG_Base::AutoWrapPythonInstance(PyObject *ob, const nsIID &iid, nsISupports **ppret)
 {
@@ -245,5 +249,5 @@
 // the object to actually use as the gateway parameter for this interface.
 // For example, it is expected that the policy will wrap the interface
-// object in one of the xpcom.client.Interface objects, allowing 
+// object in one of the xpcom.client.Interface objects, allowing
 // natural usage of the interface from Python clients.
 // Note that piid will usually be NULL - this is because the runtime
@@ -256,8 +260,8 @@
 // so at least the user can simply QI the object.
 PyObject *
-PyG_Base::MakeInterfaceParam(nsISupports *pis, 
-			     const nsIID *piid, 
+PyG_Base::MakeInterfaceParam(nsISupports *pis,
+			     const nsIID *piid,
 			     int methodIndex /* = -1 */,
-			     const XPTParamDescriptor *d /* = NULL */, 
+			     const XPTParamDescriptor *d /* = NULL */,
 			     int paramIndex /* = -1 */)
 {
@@ -302,5 +306,5 @@
 		goto done;
 
-	result = PyObject_CallMethod(m_pPyObject, 
+	result = PyObject_CallMethod(m_pPyObject,
 	                               (char*)"_MakeInterfaceParam_",
 				       (char*)"OOiOi",
@@ -351,5 +355,5 @@
 		return NS_OK;
 	}
-	// If we have a "base object", then we need to delegate _every_ remaining 
+	// If we have a "base object", then we need to delegate _every_ remaining
 	// QI to it.
 	if (m_pBaseObject != NULL)
@@ -374,5 +378,5 @@
 
 		PyObject *result = PyObject_CallMethod(m_pPyObject, (char*)"_QueryInterface_",
-		                                                    (char*)"OO", 
+		                                                    (char*)"OO",
 		                                                    this_interface_ob, ob);
 		Py_DECREF(ob);
@@ -462,9 +466,9 @@
 	if (PyErr_Occurred()) {
 		// The error handling - fairly involved, but worth it as
-		// good error reporting is critical for users to know WTF 
+		// good error reporting is critical for users to know WTF
 		// is going on - especially with TypeErrors etc in their
 		// return values (ie, after the Python code has successfully
 		// exited, but we encountered errors unpacking their
-		// result values for the COM caller - there is literally no 
+		// result values for the COM caller - there is literally no
 		// way to catch these exceptions from Python code, as their
 		// is no Python function directly on the call-stack)
@@ -481,5 +485,5 @@
 		PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
 
-		PyObject *err_result = PyObject_CallMethod(m_pPyObject, 
+		PyObject *err_result = PyObject_CallMethod(m_pPyObject,
 	                                       (char*)"_GatewayException_",
 					       (char*)"z(OOO)",
@@ -641,6 +645,6 @@
 		ob_ret = PyObject_GetAttrString(real_ob, (char *)szPropertyName);
 		if (ob_ret==NULL) {
-			PyErr_Format(PyExc_AttributeError, 
-				     "The object does not have a 'get_%s' function, or a '%s attribute.", 
+			PyErr_Format(PyExc_AttributeError,
+				     "The object does not have a 'get_%s' function, or a '%s attribute.",
 				     szPropertyName, szPropertyName);
 		} else {
@@ -695,6 +699,6 @@
 			ret = NS_OK;
 		else {
-			PyErr_Format(PyExc_AttributeError, 
-				     "The object does not have a 'set_%s' function, or a '%s attribute.", 
+			PyErr_Format(PyExc_AttributeError,
+				     "The object does not have a 'set_%s' function, or a '%s attribute.",
 				     szPropertyName, szPropertyName);
 		}
@@ -737,5 +741,5 @@
   first thing we do is see if it has been auto-wrapped before.
 
-  If not, we create a new wrapper, then make a COM weak reference 
+  If not, we create a new wrapper, then make a COM weak reference
   to that wrapper, and store it directly back into the instance
   we are auto-wrapping!  The use of a weak-reference prevents
@@ -761,6 +765,6 @@
 		PRBool ok = PR_TRUE;
 		nsCOMPtr<nsIWeakReference> pWeakRef;
-		ok = NS_SUCCEEDED(Py_nsISupports::InterfaceFromPyObject(ob_existing_weak, 
-		                                       NS_GET_IID(nsIWeakReference), 
+		ok = NS_SUCCEEDED(Py_nsISupports::InterfaceFromPyObject(ob_existing_weak,
+		                                       NS_GET_IID(nsIWeakReference),
 		                                       getter_AddRefs(pWeakRef),
 		                                       PR_FALSE));
@@ -791,7 +795,7 @@
 		PRBool ok = PR_TRUE;
 		nsCOMPtr<nsIWeakReference> pWeakRef;
-		ok = NS_SUCCEEDED(Py_nsISupports::InterfaceFromPyObject(ob_existing_weak, 
-		                                       NS_GET_IID(nsIWeakReference), 
-		                                       getter_AddRefs(pWeakRef), 
+		ok = NS_SUCCEEDED(Py_nsISupports::InterfaceFromPyObject(ob_existing_weak,
+		                                       NS_GET_IID(nsIWeakReference),
+		                                       getter_AddRefs(pWeakRef),
 		                                       PR_FALSE));
 		Py_DECREF(ob_existing_weak);
@@ -827,5 +831,5 @@
 			swr->GetWeakReference( getter_AddRefs(pWeakReference) );
 			if (pWeakReference) {
-				PyObject *ob_new_weak = Py_nsISupports::PyObjectFromInterface(pWeakReference, 
+				PyObject *ob_new_weak = Py_nsISupports::PyObjectFromInterface(pWeakReference,
 										   NS_GET_IID(nsIWeakReference),
 										   PR_FALSE ); /* bMakeNicePyObject */
Index: /trunk/src/libs/xpcom18a4/python/src/PyIClassInfo.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIClassInfo.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIClassInfo.cpp	(revision 59809)
@@ -107,5 +107,9 @@
 {
 	if (v)
+#if PY_MAJOR_VERSION <= 2
 		return PyString_FromString(v);
+#else
+		return PyUnicode_FromString(v);
+#endif
 	Py_INCREF(Py_None);
 	return Py_None;
@@ -167,5 +171,5 @@
 }
 
-struct PyMethodDef 
+struct PyMethodDef
 PyMethods_IClassInfo[] =
 {
Index: /trunk/src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp	(revision 59809)
@@ -133,6 +133,11 @@
 		return PyXPCOM_BuildPyException(r);
 
+#if PY_MAJOR_VERSION <= 2
 	PyObject *ob_pid = PyString_FromString(ret_pid);
 	PyObject *ob_class = PyString_FromString(ret_class);
+#else
+	PyObject *ob_pid = PyUnicode_FromString(ret_pid);
+	PyObject *ob_class = PyUnicode_FromString(ret_class);
+#endif
 	PyObject *ret = Py_BuildValue("OO", ob_pid, ob_class);
 	nsMemory::Free(ret_pid);
@@ -183,5 +188,5 @@
 }
 
-struct PyMethodDef 
+struct PyMethodDef
 PyMethods_IComponentManagerObsolete[] =
 {
Index: /trunk/src/libs/xpcom18a4/python/src/PyIID.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIID.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIID.cpp	(revision 59809)
@@ -60,4 +60,5 @@
 	PyObject *obBuf;
 	if ( PyArg_ParseTuple(args, "O", &obBuf)) {
+#if PY_MAJOR_VERSION <= 2
 		if (PyBuffer_Check(obBuf)) {
 			PyBufferProcs *pb = NULL;
@@ -65,7 +66,22 @@
 			void *buf = NULL;
 			int size = (*pb->bf_getreadbuffer)(obBuf, 0, &buf);
+#else
+		if (PyObject_CheckBuffer(obBuf)) {
+			void *buf = NULL;
+            Py_buffer view;
+            if (PyObject_GetBuffer(obBuf, &view, PyBUF_CONTIG_RO) != 0)
+            {
+                PyErr_Format(PyExc_ValueError, "Could not get contiguous buffer from object");
+                return NULL;
+            }
+            Py_ssize_t size = view.len;
+            buf = view.buf;
+#endif
 			if (size != sizeof(nsIID) || buf==NULL) {
+#if PY_MAJOR_VERSION >= 3
+                PyBuffer_Release(&view);
+#endif
 #ifdef VBOX
-                                PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", (int)sizeof(nsIID));
+                PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", (int)sizeof(nsIID));
 #else
 				PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", sizeof(nsIID));
@@ -85,4 +101,7 @@
 				ptr += sizeof(PRUint8);
 			}
+#if PY_MAJOR_VERSION >= 3
+            PyBuffer_Release(&view);
+#endif
 			return new Py_nsIID(iid);
 		}
@@ -107,6 +126,11 @@
 		return PR_FALSE;
 	}
+#if PY_MAJOR_VERSION <= 2
 	if (PyString_Check(ob)) {
 		ok = iid.Parse(PyString_AsString(ob));
+#else
+	if (PyUnicode_Check(ob)) {
+		ok = iid.Parse(PyUnicode_AsUTF8(ob));
+#endif
 		if (!ok) {
 			PyXPCOM_BuildPyException(NS_ERROR_ILLEGAL_VALUE);
@@ -144,6 +168,5 @@
 PyTypeObject Py_nsIID::type =
 {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"IID",
 	sizeof(Py_nsIID),
@@ -153,5 +176,9 @@
 	PyTypeMethod_getattr,                           /* tp_getattr */
 	0,                                              /* tp_setattr */
+#if PY_MAJOR_VERSION <= 2
 	PyTypeMethod_compare,                           /* tp_compare */
+#else
+	0,                                              /* reserved */
+#endif
 	PyTypeMethod_repr,                              /* tp_repr */
 	0,                                              /* tp_as_number */
@@ -161,4 +188,19 @@
 	0,                                              /* tp_call */
 	PyTypeMethod_str,                               /* tp_str */
+	0,                                              /* tp_getattro */
+	0,                                              /* tp_setattro */
+	0,                                              /* tp_as_buffer */
+	0,                                              /* tp_flags */
+	0,                                              /* tp_doc */
+	0,                                              /* tp_traverse */
+	0,                                              /* tp_clear */
+	PyTypeMethod_richcompare,                       /* tp_richcompare */
+	0,                                              /* tp_weaklistoffset */
+	0,                                              /* tp_iter */
+	0,                                              /* tp_iternext */
+	0,                                              /* tp_methods */
+	0,                                              /* tp_members */
+	0,                                              /* tp_getset */
+	0,                                              /* tp_base */
 };
 
@@ -184,8 +226,16 @@
 		PyObject *ret;
 		if (iid_repr != nsnull) {
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromString(iid_repr);
+#else
+			ret = PyUnicode_FromString(iid_repr);
+#endif
 			nsMemory::Free(iid_repr);
 		} else
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromString("<cant get IID info!>");
+#else
+			ret = PyUnicode_FromString("<cant get IID info!>");
+#endif
 		return ret;
 	}
@@ -193,4 +243,5 @@
 }
 
+#if PY_MAJOR_VERSION <= 2
 /* static */ int
 Py_nsIID::PyTypeMethod_compare(PyObject *self, PyObject *other)
@@ -201,4 +252,37 @@
 	return rc == 0 ? 0 : (rc < 0 ? -1 : 1);
 }
+#endif
+
+/* static */ PyObject *
+Py_nsIID::PyTypeMethod_richcompare(PyObject *self, PyObject *other, int op)
+{
+    PyObject *result = NULL;
+	Py_nsIID *s_iid = (Py_nsIID *)self;
+	Py_nsIID *o_iid = (Py_nsIID *)other;
+	int rc = memcmp(&s_iid->m_iid, &o_iid->m_iid, sizeof(s_iid->m_iid));
+    switch (op)
+    {
+        case Py_LT:
+            result = rc < 0 ? Py_True : Py_False;
+            break;
+        case Py_LE:
+            result = rc <= 0 ? Py_True : Py_False;
+            break;
+        case Py_EQ:
+            result = rc == 0 ? Py_True : Py_False;
+            break;
+        case Py_NE:
+            result = rc != 0 ? Py_True : Py_False;
+            break;
+        case Py_GT:
+            result = rc > 0 ? Py_True : Py_False;
+            break;
+        case Py_GE:
+            result = rc >= 0 ? Py_True : Py_False;
+            break;
+    }
+    Py_XINCREF(result);
+    return result;
+}
 
 /* static */ PyObject *
@@ -209,10 +293,14 @@
 	char *sziid = s_iid->m_iid.ToString();
 #ifdef VBOX
-	snprintf(buf, sizeof(buf), "_xpcom.IID('%s')", sziid);
+	snprintf(buf, sizeof(buf), "_xpcom.ID('%s')", sziid);
 #else
 	sprintf(buf, "_xpcom.IID('%s')", sziid);
 #endif
 	nsMemory::Free(sziid);
+#if PY_MAJOR_VERSION <= 2
 	return PyString_FromString(buf);
+#else
+	return PyUnicode_FromString(buf);
+#endif
 }
 
@@ -222,5 +310,9 @@
 	Py_nsIID *s_iid = (Py_nsIID *)self;
 	char *sziid = s_iid->m_iid.ToString();
+#if PY_MAJOR_VERSION <= 2
 	PyObject *ret = PyString_FromString(sziid);
+#else
+	PyObject *ret = PyUnicode_FromString(sziid);
+#endif
 	nsMemory::Free(sziid);
 	return ret;
Index: /trunk/src/libs/xpcom18a4/python/src/PyIInputStream.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIInputStream.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIInputStream.cpp	(revision 59809)
@@ -109,5 +109,9 @@
 	}
 	if (n==0) { // mozilla will assert if we alloc zero bytes.
+#if PY_MAJOR_VERSION <= 2
 		return PyBuffer_New(0);
+#else
+		return PyBytes_FromString("");
+#endif
 	}
 	char *buf = (char *)nsMemory::Alloc(n);
@@ -123,4 +127,5 @@
 	PyObject *rc = NULL;
 	if ( NS_SUCCEEDED(r) ) {
+#if PY_MAJOR_VERSION <= 2
 		rc = PyBuffer_New(nread);
 		if (rc != NULL) {
@@ -146,4 +151,7 @@
 			memcpy(ob_buf, buf, nread);
 		}
+#else
+        rc = PyBytes_FromStringAndSize(buf, nread);
+#endif
 	} else
 		PyXPCOM_BuildPyException(r);
Index: /trunk/src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp	(revision 59809)
@@ -75,5 +75,9 @@
 	if ( NS_FAILED(r) )
 		return PyXPCOM_BuildPyException(r);
+#if PY_MAJOR_VERSION <= 2
 	PyObject *ret = PyString_FromString(name);
+#else
+	PyObject *ret = PyUnicode_FromString(name);
+#endif
 	nsMemory::Free(name);
 	return ret;
@@ -393,5 +397,5 @@
 }
 
-struct PyMethodDef 
+struct PyMethodDef
 PyMethods_IInterfaceInfo[] =
 {
Index: /trunk/src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp	(revision 59809)
@@ -135,5 +135,9 @@
 		return PyXPCOM_BuildPyException(r);
 
+#if PY_MAJOR_VERSION <= 2
 	PyObject *ret = PyString_FromString(ret_name);
+#else
+	PyObject *ret = PyUnicode_FromString(ret_name);
+#endif
 	nsMemory::Free(ret_name);
 	return ret;
@@ -186,5 +190,5 @@
 // void autoRegisterInterfaces();
 
-PyMethodDef 
+PyMethodDef
 PyMethods_IInterfaceInfoManager[] =
 {
Index: /trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp	(revision 59809)
@@ -218,5 +218,34 @@
 	}
 	PyXPCOM_TypeObject *this_type = (PyXPCOM_TypeObject *)ob_type;
+#if PY_MAJOR_VERSION <= 2
 	return Py_FindMethodInChain(&this_type->chain, this, (char *)name);
+#else
+    PyMethodChain *chain = &this_type->chain;
+    if (name[0] == '_' && name[1] == '_')
+    {
+        if (!strcmp(name, "__doc__"))
+        {
+            const char *doc = ob_type->tp_doc;
+            if (doc)
+#if PY_MAJOR_VERSION <= 2
+                return PyString_FromString(doc);
+#else
+                return PyUnicode_FromString(doc);
+#endif
+        }
+    }
+    while (chain)
+    {
+        PyMethodDef *ml = chain->methods;
+        for (; ml->ml_name; ml++)
+        {
+            if (!strcmp(name, ml->ml_name))
+                return PyCFunction_New(ml, this);
+        }
+        chain = chain->link;
+    }
+    PyErr_SetString(PyExc_AttributeError, name);
+    return NULL;
+#endif
 }
 
Index: /trunk/src/libs/xpcom18a4/python/src/PyIVariant.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/PyIVariant.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/PyIVariant.cpp	(revision 59809)
@@ -62,5 +62,9 @@
 }
 static PyObject *MyChar( char c) {
+#if PY_MAJOR_VERSION <= 2
 	return PyString_FromStringAndSize(&c, 1);
+#else
+	return PyUnicode_FromStringAndSize(&c, 1);
+#endif
 }
 static PyObject *MyUChar( PRUnichar c) {
@@ -123,7 +127,15 @@
 GET_SIMPLE(nsIID, GetAsID, Py_nsIID::PyObjectFromIID)
 
+#if PY_MAJOR_VERSION <= 2
 GET_ALLOCATED(char *, GetAsString, PyString_FromString, nsMemory::Free)
+#else
+GET_ALLOCATED(char *, GetAsString, PyUnicode_FromString, nsMemory::Free)
+#endif
 GET_ALLOCATED(PRUnichar *, GetAsWString, MyUnicode, nsMemory::Free)
+#if PY_MAJOR_VERSION <= 2
 GET_ALLOCATED_SIZE(char *, GetAsStringWithSize, PyString_FromStringAndSize, nsMemory::Free)
+#else
+GET_ALLOCATED_SIZE(char *, GetAsStringWithSize, PyUnicode_FromStringAndSize, nsMemory::Free)
+#endif
 GET_ALLOCATED_SIZE(PRUnichar *, GetAsWStringWithSize, PyObject_FromNSString, nsMemory::Free)
 
@@ -166,5 +178,5 @@
 }
 
-struct PyMethodDef 
+struct PyMethodDef
 PyMethods_IVariant[] =
 {
Index: /trunk/src/libs/xpcom18a4/python/src/Pyxpt_info.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/Pyxpt_info.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/Pyxpt_info.cpp	(revision 59809)
@@ -55,5 +55,5 @@
 	}
     // build an object using the same format as a TypeDescriptor.
-	return Py_BuildValue("bzzz", 
+	return Py_BuildValue("bzzz",
 		d->flags,
 		NULL, NULL, NULL);
@@ -66,5 +66,5 @@
 		return Py_None;
 	}
-	return Py_BuildValue("bbbh", 
+	return Py_BuildValue("bbbh",
 		d->prefix.flags,
 		d->argnum,
@@ -150,10 +150,14 @@
 			break;
 		case TD_CHAR:
+#if PY_MAJOR_VERSION <= 2
 			v = PyString_FromStringAndSize(&c->value.ch, 1);
+#else
+			v = PyUnicode_FromStringAndSize(&c->value.ch, 1);
+#endif
 			break;
 		case TD_WCHAR:
 			v = PyObject_FromNSString((PRUnichar *)&c->value.wch, 1);
 			break;
-	//    TD_VOID              = 13,  
+	//    TD_VOID              = 13,
 		case TD_PNSIID:
 			v = Py_nsIID::PyObjectFromIID(*c->value.iid);
@@ -161,5 +165,9 @@
 	//    TD_DOMSTRING         = 15,
 		case TD_PSTRING:
+#if PY_MAJOR_VERSION <= 2
 			v = PyString_FromString(c->value.str);
+#else
+			v = PyUnicode_FromString(c->value.str);
+#endif
 			break;
 		case TD_PWSTRING:
@@ -175,5 +183,9 @@
 	//    TD_ASTRING           = 25
 		default:
+#if PY_MAJOR_VERSION <= 2
 			v = PyString_FromString("Unknown type code!!");
+#else
+			v = PyUnicode_FromString("Unknown type code!!");
+#endif
 			break;
 
Index: /trunk/src/libs/xpcom18a4/python/src/TypeObject.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/TypeObject.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/TypeObject.cpp	(revision 59809)
@@ -53,6 +53,5 @@
 
 static PyTypeObject PyInterfaceType_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,			/* Number of items for varobject */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"interface-type",			/* Name of this type */
 	sizeof(PyTypeObject),	/* Basic object size */
@@ -80,5 +79,9 @@
 PyXPCOM_TypeObject::IsType(PyTypeObject *t)
 {
+#if PY_MAJOR_VERSION <= 2
 	return t->ob_type == &PyInterfaceType_Type;
+#else
+	return Py_TYPE(t) == &PyInterfaceType_Type;
+#endif
 }
 
@@ -122,4 +125,34 @@
 }
 
+/*static*/PyObject *
+PyXPCOM_TypeObject::Py_richcmp(PyObject *self, PyObject *other, int op)
+{
+    PyObject *result = NULL;
+    int rc = Py_cmp(self, other);
+    switch (op)
+    {
+        case Py_LT:
+            result = rc < 0 ? Py_True : Py_False;
+            break;
+        case Py_LE:
+            result = rc <= 0 ? Py_True : Py_False;
+            break;
+        case Py_EQ:
+            result = rc == 0 ? Py_True : Py_False;
+            break;
+        case Py_NE:
+            result = rc != 0 ? Py_True : Py_False;
+            break;
+        case Py_GT:
+            result = rc > 0 ? Py_True : Py_False;
+            break;
+        case Py_GE:
+            result = rc >= 0 ? Py_True : Py_False;
+            break;
+    }
+    Py_XINCREF(result);
+    return result;
+}
+
 // @pymethod int|Py_nsISupports|__hash__|Implement a hash-code for the XPCOM object using XPCOM identity rules.
 /*static*/long PyXPCOM_TypeObject::Py_hash(PyObject *self)
@@ -152,5 +185,5 @@
 	char buf[512];
 #ifdef VBOX
-	snprintf(buf, sizeof(buf), "<XPCOM object (%s) at 0x%p/0x%p>",
+	snprintf(buf, sizeof(buf), "<XPCOM object (%s) at %p/%p>",
 	        iid_repr, (void *)self, (void *)pis->m_obj.get());
 #else
@@ -159,5 +192,9 @@
 #endif
 	nsMemory::Free(iid_repr);
+#if PY_MAJOR_VERSION <= 2
 	return PyString_FromString(buf);
+#else
+	return PyUnicode_FromString(buf);
+#endif
 }
 
@@ -173,5 +210,5 @@
 	if (NS_SUCCEEDED(rv))
 		rv = ss->ToString(&val);
-	} // end-scope 
+	} // end-scope
 	Py_END_ALLOW_THREADS;
 	PyObject *ret;
@@ -179,5 +216,9 @@
 		ret = Py_repr(self);
 	else
+#if PY_MAJOR_VERSION <= 2
 		ret = PyString_FromString(val);
+#else
+		ret = PyUnicode_FromString(val);
+#endif
 	if (val) nsMemory::Free(val);
 	return ret;
@@ -193,8 +234,7 @@
 {
 	static const PyTypeObject type_template = {
-		PyObject_HEAD_INIT(&PyInterfaceType_Type)
-		0,                                           /*ob_size*/
+		PyVarObject_HEAD_INIT(&PyInterfaceType_Type, 0)
 		"XPCOMTypeTemplate",                         /*tp_name*/
-		sizeof(Py_nsISupports),                 /*tp_basicsize*/
+		sizeof(Py_nsISupports),                      /*tp_basicsize*/
 		0,                                           /*tp_itemsize*/
 		Py_dealloc,                                  /* tp_dealloc */
@@ -202,7 +242,11 @@
 		Py_getattr,                                  /* tp_getattr */
 		Py_setattr,                                  /* tp_setattr */
+#if PY_MAJOR_VERSION <= 2
 		Py_cmp,                                      /* tp_compare */
+#else
+		0,                                           /* reserved */
+#endif
 		Py_repr,                                     /* tp_repr */
-    		0,                                           /* tp_as_number*/
+		0,                                           /* tp_as_number*/
 		0,                                           /* tp_as_sequence */
 		0,                                           /* tp_as_mapping */
@@ -211,5 +255,5 @@
 		Py_str,                                      /* tp_str */
 		0,                                           /* tp_getattro */
-		0,                                           /*tp_setattro */
+		0,                                           /* tp_setattro */
 		0,                                           /* tp_as_buffer */
 		0,                                           /* tp_flags */
@@ -217,5 +261,5 @@
 		0,                                           /* tp_traverse */
 		0,                                           /* tp_clear */
-		0,                                           /* tp_richcompare */
+		Py_richcmp,                                  /* tp_richcompare */
 		0,                                           /* tp_weaklistoffset */
 		0,                                           /* tp_iter */
Index: /trunk/src/libs/xpcom18a4/python/src/VariantUtils.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/VariantUtils.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/VariantUtils.cpp	(revision 59809)
@@ -84,4 +84,5 @@
 	PRUint32 size;
 	PyObject *s;
+	void *src;
 	PRUnichar *dest;
 
@@ -89,5 +90,19 @@
 	if (!s)
 		return -1;
+	// Drop the UTF-16 byte order mark at the beginning of
+	// the string.  (See the docs on PyUnicode_AsUTF16String.)
+	// Some Mozilla libraries don't like the mark.
+#if PY_MAJOR_VERSION <= 2
 	size = (PyString_GET_SIZE(s) - 2) / sizeof(PRUnichar);
+	src = PyString_AS_STRING(s) + 2;
+#else
+    if (!PyBytes_Check(obj))
+    {
+        PyErr_SetString(PyExc_TypeError, "internal error in PyXPCOM, parameter must be a bytes object");
+        return -1;
+    }
+    size = (PyBytes_GET_SIZE(obj) - 2) / sizeof(PRUnichar);
+    src = PyBytes_AS_STRING(obj) + 2;
+#endif
 	dest = (PRUnichar *)nsMemory::Alloc(sizeof(PRUnichar) * (size + 1));
 	if (!dest) {
@@ -96,8 +111,5 @@
 		return -1;
 	}
-	// Drop the UTF-16 byte order mark at the beginning of
-	// the string.  (See the docs on PyUnicode_AsUTF16String.)
-	// Some Mozilla libraries don't like the mark.
-	memcpy(dest, PyString_AS_STRING(s) + 2, sizeof(PRUnichar) * size);
+	memcpy(dest, src, sizeof(PRUnichar) * size);
 	Py_DECREF(s);
 	dest[size] = 0;
@@ -116,13 +128,21 @@
 	} else {
 		if (bAssumeUTF8) {
-                        const nsPromiseFlatCString& temp = PromiseFlatCString(s);
-                        ret = PyUnicode_DecodeUTF8(temp.get(), temp.Length(), NULL);
+			const nsPromiseFlatCString& temp = PromiseFlatCString(s);
+			ret = PyUnicode_DecodeUTF8(temp.get(), temp.Length(), NULL);
 		} else {
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromStringAndSize(NULL, s.Length());
+#else
+			ret = PyUnicode_FromStringAndSize(NULL, s.Length());
+#endif
 			if (!ret)
 				return NULL;
 			// Need "CopyAsciiTo"!?
 			nsACString::const_iterator fromBegin, fromEnd;
-			char* dest = PyString_AS_STRING(ret);
+#if PY_MAJOR_VERSION <= 2
+			char* dest = (char *)PyString_AS_STRING(ret);
+#else
+			char* dest = (char *)PyUnicode_AsUTF8(ret);
+#endif
 			copy_string(s.BeginReading(fromBegin), s.EndReading(fromEnd), dest);
 		}
@@ -159,4 +179,5 @@
 	PyObject *val_use = NULL;
 	PRBool ok = PR_TRUE;
+#if PY_MAJOR_VERSION <= 2
 	if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 		PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -165,4 +186,12 @@
 	if (ok && (val_use = PyUnicode_FromObject(val))==NULL)
 		ok = PR_FALSE;
+#else
+    if (!PyUnicode_Check(val)) {
+        PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+        ok = PR_FALSE;
+    }
+    val_use = val;
+    Py_INCREF(val_use);
+#endif
 	if (ok) {
 		if (PyUnicode_GET_SIZE(val_use) == 0) {
@@ -353,16 +382,28 @@
 	// If it is NOT a string, we just fall through and allow the standard
 	// sequence unpack code process it (just slower!)
+#if PY_MAJOR_VERSION <= 2
 	if ( array_type == nsXPTType::T_U8 &&
 		(PyString_Check(sequence_ob) || PyUnicode_Check(sequence_ob))) {
+#else
+	if ( array_type == nsXPTType::T_U8 && PyUnicode_Check(sequence_ob)) {
+#endif
 
 		PRBool release_seq;
 		if (PyUnicode_Check(sequence_ob)) {
 			release_seq = PR_TRUE;
+#if PY_MAJOR_VERSION <= 2
 			sequence_ob = PyObject_Str(sequence_ob);
+#else
+			sequence_ob = PyUnicode_AsUTF8String(sequence_ob);
+#endif
 		} else
 			release_seq = PR_FALSE;
 		if (!sequence_ob) // presumably a memory error, or Unicode encoding error.
 			return PR_FALSE;
+#if PY_MAJOR_VERSION <= 2
 		memcpy(pthis, PyString_AS_STRING(sequence_ob), sequence_size);
+#else
+		memcpy(pthis, PyUnicode_AsUTF8(sequence_ob), sequence_size);
+#endif
 		if (release_seq)
                 {
@@ -423,4 +464,5 @@
 				break;
 			  case nsXPTType::T_CHAR:
+#if PY_MAJOR_VERSION <= 2
 				if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 					PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -432,11 +474,25 @@
 				NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
 				FILL_SIMPLE_POINTER( char, *PyString_AS_STRING(val_use) );
+#else
+				if (!PyUnicode_Check(val)) {
+					PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+					BREAK_FALSE;
+				}
+				FILL_SIMPLE_POINTER( char, *PyUnicode_AsUTF8(val) );
+#endif
 				break;
 
 			  case nsXPTType::T_WCHAR:
+#if PY_MAJOR_VERSION <= 2
 				if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 					PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
 					BREAK_FALSE;
 				}
+#else
+				if (!PyUnicode_Check(val)) {
+					PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+					BREAK_FALSE;
+				}
+#endif
 				if ((val_use = PyUnicode_FromObject(val)) == NULL)
 					BREAK_FALSE;
@@ -474,4 +530,5 @@
 				if (val == Py_None)
 					break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
 				if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 					PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -485,4 +542,15 @@
 				const char *sz = PyString_AS_STRING(val_use);
 				int nch = PyString_GET_SIZE(val_use);
+#else
+				if (!PyUnicode_Check(val)) {
+					PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+					BREAK_FALSE;
+				}
+				if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+					BREAK_FALSE;
+
+				const char *sz = PyBytes_AS_STRING(val_use);
+				int nch = PyBytes_GET_SIZE(val_use);
+#endif
 
 				*pp = (char *)nsMemory::Alloc(nch+1);
@@ -502,4 +570,5 @@
 				if (val == Py_None)
 					break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
 				if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 					PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -509,4 +578,12 @@
 					BREAK_FALSE;
 				NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+				if (!PyUnicode_Check(val)) {
+					PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+					BREAK_FALSE;
+				}
+				val_use = val;
+                Py_INCREF(val_use);
+#endif
 				if (PyUnicode_AsPRUnichar(val_use, pp, NULL) < 0)
 					BREAK_FALSE;
@@ -549,5 +626,9 @@
 	}
 	if (array_type == nsXPTType::T_U8)
+#if PY_MAJOR_VERSION <= 2
 		return PyString_FromStringAndSize( (char *)array_ptr, sequence_size );
+#else
+		return PyUnicode_FromStringAndSize( (char *)array_ptr, sequence_size );
+#endif
 
 	PRUint32 array_element_size = GetArrayElementSize(array_type);
@@ -599,5 +680,9 @@
 					val = Py_None;
 				} else
+#if PY_MAJOR_VERSION <= 2
 					val = PyString_FromString(*pp);
+#else
+					val = PyUnicode_FromString(*pp);
+#endif
 				break;
 				}
@@ -632,5 +717,9 @@
 				sprintf(buf, "Unknown XPCOM array type flags (0x%x)", array_type);
 				PyXPCOM_LogWarning("%s - returning a string object with this message!\n", buf);
+#if PY_MAJOR_VERSION <= 2
 				val = PyString_FromString(buf);
+#else
+				val = PyUnicode_FromString(buf);
+#endif
 				break;
 				}
@@ -670,6 +759,8 @@
 	if (PyFloat_Check(ob))
 		return nsIDataType::VTYPE_DOUBLE;
+#if PY_MAJOR_VERSION <= 2
 	if (PyString_Check(ob))
 		return nsIDataType::VTYPE_STRING_SIZE_IS;
+#endif
 	if (PyUnicode_Check(ob))
 		return nsIDataType::VTYPE_WSTRING_SIZE_IS;
@@ -726,5 +817,12 @@
 			break;
 		case nsIDataType::VTYPE_STRING_SIZE_IS:
+#if PY_MAJOR_VERSION <= 2
 			nr = v->SetAsStringWithSize(PyString_Size(ob), PyString_AsString(ob));
+#else
+            Py_ssize_t cb;
+            const char *psz;
+            psz = PyUnicode_AsUTF8AndSize(ob, &cb);
+			nr = v->SetAsStringWithSize(cb, psz);
+#endif
 			break;
 		case nsIDataType::VTYPE_WSTRING_SIZE_IS:
@@ -1296,4 +1394,5 @@
 			break;
 		  case nsXPTType::T_CHAR:{
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -1310,17 +1409,36 @@
 
 			ns_v.val.c = *PyString_AS_STRING(val_use);
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+			if (PyUnicode_GET_SIZE(val) != 1) {
+				PyErr_SetString(PyExc_ValueError, "Must specify a one character string for a character");
+				BREAK_FALSE;
+			}
+
+			ns_v.val.c = *PyUnicode_AS_UNICODE(val_use);
+#endif
 			break;
 			}
 
 		  case nsXPTType::T_WCHAR: {
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
 				BREAK_FALSE;
 			}
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+#endif
 			if ((val_use = PyUnicode_FromObject(val))==NULL)
 				BREAK_FALSE;
-			// Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+			// Sanity check should PyUnicode_FromObject() ever loosen its semantics wrt Unicode!
 			NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a unicode object!");
-			if (PyUnicode_GetSize(val_use) != 1) {
+			if (PyUnicode_GET_SIZE(val_use) != 1) {
 				PyErr_SetString(PyExc_ValueError, "Must specify a one character string for a character");
 				BREAK_FALSE;
@@ -1360,22 +1478,39 @@
 				ns_v.val.p = new nsCString();
 			} else {
-				// strings are assumed to already be UTF8 encoded.
+#if PY_MAJOR_VERSION <= 2
 				if (PyString_Check(val)) {
+                    // strings are assumed to already be UTF8 encoded.
 					val_use = val;
 					Py_INCREF(val);
-				// Unicode objects are encoded by us.
-				} else if (PyUnicode_Check(val)) {
+				}
+                else
+#endif
+                if (PyUnicode_Check(val)) {
+                    // Unicode objects are encoded by us.
 					if (bIsUTF8)
 						val_use = PyUnicode_AsUTF8String(val);
 					else
+#if PY_MAJOR_VERSION <= 2
 						val_use = PyObject_Str(val);
+#else
+						val_use = PyUnicode_AsUTF8String(val);
+#endif
 				} else {
+#if PY_MAJOR_VERSION <= 2
 					PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be string or Unicode objects");
+#else
+					PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be unicode objects");
+#endif
 					BREAK_FALSE;
 				}
 				if (!val_use)
 					BREAK_FALSE;
+#if PY_MAJOR_VERSION <= 2
 				ns_v.val.p = new nsCString(PyString_AS_STRING(val_use),
 				                           PyString_GET_SIZE(val_use));
+#else
+				ns_v.val.p = new nsCString(PyBytes_AS_STRING(val_use),
+				                           PyBytes_GET_SIZE(val_use));
+#endif
 			}
 
@@ -1393,8 +1528,9 @@
 				break;
 			}
+#if PY_MAJOR_VERSION <= 2
 			// If an "in" char *, and we have a PyString, then pass the
 			// pointer (hoping everyone else plays by the rules too.
 			if (!XPT_PD_IS_OUT(td.param_flags) && PyString_Check(val)) {
-				ns_v.val.p = PyString_AS_STRING(val);
+				ns_v.val.p = (void *)PyString_AS_STRING(val);
 				break;
 			}
@@ -1412,4 +1548,17 @@
 			MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
 			memcpy(this_buffer_pointer, PyString_AS_STRING(val_use), cb_this_buffer_pointer);
+#else
+
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+			if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+				BREAK_FALSE;
+
+			cb_this_buffer_pointer = PyBytes_GET_SIZE(val_use)+1;
+			MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+			memcpy(this_buffer_pointer, PyBytes_AS_STRING(val_use), cb_this_buffer_pointer);
+#endif
 			ns_v.val.p = this_buffer_pointer;
 			break;
@@ -1421,4 +1570,5 @@
 				break;
 			}
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -1428,4 +1578,12 @@
 				BREAK_FALSE;
 			NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+            val_use = val;
+            Py_INCREF(val_use);
+#endif
 			PRUnichar *sv;
 			PRUint32 nch;
@@ -1484,4 +1642,5 @@
 				break;
 			}
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -1496,4 +1655,16 @@
 			MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
 			memcpy(this_buffer_pointer, PyString_AS_STRING(val_use), cb_this_buffer_pointer);
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+			if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+				BREAK_FALSE;
+
+			cb_this_buffer_pointer = PyBytes_GET_SIZE(val_use);
+			MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+			memcpy(this_buffer_pointer, PyBytes_AS_STRING(val_use), cb_this_buffer_pointer);
+#endif
 			ns_v.val.p = this_buffer_pointer;
 			rc = SetSizeIs(value_index, PR_TRUE, cb_this_buffer_pointer);
@@ -1506,4 +1677,5 @@
 				break;
 			}
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -1514,4 +1686,12 @@
 			// Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
 			NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyObject_Unicode didnt return a unicode object!");
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+            val_use = val;
+            Py_INCREF(val_use);
+#endif
 			PRUnichar *sv;
 			PRUint32 nch;
@@ -1719,5 +1899,9 @@
 		break;
 	  case nsXPTType::T_CHAR:
+#if PY_MAJOR_VERSION <= 2
 		ret = PyString_FromStringAndSize( ((char *)ns_v.ptr), 1 );
+#else
+		ret = PyUnicode_FromStringAndSize( ((char *)ns_v.ptr), 1 );
+#endif
 		break;
 
@@ -1747,5 +1931,9 @@
 			Py_INCREF(Py_None);
 		} else
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromString( *((char **)ns_v.ptr) );
+#else
+			ret = PyUnicode_FromString( *((char **)ns_v.ptr) );
+#endif
 		break;
 
@@ -1828,5 +2016,9 @@
 		} else {
 			PRUint32 string_size = GetSizeIs(index, PR_TRUE);
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromStringAndSize( *((char **)ns_v.ptr), string_size );
+#else
+			ret = PyUnicode_FromStringAndSize( *((char **)ns_v.ptr), string_size );
+#endif
 		}
 		break;
@@ -2083,5 +2275,9 @@
 	  case nsXPTType::T_CHAR: {
 		char temp = DEREF_IN_OR_OUT(ns_v.val.c, char);
+#if PY_MAJOR_VERSION <= 2
 		ret = PyString_FromStringAndSize(&temp, 1);
+#else
+		ret = PyUnicode_FromStringAndSize(&temp, 1);
+#endif
 		break;
 		}
@@ -2116,5 +2312,9 @@
 			Py_INCREF(Py_None);
 		} else
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromString(t);
+#else
+			ret = PyUnicode_FromString(t);
+#endif
 		break;
 		}
@@ -2178,5 +2378,9 @@
 			Py_INCREF(Py_None);
 		} else
+#if PY_MAJOR_VERSION <= 2
 			ret = PyString_FromStringAndSize(t, string_size);
+#else
+			ret = PyUnicode_FromStringAndSize(t, string_size);
+#endif
 		break;
 		}
@@ -2199,5 +2403,9 @@
 		sprintf(buf, "Unknown XPCOM type flags (0x%x)", td.type_flags);
 		PyXPCOM_LogWarning("%s - returning a string object with this message!\n", buf);
+#if PY_MAJOR_VERSION <= 2
 		ret = PyString_FromString(buf);
+#else
+		ret = PyUnicode_FromString(buf);
+#endif
 		break;
 		}
@@ -2340,4 +2548,5 @@
 		break;
 	  case nsXPTType::T_CHAR:
+#if PY_MAJOR_VERSION <= 2
 		if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 			PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -2349,11 +2558,25 @@
 		NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
 		FILL_SIMPLE_POINTER( char, *PyString_AS_STRING(val_use) );
+#else
+		if (!PyUnicode_Check(val)) {
+			PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+			BREAK_FALSE;
+		}
+		FILL_SIMPLE_POINTER( char, *PyUnicode_AS_UNICODE(val) );
+#endif
 		break;
 
 	  case nsXPTType::T_WCHAR:
+#if PY_MAJOR_VERSION <= 2
 		if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 			PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
 			BREAK_FALSE;
 		}
+#else
+		if (!PyUnicode_Check(val)) {
+			PyErr_SetString(PyExc_TypeError, "This parameter must be a Unicode object");
+			BREAK_FALSE;
+		}
+#endif
 		if ((val_use = PyUnicode_FromObject(val))==NULL)
 			BREAK_FALSE;
@@ -2395,4 +2618,5 @@
 			NS_ABORT_IF_FALSE(0, "dont handle None here yet");
 		} else {
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -2402,5 +2626,14 @@
 			NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
 			const char *sz = PyString_AS_STRING(val_use);
-			ws->Assign(sz, PyString_Size(val_use));
+			ws->Assign(sz, PyString_GET_SIZE(val_use));
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+			val_use = PyUnicode_AsUTF8String(val);
+			const char *sz = PyBytes_AS_STRING(val_use);
+			ws->Assign(sz, PyBytes_GET_SIZE(val_use));
+#endif
 		}
 		break;
@@ -2412,16 +2645,30 @@
 			NS_ABORT_IF_FALSE(0, "dont handle None here yet");
 		} else {
+#if PY_MAJOR_VERSION <= 2
 			if (PyString_Check(val)) {
 				val_use = val;
 				Py_INCREF(val);
-			} else if (PyUnicode_Check(val)) {
+			}
+            else
+#endif
+            if (PyUnicode_Check(val)) {
 				val_use = PyUnicode_AsUTF8String(val);
 			} else {
+#if PY_MAJOR_VERSION <= 2
 				PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be string or Unicode objects");
-				BREAK_FALSE;
-			}
+#else
+				PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be unicode objects");
+#endif
+				BREAK_FALSE;
+			}
+#if PY_MAJOR_VERSION <= 2
 			NS_ABORT_IF_FALSE(PyString_Check(val_use), "must have a string object!");
 			const char *sz = PyString_AS_STRING(val_use);
-			ws->Assign(sz, PyString_Size(val_use));
+			ws->Assign(sz, PyString_GET_SIZE(val_use));
+#else
+			NS_ABORT_IF_FALSE(PyBytes_Check(val_use), "must have a bytes object!");
+			const char *sz = PyBytes_AS_STRING(val_use);
+			ws->Assign(sz, PyBytes_GET_SIZE(val_use));
+#endif
 		}
 		break;
@@ -2437,4 +2684,5 @@
 		if (val == Py_None)
 			break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
 		if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 			PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -2448,4 +2696,15 @@
 		const char *sz = PyString_AS_STRING(val_use);
 		int nch = PyString_GET_SIZE(val_use);
+#else
+		if (!PyUnicode_Check(val)) {
+			PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+			BREAK_FALSE;
+		}
+		if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+			BREAK_FALSE;
+
+		const char *sz = PyBytes_AS_STRING(val_use);
+		int nch = PyBytes_GET_SIZE(val_use);
+#endif
 
 		*pp = (char *)nsMemory::Alloc(nch+1);
@@ -2465,4 +2724,5 @@
 		if (val == Py_None)
 			break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
 		if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 			PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -2471,4 +2731,12 @@
 		val_use = PyUnicode_FromObject(val);
 		NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+		if (!PyUnicode_Check(val)) {
+			PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+			BREAK_FALSE;
+		}
+        val_use = val;
+        Py_INCREF(val_use);
+#endif
 		if (PyUnicode_AsPRUnichar(val_use, pp, NULL) < 0)
 			BREAK_FALSE;
@@ -2525,4 +2793,5 @@
 		PRUint32 nch = 0;
 		if (val != Py_None) {
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -2536,4 +2805,15 @@
 			sz = PyString_AS_STRING(val_use);
 			nch = PyString_GET_SIZE(val_use);
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+			if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+				BREAK_FALSE;
+
+			sz = PyBytes_AS_STRING(val_use);
+			nch = PyBytes_GET_SIZE(val_use);
+#endif
 		}
 		PRBool bBackFill = PR_FALSE;
@@ -2582,4 +2862,5 @@
 
 		if (val != Py_None) {
+#if PY_MAJOR_VERSION <= 2
 			if (!PyString_Check(val) && !PyUnicode_Check(val)) {
 				PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
@@ -2588,4 +2869,12 @@
 			val_use = PyUnicode_FromObject(val);
 			NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+			if (!PyUnicode_Check(val)) {
+				PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+				BREAK_FALSE;
+			}
+            val_use = val;
+            Py_INCREF(val_use);
+#endif
 			if (PyUnicode_AsPRUnichar(val_use, &sz, &nch) < 0)
 				BREAK_FALSE;
@@ -2750,5 +3039,9 @@
 		// But the retval is often the last param described in the info.
 		if (!PySequence_Check(user_result) ||
+#if PY_MAJOR_VERSION <= 2
 		     PyString_Check(user_result) ||
+#else
+		     PyBytes_Check(user_result) ||
+#endif
 		     PyUnicode_Check(user_result)) {
 			PyErr_SetString(PyExc_TypeError, "This function has multiple results, but a sequence was not given to fill them");
Index: /trunk/src/libs/xpcom18a4/python/src/dllmain.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/dllmain.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/dllmain.cpp	(revision 59809)
@@ -196,5 +196,5 @@
 	CEnterLeaveXPCOMFramework _celf;
 	PRInt32 cnt = PR_AtomicIncrement(&g_cLockCount);
-	if (cnt==1) { // First call 
+	if (cnt==1) { // First call
 		if (!Py_IsInitialized()) {
 			Py_Initialize();
@@ -204,5 +204,9 @@
 			if (PySys_GetObject((char*)"argv")==NULL) {
 				PyObject *path = PyList_New(0);
+#if PY_MAJOR_VERSION <= 2
 				PyObject *str = PyString_FromString("");
+#else
+				PyObject *str = PyUnicode_FromString("");
+#endif
 				PyList_Append(path, str);
 				PySys_SetObject((char*)"argv", path);
@@ -246,5 +250,5 @@
 	PR_DestroyLock(g_lockMain);
 #ifndef PYXPCOM_USE_PYGILSTATE
-	// I can't locate a way to kill this - 
+	// I can't locate a way to kill this -
 	// should I pass a dtor to PR_NewThreadPrivateIndex??
 	// TlsFree(tlsIndex);
@@ -330,5 +334,5 @@
 		bHaveInitXPCOM = PR_TRUE;
 		// Register our custom interfaces.
-	
+
 		Py_nsISupports::InitType();
 		Py_nsIComponentManager::InitType();
@@ -342,5 +346,5 @@
 		// for backward compatibility:
 		Py_nsIComponentManagerObsolete::InitType();
-		
+
 	}
 	return rc;
Index: /trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp
===================================================================
--- /trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp	(revision 59808)
+++ /trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp	(revision 59809)
@@ -84,33 +84,57 @@
 # endif
 # ifdef VBOX_PYXPCOM_VERSIONED
-#  if   PY_VERSION_HEX >= 0x02080000
+#  if   PY_VERSION_HEX >= 0x03080000 && PY_VERSION_HEX < 0x03090000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_8")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_8)
+
+#  elif PY_VERSION_HEX >= 0x03070000 && PY_VERSION_HEX < 0x03080000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_7")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_7)
+
+#  elif PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x03070000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_6")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_6)
+
+#  elif PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03060000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_5")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_5)
+
+#  elif PY_VERSION_HEX >= 0x03040000 && PY_VERSION_HEX < 0x03050000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_4")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_4)
+
+#  elif PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x03040000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_3")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_3)
+
+#  elif PY_VERSION_HEX >= 0x03020000 && PY_VERSION_HEX < 0x03030000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_2")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_2)
+
+#  elif PY_VERSION_HEX >= 0x03010000 && PY_VERSION_HEX < 0x03020000
+#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython3_1")
+#   define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_1)
+
+#  elif PY_VERSION_HEX >= 0x02080000 && PY_VERSION_HEX < 0x02090000
 #   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython2_8")
 #   define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_8)
 
-#  elif PY_VERSION_HEX >= 0x02070000
+#  elif PY_VERSION_HEX >= 0x02070000 && PY_VERSION_HEX < 0x02080000
 #   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython2_7")
 #   define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_7)
 
-#  elif PY_VERSION_HEX >= 0x02060000
+#  elif PY_VERSION_HEX >= 0x02060000 && PY_VERSION_HEX < 0x02070000
 #   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython2_6")
 #   define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_6)
-
-#  elif PY_VERSION_HEX >= 0x02050000
-#   define MODULE_NAME 	  MANGLE_MODULE_NAME("VBoxPython2_5")
-#   define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_5)
-
-#  elif PY_VERSION_HEX >= 0x02040000
-#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython2_4")
-#   define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_4)
-
-#  elif PY_VERSION_HEX >= 0x02030000
-#   define MODULE_NAME    MANGLE_MODULE_NAME("VBoxPython2_3")
-#   define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_3)
 #  else
-#   error "Fix module versioning."
+#   error "Fix module versioning. This Python version is not recognized."
 #  endif
 # else
 #  define MODULE_NAME 	  MANGLE_MODULE_NAME("VBoxPython")
-#  define initVBoxPython  MANGLE_MODULE_INIT(initVBoxPython)
+#  if PY_MAJOR_VERSION <= 2
+#   define initVBoxPython  MANGLE_MODULE_INIT(initVBoxPython)
+#  else
+#   define initVBoxPython  MANGLE_MODULE_INIT(PyInit_VBoxPython)
+#  endif
 # endif
 #else
@@ -121,4 +145,5 @@
 // interface support!
 
+#ifndef VBOX
 /* deprecated, included for backward compatibility */
 static PyObject *
@@ -143,4 +168,5 @@
 	return Py_nsISupports::PyObjectFromInterface(ocm, NS_GET_IID(nsIComponentManagerObsolete), PR_FALSE);
 }
+#endif
 
 static PyObject *
@@ -195,4 +221,5 @@
 }
 
+#ifndef VBOX
 /* deprecated, included for backward compatibility */
 static PyObject *
@@ -204,4 +231,5 @@
 	return PyXPCOMMethod_GetComponentManager(self, args);
 }
+#endif
 
 static PyObject *
@@ -500,5 +528,9 @@
 	if (!PyArg_ParseTuple(args, "i", &bufSize))
 		return NULL;
+#if PY_MAJOR_VERSION <= 2
 	return PyBuffer_New(bufSize);
+#else
+    return PyBytes_FromStringAndSize(NULL, bufSize);
+#endif
 }
 
@@ -671,10 +703,14 @@
 	{"GetComponentManager", PyXPCOMMethod_GetComponentManager, 1},
 	{"GetComponentRegistrar", PyXPCOMMethod_GetComponentRegistrar, 1},
+#ifndef VBOX
 	{"NS_GetGlobalComponentManager", PyXPCOMMethod_NS_GetGlobalComponentManager, 1}, // deprecated
+#endif
 	{"XPTI_GetInterfaceInfoManager", PyXPCOMMethod_XPTI_GetInterfaceInfoManager, 1},
 	{"XPTC_InvokeByIndex", PyXPCOMMethod_XPTC_InvokeByIndex, 1},
 	{"GetServiceManager", PyXPCOMMethod_GetServiceManager, 1},
+#ifndef VBOX
 	{"GetGlobalServiceManager", PyXPCOMMethod_GetGlobalServiceManager, 1}, // deprecated
 	{"IID", PyXPCOMMethod_IID, 1}, // IID is wrong - deprecated - not just IID, but CID, etc.
+#endif
 	{"ID", PyXPCOMMethod_IID, 1}, // This is the official name.
 	{"NS_ShutdownXPCOM", PyXPCOMMethod_NS_ShutdownXPCOM, 1},
@@ -691,9 +727,9 @@
 	{"GetVariantValue", PyXPCOMMethod_GetVariantValue, 1},
 #ifdef VBOX
-        {"WaitForEvents", PyXPCOMMethod_WaitForEvents, 1},
-        {"InterruptWait", PyXPCOMMethod_InterruptWait, 1},
-        {"DeinitCOM",     PyXPCOMMethod_DeinitCOM, 1},
-        {"AttachThread",  PyXPCOMMethod_AttachThread, 1},
-        {"DetachThread",  PyXPCOMMethod_DetachThread, 1},
+    {"WaitForEvents", PyXPCOMMethod_WaitForEvents, 1},
+    {"InterruptWait", PyXPCOMMethod_InterruptWait, 1},
+    {"DeinitCOM",     PyXPCOMMethod_DeinitCOM, 1},
+    {"AttachThread",  PyXPCOMMethod_AttachThread, 1},
+    {"DetachThread",  PyXPCOMMethod_DetachThread, 1},
 #endif
 #ifdef VBOX_DEBUG_LIFETIMES
@@ -705,4 +741,16 @@
 };
 
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef xpcom_module =
+{
+    PyModuleDef_HEAD_INIT,
+    MODULE_NAME,    /* name of module */
+    NULL,           /* module documentation */
+    -1,             /* size of per-interpreter state or -1 if using globals */
+    xpcom_methods
+};
+#endif
+
+
 #define REGISTER_IID(t) { \
 	PyObject *iid_ob = Py_nsIID::PyObjectFromIID(NS_GET_IID(t)); \
@@ -721,6 +769,10 @@
 // The module init code.
 //
+#if PY_MAJOR_VERSION <= 2
 extern "C" NS_EXPORT
 void
+#else
+PyObject *
+#endif
 init_xpcom() {
 	PyObject *oModule;
@@ -728,5 +780,9 @@
 	// ensure the framework has valid state to work with.
 	if (!PyXPCOM_Globals_Ensure())
+#if PY_MAJOR_VERSION <= 2
 		return;
+#else
+		return NULL;
+#endif
 
 	// Must force Python to start using thread locks
@@ -734,5 +790,9 @@
 
 	// Create the module and add the functions
+#if PY_MAJOR_VERSION <= 2
 	oModule = Py_InitModule(MODULE_NAME, xpcom_methods);
+#else
+	oModule = PyModule_Create(&xpcom_module);
+#endif
 
 	PyObject *dict = PyModule_GetDict(oModule);
@@ -741,5 +801,9 @@
 	{
 		PyErr_SetString(PyExc_MemoryError, "can't define error");
+#if PY_MAJOR_VERSION <= 2
 		return;
+#else
+		return NULL;
+#endif
 	}
 	PyDict_SetItemString(dict, "IIDType", (PyObject *)&Py_nsIID::type);
@@ -784,4 +848,7 @@
     PyDict_SetItemString(dict, "NS_DEBUG", ob);
     Py_DECREF(ob);
+#if PY_MAJOR_VERSION >= 3
+    return oModule;
+#endif
 }
 
@@ -795,6 +862,15 @@
 #include <iprt/stream.h>
 
+#if PY_MAJOR_VERSION <= 2
 extern "C" NS_EXPORT
 void
+#else
+/** @todo r=klaus this is hacky, but as Python3 doesn't deal with ELF
+ * visibility, assuming that all globals are visible (which is ugly and not
+ * true in our case). */
+#undef PyMODINIT_FUNC
+#define PyMODINIT_FUNC extern "C" NS_EXPORT PyObject*
+PyMODINIT_FUNC
+#endif
 initVBoxPython() { /* NOTE! This name is redefined at the top of the file! */
   static bool s_vboxInited = false;
@@ -819,6 +895,13 @@
     rc = com::Initialize();
 
+#if PY_MAJOR_VERSION <= 2
     init_xpcom();
+#else
+    return init_xpcom();
+#endif
   }
+#if PY_MAJOR_VERSION >= 3
+  return NULL;
+#endif
 }
 
