diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py
index 2a426fe35a0969b1646c1e853522f5b2f71acc3f..1cf091eac28861aacb350c8917aff8e802e3135f 100644
--- a/Cython/Compiler/Code.py
+++ b/Cython/Compiler/Code.py
@@ -943,6 +943,15 @@ class CCodeWriter(object):
     def put_finish_refcount_context(self):
         self.putln("__Pyx_FinishRefcountContext();")
 
+    def put_trace_call(self, name, pos):
+        self.putln('__Pyx_TraceCall("%s", %s[%s], %s);' % (name, Naming.filetable_cname, self.lookup_filename(pos[0]), pos[1]));
+    
+    def put_trace_exception(self):
+        self.putln("__Pyx_TraceException();")
+    
+    def put_trace_return(self, retvalue_cname):
+        self.putln("__Pyx_TraceReturn(%s);" % retvalue_cname)
+
 
 class PyrexCodeWriter(object):
     # f                file      output file
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index cb59255e10fdfc4e6ab5124ec7e44adb438d2797..1922db255530e4a1bff3d82aa96c0886484c7d40 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -2578,6 +2578,9 @@ class GeneralCallNode(CallNode):
         if self.starstar_arg:
             self.starstar_arg.analyse_types(env)
         if not self.function.type.is_pyobject:
+            if self.function.type.is_error:
+                self.type = error_type
+                return error_type
             if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
                 error(self.pos, "Keyword arguments not allowed in cdef functions.")
             else:
@@ -2592,6 +2595,7 @@ class GeneralCallNode(CallNode):
         self.is_temp = 1
         
     def generate_result_code(self, code):
+        if self.type.is_error: return
         if self.keyword_args and self.starstar_arg:
             code.put_error_if_neg(self.pos, 
                 "PyDict_Update(%s, %s)" % (
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 63b72a3a2b88c2a76d0b51a2fdc0550d38fecca9..9f61513ebe982345efe36ddff71697c36522546b 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -573,6 +573,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln('static PyObject *%s;' % env.module_cname)
         code.putln('static PyObject *%s;' % Naming.builtins_cname)
         code.putln('static PyObject *%s;' % Naming.empty_tuple)
+        code.putln('static PyObject *%s;' % Naming.empty_bytes)
         if Options.pre_import is not None:
             code.putln('static PyObject *%s;' % Naming.preimport_cname)
         code.putln('static int %s;' % Naming.lineno_cname)
@@ -588,8 +589,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             code.putln('static char %s[] = "%s";' % (
                     env.doc_cname, escape_byte_string(docstr)))
 
-        env.use_utility_code(streq_utility_code)
-
         # XXX this is a mess
         for utility_code in PyrexTypes.c_int_from_py_function.specialize_list:
             env.use_utility_code(utility_code)
@@ -1556,6 +1555,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
         
     def generate_import_star(self, env, code):
+        env.use_utility_code(streq_utility_code)
         code.putln()
         code.putln("char* %s_type_names[] = {" % Naming.import_star)
         for name, entry in env.entries.items():
@@ -1648,6 +1648,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("#endif")
 
         code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
+        code.putln("#if PY_MAJOR_VERSION < 3");
+        code.putln("%s = PyString_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
+        code.putln("#else");
+        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
+        code.putln("#endif");
 
         code.putln("/*--- Library function declarations ---*/")
         env.generate_library_function_declarations(code)
@@ -2475,6 +2480,7 @@ static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
 #define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
 """)
 
+
 main_method = UtilityCode(
 impl = """
 #if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
diff --git a/Cython/Compiler/Naming.py b/Cython/Compiler/Naming.py
index e12a40480ddd28f0520a75e47630853f55cc330e..b659199a9df2906b3291e479cf83ed737901cabf 100644
--- a/Cython/Compiler/Naming.py
+++ b/Cython/Compiler/Naming.py
@@ -74,6 +74,7 @@ c_api_tab_cname  = pyrex_prefix + "c_api_tab"
 gilstate_cname   = pyrex_prefix + "state"
 skip_dispatch_cname = pyrex_prefix + "skip_dispatch"
 empty_tuple      = pyrex_prefix + "empty_tuple"
+empty_bytes      = pyrex_prefix + "empty_bytes"
 print_function   = pyrex_prefix + "print"
 print_function_kwargs   = pyrex_prefix + "print_kwargs"
 cleanup_cname    = pyrex_prefix + "module_cleanup"
@@ -83,6 +84,8 @@ import_star      = pyrex_prefix + "import_star"
 import_star_set  = pyrex_prefix + "import_star_set"
 cur_scope_cname  = pyrex_prefix + "cur_scope"
 enc_scope_cname  = pyrex_prefix + "enc_scope"
+frame_cname      = pyrex_prefix + "frame"
+frame_code_cname = pyrex_prefix + "frame_code"
 
 line_c_macro = "__LINE__"
 
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index 4e1c860617e9d9a50bbf17d44993e334a21eeef6..efba286bb1e1cbd9dd9867bdf2ea859e6d2a3bd6 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -801,25 +801,18 @@ class CVarDefNode(StatNode):
         self.dest_scope = dest_scope
         base_type = self.base_type.analyse(env)
 
-        need_property = False
+        # If the field is an external typedef, we cannot be sure about the type,
+        # so do conversion ourself rather than rely on the CPython mechanism (through
+        # a property; made in AnalyseDeclarationsTransform).
         if (dest_scope.is_c_class_scope
-              and self.visibility == 'public'
-              and base_type.is_pyobject
-              and (base_type.is_builtin_type or base_type.is_extension_type)):
-            # If the field is settable and extension type, then the CPython mechanism does
-            # not do enough type-checking for us.
-            need_property = True
-        elif (base_type.is_typedef and base_type.typedef_is_external
-              and (self.visibility in ('public', 'readonly'))):
-            # If the field is an external typedef, we cannot be sure about the type,
-            # so do conversion ourself rather than rely on the CPython mechanism (through
-            # a property; made in AnalyseDeclarationsTransform).
+                and self.visibility == 'public' 
+                and base_type.is_pyobject 
+                and (base_type.is_builtin_type or base_type.is_extension_type)):
+            self.need_properties = []
             need_property = True
-
-        if need_property:
             visibility = 'private'
-            self.need_properties = []
         else:
+            need_property = False
             visibility = self.visibility
             
         for declarator in self.declarators:
@@ -1009,6 +1002,7 @@ class FuncDefNode(StatNode, BlockNode):
     py_func = None
     assmt = None
     needs_closure = False
+    modifiers = []
     
     def analyse_default_values(self, env):
         genv = env.global_scope()
@@ -1061,6 +1055,15 @@ class FuncDefNode(StatNode, BlockNode):
 
         is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
                              self.entry.scope.is_c_class_scope)
+        
+        if code.globalstate.directives['profile'] is None:
+            profile = 'inline' not in self.modifiers and not lenv.nogil
+        else:
+            profile = code.globalstate.directives['profile']
+            if profile and lenv.nogil:
+                error(self.pos, "Cannot profile nogil function.")
+        if profile:
+            code.globalstate.use_utility_code(trace_utility_code)
 
         # Generate C code for header and body of function
         code.enter_cfunc_scope()
@@ -1108,6 +1111,8 @@ class FuncDefNode(StatNode, BlockNode):
             env.use_utility_code(force_init_threads_utility_code)
             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
         # ----- Automatic lead-ins for certain special functions
+        if profile:
+            code.put_trace_call(self.entry.name, self.pos)
         if not lenv.nogil:
             code.put_setup_refcount_context(self.entry.name)
         if is_getbuffer_slot:
@@ -1172,6 +1177,9 @@ class FuncDefNode(StatNode, BlockNode):
             err_val = self.error_value()
             exc_check = self.caller_will_check_exceptions()
             if err_val is not None or exc_check:
+                # TODO: Fix exception tracing (though currently unused by cProfile). 
+                # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
+                # code.put_trace_exception()
                 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
             else:
                 warning(self.entry.pos, "Unraisable exception in function '%s'." \
@@ -1201,9 +1209,6 @@ class FuncDefNode(StatNode, BlockNode):
 
 
         # ----- Non-error return cleanup
-        # If you add anything here, remember to add a condition to the
-        # if-test above in the error block (so that it can jump past this
-        # block).
         code.put_label(code.return_label)
         for entry in lenv.buffer_entries:
             if entry.used:
@@ -1235,6 +1240,17 @@ class FuncDefNode(StatNode, BlockNode):
 
             code.put_finish_refcount_context()
 
+        if self.entry.is_special and self.entry.name == "__hash__":
+            # Returning -1 for __hash__ is supposed to signal an error
+            # We do as Python instances and coerce -1 into -2. 
+            code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
+
+        if profile:
+            if self.return_type.is_pyobject:
+                code.put_trace_return(Naming.retval_cname)
+            else:
+                code.put_trace_return("Py_None")
+        
         if acquire_gil:
             code.putln("PyGILState_Release(_save);")
 
@@ -1334,7 +1350,7 @@ class CFuncDefNode(FuncDefNode):
         return self.entry.name
         
     def analyse_declarations(self, env):
-        directive_locals = self.directive_locals = env.directives['locals']
+        self.directive_locals.update(env.directives['locals'])
         base_type = self.base_type.analyse(env)
         # The 2 here is because we need both function and argument names. 
         name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
@@ -5414,7 +5430,6 @@ static void __Pyx_AddTraceback(const char *funcname) {
     PyObject *py_srcfile = 0;
     PyObject *py_funcname = 0;
     PyObject *py_globals = 0;
-    PyObject *empty_string = 0;
     PyCodeObject *py_code = 0;
     PyFrameObject *py_frame = 0;
 
@@ -5441,12 +5456,6 @@ static void __Pyx_AddTraceback(const char *funcname) {
     if (!py_funcname) goto bad;
     py_globals = PyModule_GetDict(%(GLOBALS)s);
     if (!py_globals) goto bad;
-    #if PY_MAJOR_VERSION < 3
-    empty_string = PyString_FromStringAndSize("", 0);
-    #else
-    empty_string = PyBytes_FromStringAndSize("", 0);
-    #endif
-    if (!empty_string) goto bad;
     py_code = PyCode_New(
         0,            /*int argcount,*/
         #if PY_MAJOR_VERSION >= 3
@@ -5455,7 +5464,7 @@ static void __Pyx_AddTraceback(const char *funcname) {
         0,            /*int nlocals,*/
         0,            /*int stacksize,*/
         0,            /*int flags,*/
-        empty_string, /*PyObject *code,*/
+        %(EMPTY_BYTES)s, /*PyObject *code,*/
         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
@@ -5464,7 +5473,7 @@ static void __Pyx_AddTraceback(const char *funcname) {
         py_srcfile,   /*PyObject *filename,*/
         py_funcname,  /*PyObject *name,*/
         %(LINENO)s,   /*int firstlineno,*/
-        empty_string  /*PyObject *lnotab*/
+        %(EMPTY_BYTES)s  /*PyObject *lnotab*/
     );
     if (!py_code) goto bad;
     py_frame = PyFrame_New(
@@ -5479,7 +5488,6 @@ static void __Pyx_AddTraceback(const char *funcname) {
 bad:
     Py_XDECREF(py_srcfile);
     Py_XDECREF(py_funcname);
-    Py_XDECREF(empty_string);
     Py_XDECREF(py_code);
     Py_XDECREF(py_frame);
 }
@@ -5490,6 +5498,7 @@ bad:
     'CLINENO':  Naming.clineno_cname,
     'GLOBALS': Naming.module_cname,
     'EMPTY_TUPLE' : Naming.empty_tuple,
+    'EMPTY_BYTES' : Naming.empty_bytes,
 })
 
 restore_exception_utility_code = UtilityCode(
@@ -5704,6 +5713,31 @@ bad:
 
 #------------------------------------------------------------------------------------
 
+get_exception_tuple_utility_code = UtilityCode(proto="""
+static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
+""",
+impl = """
+static PyObject *__Pyx_GetExceptionTuple(void) {
+    PyObject *type = NULL, *value = NULL, *tb = NULL;
+    if (__Pyx_GetException(&type, &value, &tb) == 0) {
+        PyObject* exc_info = PyTuple_New(3);
+        if (exc_info) {
+            Py_INCREF(type);
+            Py_INCREF(value);
+            Py_INCREF(tb);
+            PyTuple_SET_ITEM(exc_info, 0, type);
+            PyTuple_SET_ITEM(exc_info, 1, value);
+            PyTuple_SET_ITEM(exc_info, 2, tb);
+            return exc_info;
+        }
+    }
+    return NULL;
+}
+""",
+requires=[get_exception_utility_code])
+
+#------------------------------------------------------------------------------------
+
 reset_exception_utility_code = UtilityCode(
 proto = """
 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
@@ -5749,3 +5783,143 @@ proto="""
 """)
 
 #------------------------------------------------------------------------------------
+
+# Note that cPython ignores PyTrace_EXCEPTION, 
+# but maybe some other profilers don't. 
+
+trace_utility_code = UtilityCode(proto="""
+#ifndef CYTHON_TRACING
+#define CYTHON_TRACING 1
+#endif
+
+#ifndef CYTHON_TRACING_REUSE_FRAME
+#define CYTHON_TRACING_REUSE_FRAME 0
+#endif
+
+#if CYTHON_TRACING
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+#if CYTHON_TRACING_REUSE_FRAME
+#define CYTHON_FRAME_MODIFIER static
+#define CYTHON_FRAME_DEL
+#else
+#define CYTHON_FRAME_MODIFIER
+#define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
+#endif
+
+#define __Pyx_TraceCall(funcname, srcfile, firstlineno)                            \\
+static PyCodeObject *%(FRAME_CODE)s = NULL;                                        \\
+CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL;                             \\
+int __Pyx_use_tracing = 0;                                                         \\
+if (PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {      \\
+    __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno);  \\
+}
+
+#define __Pyx_TraceException()                                                           \\
+if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
+    PyObject *exc_info = __Pyx_GetExceptionTuple();                                      \\
+    if (exc_info) {                                                                      \\
+        PyThreadState_GET()->c_profilefunc(                                              \\
+            PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info);  \\
+        Py_DECREF(exc_info);                                                             \\
+    }                                                                                    \\
+}
+
+#define __Pyx_TraceReturn(result)                                                  \\
+if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
+    PyThreadState_GET()->c_profilefunc(                                            \\
+        PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result);     \\
+    CYTHON_FRAME_DEL;                                                               \\
+}
+
+static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
+static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
+
+#else
+#define __Pyx_TraceCall(funcname, srcfile, firstlineno) 
+#define __Pyx_TraceException() 
+#define __Pyx_TraceReturn(result) 
+#endif /* CYTHON_TRACING */
+""" 
+% {
+    "FRAME": Naming.frame_cname,
+    "FRAME_CODE": Naming.frame_code_cname,
+},
+impl = """
+
+#if CYTHON_TRACING
+
+static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
+                                   PyFrameObject** frame,
+                                   const char *funcname,
+                                   const char *srcfile,
+                                   int firstlineno) {
+    if (*frame == NULL || !CYTHON_TRACING_REUSE_FRAME) {
+        if (*code == NULL) {
+            *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
+            if (*code == NULL) return 0;
+        }
+        *frame = PyFrame_New(
+            PyThreadState_GET(),            /*PyThreadState *tstate*/
+            *code,                          /*PyCodeObject *code*/
+            PyModule_GetDict(%(MODULE)s),      /*PyObject *globals*/
+            0                               /*PyObject *locals*/
+        );
+        if (*frame == NULL) return 0;
+    }
+    else {
+        (*frame)->f_tstate = PyThreadState_GET();
+    }
+    return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
+}
+
+static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    PyCodeObject *py_code = 0;
+
+    #if PY_MAJOR_VERSION < 3
+    py_funcname = PyString_FromString(funcname);
+    py_srcfile = PyString_FromString(srcfile);
+    #else
+    py_funcname = PyUnicode_FromString(funcname);
+    py_srcfile = PyUnicode_FromString(srcfile);
+    #endif
+    if (!py_funcname | !py_srcfile) goto bad;
+
+    py_code = PyCode_New(
+        0,                /*int argcount,*/
+        #if PY_MAJOR_VERSION >= 3
+        0,                /*int kwonlyargcount,*/
+        #endif
+        0,                /*int nlocals,*/
+        0,                /*int stacksize,*/
+        0,                /*int flags,*/
+        %(EMPTY_BYTES)s,  /*PyObject *code,*/
+        %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
+        %(EMPTY_TUPLE)s,  /*PyObject *names,*/
+        %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
+        %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
+        %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
+        py_srcfile,       /*PyObject *filename,*/
+        py_funcname,      /*PyObject *name,*/
+        firstlineno,      /*int firstlineno,*/
+        %(EMPTY_BYTES)s   /*PyObject *lnotab*/
+    );
+
+bad: 
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    
+    return py_code;
+}
+
+#endif /* CYTHON_TRACING */
+""" % {
+    'EMPTY_TUPLE' : Naming.empty_tuple,
+    'EMPTY_BYTES' : Naming.empty_bytes,
+    "MODULE": Naming.module_cname,
+})
diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py
index a5d70fd58ae302c2c4e6afb1b60cb86b02fede16..60a2cab05c4a6da02c48ed550bad630993ec790e 100644
--- a/Cython/Compiler/Options.py
+++ b/Cython/Compiler/Options.py
@@ -67,10 +67,11 @@ option_defaults = {
     'wraparound' : True,
     'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this...
     'callspec' : "",
+    'profile': None,
 }
 
 # Override types possibilities above, if needed
-option_types = { }
+option_types = { 'profile': bool }
 
 for key, val in option_defaults.items():
     if key not in option_types:
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py
index 1f3bf7d232383df7f34bbfc54f59195915c84c7f..36200d7414c8ffe72c07f014add32d70f22eb4a8 100644
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -625,12 +625,6 @@ property NAME:
         ATTR = value
     """, level='c_class')
 
-    readonly_property = TreeFragment(u"""
-property NAME:
-    def __get__(self):
-        return ATTR
-    """, level='c_class')
-    
     def __call__(self, root):
         self.env_stack = [root.scope]
         # needed to determine if a cdef var is declared after it's used.
@@ -707,7 +701,7 @@ property NAME:
             # mechanism for them. 
             stats = []
             for entry in node.need_properties:
-                property = self.create_Property(entry, node.visibility == 'readonly')
+                property = self.create_Property(entry)
                 property.analyse_declarations(node.dest_scope)
                 self.visit(property)
                 stats.append(property)
@@ -715,11 +709,8 @@ property NAME:
         else:
             return None
             
-    def create_Property(self, entry, readonly):
-        if readonly:
-            template = self.readonly_property
-        else:
-            template = self.basic_property
+    def create_Property(self, entry):
+        template = self.basic_property
         property = template.substitute({
                 u"ATTR": AttributeNode(pos=entry.pos,
                                        obj=NameNode(pos=entry.pos, name="self"), 
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
index 590a6a9543fc843b5cba16fddfd4fb33f7dc6579..d285aec7d0292fd2c05c6d83cb0bc3590e5dd3da 100644
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -170,6 +170,19 @@ class CTypedefType(BaseType):
         self.typedef_cname = cname
         self.typedef_base_type = base_type
         self.typedef_is_external = is_external
+
+        # Make typecodes in external typedefs use typesize-neutral macros
+        if is_external:
+            typecode = None
+            if base_type.is_int:
+                if base_type.signed == 0:
+                    typecode = "__Pyx_T_UNSIGNED_INT"
+                else:
+                    typecode = "__Pyx_T_SIGNED_INT"
+            elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
+                typecode = "__Pyx_T_FLOATING"
+            if typecode:
+                self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
     
     def resolve(self):
         return self.typedef_base_type.resolve()
@@ -814,13 +827,14 @@ static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o); /* proto */
 """, 
 impl="""
 static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o) {
-    if (PyComplex_Check(o)) {
+    if (PyComplex_CheckExact(o)) {
         return %(type_name)s_from_parts(
             (%(real_type)s)((PyComplexObject *)o)->cval.real,
             (%(real_type)s)((PyComplexObject *)o)->cval.imag);
     }
     else {
-        return %(type_name)s_from_parts(%(type_convert)s(o), 0);
+        Py_complex cval = PyComplex_AsCComplex(o);
+        return %(type_name)s_from_parts((%(real_type)s)cval.real, (%(real_type)s)cval.imag);
     }
 }
 """)
@@ -1726,6 +1740,40 @@ static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
 #endif
 #endif
 
+
+#if !defined(T_ULONGLONG)
+#define __Pyx_T_UNSIGNED_INT(x) \\
+        ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
+        ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
+        ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
+        ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : -1))))
+#else
+#define __Pyx_T_UNSIGNED_INT(x) \\
+        ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
+        ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
+        ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
+        ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : \\
+        ((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
+#endif
+#if !defined(T_LONGLONG)
+#define __Pyx_T_SIGNED_INT(x) \\
+        ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
+        ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
+        ((sizeof(x) == sizeof(int))   ? T_INT : \\
+        ((sizeof(x) == sizeof(long))  ? T_LONG : -1))))
+#else
+#define __Pyx_T_SIGNED_INT(x) \\
+        ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
+        ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
+        ((sizeof(x) == sizeof(int))   ? T_INT : \\
+        ((sizeof(x) == sizeof(long))  ? T_LONG : \\
+        ((sizeof(x) == sizeof(PY_LONG_LONG))   ? T_LONGLONG : -1)))))
+#endif
+
+#define __Pyx_T_FLOATING(x) \\
+        ((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
+        ((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))
+
 #if !defined(T_SIZET)
 #if !defined(T_ULONGLONG)
 #define T_SIZET \\
diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py
index 2e5415ef04fecd5961b8ae0bbd69ad99f18cf637..8c96a208f205a2f127c0ddd00aba24d36077b1d7 100644
--- a/Cython/Compiler/Symtab.py
+++ b/Cython/Compiler/Symtab.py
@@ -1583,8 +1583,14 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
 impl = """
 static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
     /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
-    /* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */ 
-    if (__Pyx_StrEq(Py_TYPE(method)->tp_name, "method_descriptor")) { /* cdef classes */
+    static PyTypeObject *methoddescr_type = NULL;
+    if (methoddescr_type == NULL) {
+       PyObject *meth = __Pyx_GetAttrString((PyObject*)&PyList_Type, "append");
+       if (!meth) return NULL;
+       methoddescr_type = Py_TYPE(meth);
+       Py_DECREF(meth);
+    }
+    if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
         PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
         return PyDescr_NewClassMethod(descr->d_type, descr->d_method);
     }
diff --git a/Cython/Includes/__cython__.pxd b/Cython/Includes/__cython__.pxd
deleted file mode 100644
index c703e6f2570969a848c0142734ffad27a2a083e3..0000000000000000000000000000000000000000
--- a/Cython/Includes/__cython__.pxd
+++ /dev/null
@@ -1,28 +0,0 @@
-cdef extern from "Python.h":
-    ctypedef struct PyObject
-
-
-
-    ctypedef struct Py_buffer:
-        void *buf
-        Py_ssize_t len
-        int readonly
-        char *format
-        int ndim
-        Py_ssize_t *shape
-        Py_ssize_t *strides
-        Py_ssize_t *suboffsets
-        Py_ssize_t itemsize
-        void *internal
-
-    
-    int PyObject_GetBuffer(PyObject* obj, Py_buffer* view, int flags) except -1
-    void PyObject_ReleaseBuffer(PyObject* obj, Py_buffer* view)
-
-    void PyErr_Format(int, char*, ...)
-
-    enum:
-        PyExc_TypeError
-
-#                  int PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
-#                       int flags)
diff --git a/Cython/Includes/numpy.pxd b/Cython/Includes/numpy.pxd
index 932a7433a100d60365a2fbaa0246e9044df6773b..3fb343d8dafa7d2f134e2e2023d3a39ca1ae8157 100644
--- a/Cython/Includes/numpy.pxd
+++ b/Cython/Includes/numpy.pxd
@@ -1,18 +1,24 @@
 # NumPy static imports for Cython
 #
+# If any of the PyArray_* functions are called, import_array must be
+# called first.
+#
 # This also defines backwards-compatability buffer acquisition
 # code for use in Python 2.x (or Python <= 2.5 when NumPy starts
 # implementing PEP-3118 directly).
-
-
+#
 # Because of laziness, the format string of the buffer is statically
 # allocated. Increase the size if this is not enough, or submit a
 # patch to do this properly.
+#
+# Author: Dag Sverre Seljebotn
+#
 
 DEF _buffer_format_string_len = 255
 
 cimport python_buffer as pybuf
 cimport stdlib
+cimport stdio
 
 cdef extern from "Python.h":
     ctypedef int Py_intptr_t
@@ -20,43 +26,124 @@ cdef extern from "Python.h":
 cdef extern from "numpy/arrayobject.h":
     ctypedef Py_intptr_t npy_intp
         
-    cdef enum:
-        NPY_BOOL,
-        NPY_BYTE, NPY_UBYTE,
-        NPY_SHORT, NPY_USHORT,
-        NPY_INT, NPY_UINT,
-        NPY_LONG, NPY_ULONG,
-        NPY_LONGLONG, NPY_ULONGLONG,
-        NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
-        NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
-        NPY_OBJECT,
-        NPY_STRING, NPY_UNICODE,
-        NPY_VOID,
-        NPY_NTYPES,
-        NPY_NOTYPE,
-        NPY_CHAR,  
-        NPY_USERDEF,
-
-        NPY_C_CONTIGUOUS,
+    cdef enum NPY_TYPES:
+        NPY_BOOL
+        NPY_BYTE
+        NPY_UBYTE
+        NPY_SHORT
+        NPY_USHORT 
+        NPY_INT
+        NPY_UINT 
+        NPY_LONG
+        NPY_ULONG
+        NPY_LONGLONG
+        NPY_ULONGLONG
+        NPY_FLOAT
+        NPY_DOUBLE 
+        NPY_LONGDOUBLE
+        NPY_CFLOAT
+        NPY_CDOUBLE
+        NPY_CLONGDOUBLE
+        NPY_OBJECT
+        NPY_STRING
+        NPY_UNICODE
+        NPY_VOID
+        NPY_NTYPES
+        NPY_NOTYPE
+
+    enum NPY_ORDER:
+        NPY_ANYORDER
+        NPY_CORDER
+        NPY_FORTRANORDER
+
+    enum NPY_CLIPMODE:
+        NPY_CLIP
+        NPY_WRAP
+        NPY_RAISE
+
+    enum NPY_SCALARKIND:
+        NPY_NOSCALAR,
+        NPY_BOOL_SCALAR,
+        NPY_INTPOS_SCALAR,
+        NPY_INTNEG_SCALAR,
+        NPY_FLOAT_SCALAR,
+        NPY_COMPLEX_SCALAR,
+        NPY_OBJECT_SCALAR
+
+
+    enum NPY_SORTKIND:
+        NPY_QUICKSORT
+        NPY_HEAPSORT
+        NPY_MERGESORT
+
+    cdef enum requirements:
+        NPY_C_CONTIGUOUS
         NPY_F_CONTIGUOUS
+        NPY_CONTIGUOUS
+        NPY_FORTRAN
+        NPY_OWNDATA
+        NPY_FORCECAST
+        NPY_ENSURECOPY
+        NPY_ENSUREARRAY
+        NPY_ELEMENTSTRIDES
+        NPY_ALIGNED
+        NPY_NOTSWAPPED
+        NPY_WRITEABLE
+        NPY_UPDATEIFCOPY
+        NPY_ARR_HAS_DESCR
+
+        NPY_BEHAVED
+        NPY_BEHAVED_NS
+        NPY_CARRAY
+        NPY_CARRAY_RO
+        NPY_FARRAY
+        NPY_FARRAY_RO
+        NPY_DEFAULT
+
+        NPY_IN_ARRAY
+        NPY_OUT_ARRAY
+        NPY_INOUT_ARRAY
+        NPY_IN_FARRAY
+        NPY_OUT_FARRAY
+        NPY_INOUT_FARRAY
+
+        NPY_UPDATE_ALL
         
+    cdef enum:
+        NPY_MAXDIMS
+
+    npy_intp NPY_MAX_ELSIZE
+
+    ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,  void *)
+    
     ctypedef class numpy.dtype [object PyArray_Descr]:
+        # Use PyDataType_* macros when possible, however there are no macros
+        # for accessing some of the fields, so some are defined. Please
+        # ask on cython-dev if you need more.
         cdef int type_num
         cdef int itemsize "elsize"
         cdef char byteorder
         cdef object fields
         cdef object names
 
+    ctypedef extern class numpy.flatiter [object PyArrayIterObject]:
+        # Use through macros
+        pass
+
+    ctypedef extern class numpy.broadcast [object PyArrayMultiIterObject]:
+        # Use through macros
+        pass
 
     ctypedef class numpy.ndarray [object PyArrayObject]:
         cdef __cythonbufferdefaults__ = {"mode": "strided"}
         
         cdef:
+            # Only taking a few of the most commonly used and stable fields.
+            # One should use PyArray_* macros instead to access the C fields.
             char *data
             int ndim "nd"
             npy_intp *shape "dimensions" 
             npy_intp *strides
-            int flags
             dtype descr
 
         # Note: This syntax (function definition in pxd files) is an
@@ -159,19 +246,9 @@ cdef extern from "numpy/arrayobject.h":
             if sizeof(npy_intp) != sizeof(Py_ssize_t):
                 stdlib.free(info.strides)
                 # info.shape was stored after info.strides in the same block
-            
 
-    cdef void* PyArray_DATA(ndarray arr)
-    cdef int PyArray_TYPE(ndarray arr)
-    cdef int PyArray_NDIM(ndarray arr)
-    cdef int PyArray_ISWRITEABLE(ndarray arr)
-    cdef npy_intp* PyArray_STRIDES(ndarray arr)
-    cdef npy_intp* PyArray_DIMS(ndarray arr)
-    cdef int PyArray_ITEMSIZE(ndarray arr)
-    cdef int PyArray_CHKFLAGS(ndarray arr, int flags)
-    cdef int PyArray_HASFIELDS(ndarray arr)
 
-    cdef int PyDataType_HASFIELDS(dtype obj)
+    ctypedef signed char      npy_bool
 
     ctypedef signed char      npy_byte
     ctypedef signed short     npy_short
@@ -216,17 +293,353 @@ cdef extern from "numpy/arrayobject.h":
     ctypedef long double complex  npy_complex256
 
     ctypedef struct npy_cfloat:
-        float real
-        float imag
+        double real
+        double imag
 
     ctypedef struct npy_cdouble:
-        float real
-        float imag
+        double real
+        double imag
 
     ctypedef struct npy_clongdouble:
-        float real
-        float imag
-
+        double real
+        double imag
+
+    ctypedef struct PyArray_Dims:
+        npy_intp *ptr
+        int len
+
+    void import_array()
+
+    #
+    # Macros from ndarrayobject.h
+    #
+    bint PyArray_CHKFLAGS(ndarray m, int flags)
+    bint PyArray_ISISCONTIGUOUS(ndarray m)
+    bint PyArray_ISWRITEABLE(ndarray m)
+    bint PyArray_ISALIGNED(ndarray m)
+
+    int PyArray_NDIM(ndarray)
+    bint PyArray_ISONESEGMENT(ndarray)
+    bint PyArray_ISFORTRAN(ndarray)
+    int PyArray_FORTRANIF(ndarray)
+
+    void* PyArray_DATA(ndarray)
+    char* PyArray_BYTES(ndarray)
+    npy_intp* PyArray_DIMS(ndarray)
+    npy_intp* PyArray_STRIDES(ndarray)
+    npy_intp PyArray_DIM(ndarray, size_t)
+    npy_intp PyArray_STRIDE(ndarray, size_t)
+
+    # object PyArray_BASE(ndarray) wrong refcount semantics
+    # dtype PyArray_DESCR(ndarray) wrong refcount semantics
+    int PyArray_FLAGS(ndarray)
+    npy_intp PyArray_ITEMSIZE(ndarray)
+    int PyArray_TYPE(ndarray arr)
+
+    object PyArray_GETITEM(ndarray arr, void *itemptr)
+    int PyArray_SETITEM(ndarray arr, void *itemptr, object obj)
+        
+    bint PyTypeNum_ISBOOL(int)
+    bint PyTypeNum_ISUNSIGNED(int)
+    bint PyTypeNum_ISSIGNED(int)
+    bint PyTypeNum_ISINTEGER(int)
+    bint PyTypeNum_ISFLOAT(int)
+    bint PyTypeNum_ISNUMBER(int)
+    bint PyTypeNum_ISSTRING(int)
+    bint PyTypeNum_ISCOMPLEX(int)
+    bint PyTypeNum_ISPYTHON(int)
+    bint PyTypeNum_ISFLEXIBLE(int)
+    bint PyTypeNum_ISUSERDEF(int)
+    bint PyTypeNum_ISEXTENDED(int)
+    bint PyTypeNum_ISOBJECT(int)
+
+    bint PyDataType_ISBOOL(dtype)
+    bint PyDataType_ISUNSIGNED(dtype)
+    bint PyDataType_ISSIGNED(dtype)
+    bint PyDataType_ISINTEGER(dtype)
+    bint PyDataType_ISFLOAT(dtype)
+    bint PyDataType_ISNUMBER(dtype)
+    bint PyDataType_ISSTRING(dtype)
+    bint PyDataType_ISCOMPLEX(dtype)
+    bint PyDataType_ISPYTHON(dtype)
+    bint PyDataType_ISFLEXIBLE(dtype)
+    bint PyDataType_ISUSERDEF(dtype)
+    bint PyDataType_ISEXTENDED(dtype)
+    bint PyDataType_ISOBJECT(dtype)
+    bint PyDataType_HASFIELDS(dtype)
+
+    bint PyArray_ISBOOL(ndarray)
+    bint PyArray_ISUNSIGNED(ndarray)
+    bint PyArray_ISSIGNED(ndarray)
+    bint PyArray_ISINTEGER(ndarray)
+    bint PyArray_ISFLOAT(ndarray)
+    bint PyArray_ISNUMBER(ndarray)
+    bint PyArray_ISSTRING(ndarray)
+    bint PyArray_ISCOMPLEX(ndarray)
+    bint PyArray_ISPYTHON(ndarray)
+    bint PyArray_ISFLEXIBLE(ndarray)
+    bint PyArray_ISUSERDEF(ndarray)
+    bint PyArray_ISEXTENDED(ndarray)
+    bint PyArray_ISOBJECT(ndarray)
+    bint PyArray_HASFIELDS(ndarray)
+
+    bint PyArray_ISVARIABLE(ndarray)
+
+    bint PyArray_SAFEALIGNEDCOPY(ndarray)
+    bint PyArray_ISNBO(ndarray)
+    bint PyArray_IsNativeByteOrder(ndarray)
+    bint PyArray_ISNOTSWAPPED(ndarray)
+    bint PyArray_ISBYTESWAPPED(ndarray)
+
+    bint PyArray_FLAGSWAP(ndarray, int)
+
+    bint PyArray_ISCARRAY(ndarray)
+    bint PyArray_ISCARRAY_RO(ndarray)
+    bint PyArray_ISFARRAY(ndarray)
+    bint PyArray_ISFARRAY_RO(ndarray)
+    bint PyArray_ISBEHAVED(ndarray)
+    bint PyArray_ISBEHAVED_RO(ndarray)
+
+
+    bint PyDataType_ISNOTSWAPPED(dtype)
+    bint PyDataType_ISBYTESWAPPED(dtype)
+
+    bint PyArray_DescrCheck(object)
+
+    bint PyArray_Check(object)
+    bint PyArray_CheckExact(object)
+
+    # Cannot be supported due to out arg:
+    # bint PyArray_HasArrayInterfaceType(object, dtype, object, object&)
+    # bint PyArray_HasArrayInterface(op, out)
+
+
+    bint PyArray_IsZeroDim(object)
+    # Cannot be supported due to ## ## in macro:
+    # bint PyArray_IsScalar(object, verbatim work)
+    bint PyArray_CheckScalar(object)
+    bint PyArray_IsPythonNumber(object)
+    bint PyArray_IsPythonScalar(object)
+    bint PyArray_IsAnyScalar(object)
+    bint PyArray_CheckAnyScalar(object)
+    ndarray PyArray_GETCONTIGUOUS(ndarray)
+    bint PyArray_SAMESHAPE(ndarray, ndarray)
+    npy_intp PyArray_SIZE(ndarray)
+    npy_intp PyArray_NBYTES(ndarray)
+    
+    object PyArray_FROM_O(object)
+    object PyArray_FROM_OF(object m, int flags)
+    bint PyArray_FROM_OT(object m, int type)
+    bint PyArray_FROM_OTF(object m, int type, int flags)
+    object PyArray_FROMANY(object m, int type, int min, int max, int flags)
+    bint PyArray_ZEROS(ndarray m, dims, int type, int fortran)
+    object PyArray_EMPTY(object m, dims, int type, int fortran)
+    void PyArray_FILLWBYTE(object, int val)
+    npy_intp PyArray_REFCOUNT(object)
+    object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
+    unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2)
+    bint PyArray_EquivByteorders(int b1, int b2)
+    object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
+    object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
+    #object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr)
+    object PyArray_ToScalar(void* data, ndarray arr)
+
+    void* PyArray_GETPTR1(ndarray m, npy_intp i)
+    void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j)
+    void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k)
+    void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l)
+
+    void PyArray_XDECREF_ERR(ndarray)
+    # Cannot be supported due to out arg
+    # void PyArray_DESCR_REPLACE(descr)
+
+
+    object PyArray_Copy(ndarray)
+    object PyArray_FromObject(object op, int type, int min_depth, int max_depth)
+    object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth)
+    object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth)
+
+    object PyArray_Cast(ndarray mp, int type_num)
+    object PyArray_Take(ndarray ap, object items, int axis)
+    object PyArray_Put(ndarray ap, object items, object values)
+
+    # Functions from __multiarray_api.h
+
+    # Functions taking dtype and returning object/ndarray are disabled
+    # for now as they steal dtype references. I'm conservative and disable
+    # more than is probably needed until it can be checked further.
+    int PyArray_SetNumericOps        (object)
+    object PyArray_GetNumericOps ()
+    int PyArray_INCREF (ndarray)
+    int PyArray_XDECREF (ndarray)
+    void PyArray_SetStringFunction (object, int)
+    dtype PyArray_DescrFromType (int)
+    object PyArray_TypeObjectFromType (int)
+    char * PyArray_Zero (ndarray)
+    char * PyArray_One (ndarray)
+    #object PyArray_CastToType (ndarray, dtype, int)
+    int PyArray_CastTo (ndarray, ndarray)
+    int PyArray_CastAnyTo (ndarray, ndarray)
+    int PyArray_CanCastSafely (int, int)
+    npy_bool PyArray_CanCastTo (dtype, dtype)
+    int PyArray_ObjectType (object, int)
+    dtype PyArray_DescrFromObject (object, dtype)
+    #ndarray* PyArray_ConvertToCommonType (object, int *)
+    dtype PyArray_DescrFromScalar (object)
+    dtype PyArray_DescrFromTypeObject (object)
+    npy_intp PyArray_Size (object)
+    #object PyArray_Scalar (void *, dtype, object)
+    #object PyArray_FromScalar (object, dtype)
+    void PyArray_ScalarAsCtype (object, void *)
+    #int PyArray_CastScalarToCtype (object, void *, dtype)
+    #int PyArray_CastScalarDirect (object, dtype, void *, int)
+    object PyArray_ScalarFromObject (object)
+    #PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int)
+    object PyArray_FromDims (int, int *, int)
+    #object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *)
+    #object PyArray_FromAny (object, dtype, int, int, int, object)
+    object PyArray_EnsureArray (object)
+    object PyArray_EnsureAnyArray (object)
+    #object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *)
+    #object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *)
+    #object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp)
+    #object PyArray_FromIter (object, dtype, npy_intp)
+    object PyArray_Return (ndarray)
+    #object PyArray_GetField (ndarray, dtype, int)
+    #int PyArray_SetField (ndarray, dtype, int, object)
+    object PyArray_Byteswap (ndarray, npy_bool)
+    object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER)
+    int PyArray_MoveInto (ndarray, ndarray)
+    int PyArray_CopyInto (ndarray, ndarray)
+    int PyArray_CopyAnyInto (ndarray, ndarray)
+    int PyArray_CopyObject (ndarray, object)
+    object PyArray_NewCopy (ndarray, NPY_ORDER)
+    object PyArray_ToList (ndarray)
+    object PyArray_ToString (ndarray, NPY_ORDER)
+    int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *)
+    int PyArray_Dump (object, object, int)
+    object PyArray_Dumps (object, int)
+    int PyArray_ValidType (int)
+    void PyArray_UpdateFlags (ndarray, int)
+    object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object)
+    #object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object)
+    #dtype PyArray_DescrNew (dtype)
+    dtype PyArray_DescrNewFromType (int)
+    double PyArray_GetPriority (object, double)
+    object PyArray_IterNew (object)
+    object PyArray_MultiIterNew (int, ...)
+    int PyArray_PyIntAsInt (object)
+    npy_intp PyArray_PyIntAsIntp (object)
+    int PyArray_Broadcast (broadcast)
+    void PyArray_FillObjectArray (ndarray, object)
+    int PyArray_FillWithScalar (ndarray, object)
+    npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)
+    dtype PyArray_DescrNewByteorder (dtype, char)
+    object PyArray_IterAllButAxis (object, int *)
+    #object PyArray_CheckFromAny (object, dtype, int, int, int, object)
+    #object PyArray_FromArray (ndarray, dtype, int)
+    object PyArray_FromInterface (object)
+    object PyArray_FromStructInterface (object)
+    #object PyArray_FromArrayAttr (object, dtype, object)
+    #NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*)
+    int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND)
+    object PyArray_NewFlagsObject (object)
+    npy_bool PyArray_CanCastScalar (type, type)
+    #int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t)
+    int PyArray_RemoveSmallest (broadcast)
+    int PyArray_ElementStrides (object)
+    void PyArray_Item_INCREF (char *, dtype)
+    void PyArray_Item_XDECREF (char *, dtype)
+    object PyArray_FieldNames (object)
+    object PyArray_Transpose (ndarray, PyArray_Dims *)
+    object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE)
+    object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE)
+    object PyArray_PutMask (ndarray, object, object)
+    object PyArray_Repeat (ndarray, object, int)
+    object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE)
+    int PyArray_Sort (ndarray, int, NPY_SORTKIND)
+    object PyArray_ArgSort (ndarray, int, NPY_SORTKIND)
+    object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE)
+    object PyArray_ArgMax (ndarray, int, ndarray)
+    object PyArray_ArgMin (ndarray, int, ndarray)
+    object PyArray_Reshape (ndarray, object)
+    object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER)
+    object PyArray_Squeeze (ndarray)
+    #object PyArray_View (ndarray, dtype, type)
+    object PyArray_SwapAxes (ndarray, int, int)
+    object PyArray_Max (ndarray, int, ndarray)
+    object PyArray_Min (ndarray, int, ndarray)
+    object PyArray_Ptp (ndarray, int, ndarray)
+    object PyArray_Mean (ndarray, int, int, ndarray)
+    object PyArray_Trace (ndarray, int, int, int, int, ndarray)
+    object PyArray_Diagonal (ndarray, int, int, int)
+    object PyArray_Clip (ndarray, object, object, ndarray)
+    object PyArray_Conjugate (ndarray, ndarray)
+    object PyArray_Nonzero (ndarray)
+    object PyArray_Std (ndarray, int, int, ndarray, int)
+    object PyArray_Sum (ndarray, int, int, ndarray)
+    object PyArray_CumSum (ndarray, int, int, ndarray)
+    object PyArray_Prod (ndarray, int, int, ndarray)
+    object PyArray_CumProd (ndarray, int, int, ndarray)
+    object PyArray_All (ndarray, int, ndarray)
+    object PyArray_Any (ndarray, int, ndarray)
+    object PyArray_Compress (ndarray, object, int, ndarray)
+    object PyArray_Flatten (ndarray, NPY_ORDER)
+    object PyArray_Ravel (ndarray, NPY_ORDER)
+    npy_intp PyArray_MultiplyList (npy_intp *, int)
+    int PyArray_MultiplyIntList (int *, int)
+    void * PyArray_GetPtr (ndarray, npy_intp*)
+    int PyArray_CompareLists (npy_intp *, npy_intp *, int)
+    #int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype)
+    #int PyArray_As1D (object*, char **, int *, int)
+    #int PyArray_As2D (object*, char ***, int *, int *, int)
+    int PyArray_Free (object, void *)
+    #int PyArray_Converter (object, object*)
+    int PyArray_IntpFromSequence (object, npy_intp *, int)
+    object PyArray_Concatenate (object, int)
+    object PyArray_InnerProduct (object, object)
+    object PyArray_MatrixProduct (object, object)
+    object PyArray_CopyAndTranspose (object)
+    object PyArray_Correlate (object, object, int)
+    int PyArray_TypestrConvert (int, int)
+    #int PyArray_DescrConverter (object, dtype*)
+    #int PyArray_DescrConverter2 (object, dtype*)
+    int PyArray_IntpConverter (object, PyArray_Dims *)
+    #int PyArray_BufferConverter (object, chunk)
+    int PyArray_AxisConverter (object, int *)
+    int PyArray_BoolConverter (object, npy_bool *)
+    int PyArray_ByteorderConverter (object, char *)
+    int PyArray_OrderConverter (object, NPY_ORDER *)
+    unsigned char PyArray_EquivTypes (dtype, dtype)
+    #object PyArray_Zeros (int, npy_intp *, dtype, int)
+    #object PyArray_Empty (int, npy_intp *, dtype, int)
+    object PyArray_Where (object, object, object)
+    object PyArray_Arange (double, double, double, int)
+    #object PyArray_ArangeObj (object, object, object, dtype)
+    int PyArray_SortkindConverter (object, NPY_SORTKIND *)
+    object PyArray_LexSort (object, int)
+    object PyArray_Round (ndarray, int, ndarray)
+    unsigned char PyArray_EquivTypenums (int, int)
+    int PyArray_RegisterDataType (dtype)
+    int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *)
+    int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND)
+    #void PyArray_InitArrFuncs (PyArray_ArrFuncs *)
+    object PyArray_IntTupleFromIntp (int, npy_intp *)
+    int PyArray_TypeNumFromName (char *)
+    int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *)
+    #int PyArray_OutputConverter (object, ndarray*)
+    object PyArray_BroadcastToShape (object, npy_intp *, int)
+    void _PyArray_SigintHandler (int)
+    void* _PyArray_GetSigintBuf ()
+    #int PyArray_DescrAlignConverter (object, dtype*)
+    #int PyArray_DescrAlignConverter2 (object, dtype*)
+    int PyArray_SearchsideConverter (object, void *)
+    object PyArray_CheckAxis (ndarray, int *, int)
+    npy_intp PyArray_OverflowMultiplyList (npy_intp *, int)
+    int PyArray_CompareString (char *, char *, size_t)
+    
+    
+        
 # Typedefs that matches the runtime dtype objects in
 # the numpy module.
 
@@ -252,8 +665,8 @@ ctypedef npy_float64    float64_t
 #ctypedef npy_float80    float80_t
 #ctypedef npy_float128   float128_t
 
-ctypedef npy_complex64    complex64_t
-ctypedef npy_complex128   complex128_t
+ctypedef float complex  complex64_t
+ctypedef double complex complex128_t
 
 # The int types are mapped a bit surprising --
 # numpy.int corresponds to 'l' and numpy.long to 'q'
diff --git a/Cython/Includes/python_version.pxd b/Cython/Includes/python_version.pxd
index 0e839704887884ae4c2157af786904ab194df210..e5aee0fb5e6c8c7d0acfffb459a0173fe3711f14 100644
--- a/Cython/Includes/python_version.pxd
+++ b/Cython/Includes/python_version.pxd
@@ -28,5 +28,5 @@ cdef extern from *:
     #    0xC (release candidate)
     #    0xF (final)
 
-    char[] PY_VERSION
-    char[] PY_PATCHLEVEL_REVISION
+    char PY_VERSION[]
+    char PY_PATCHLEVEL_REVISION[]
diff --git a/Demos/freeze/Makefile b/Demos/freeze/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..dd511e084fa630f089f419da150fc1bb0423f3ed
--- /dev/null
+++ b/Demos/freeze/Makefile
@@ -0,0 +1,33 @@
+CC = gcc
+CYTHON = ./../bin/cython
+CYTHON_FREEZE = ../../bin/cython_freeze.py
+
+CFLAGS = -fPIC -g -O2 -Wall -Wextra
+CPPFLAGS = -I /usr/include/python2.6
+LDFLAGS = -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
+LDLIBS = /usr/lib/python2.6/config/libpython2.6.a \
+	-lm -ldl -pthread -lutil -lz
+
+
+# Name of executable
+TARGET = nCr
+
+# List of Cython source files, with main module first.
+CYTHON_SOURCE = combinatorics.pyx cmath.pyx
+
+
+all : $(TARGET)
+
+$(TARGET) : $(TARGET).o $(CYTHON_SOURCE:.pyx=.o)
+
+$(TARGET).c :
+	$(CYTHON_FREEZE) $(CYTHON_SOURCE:.pyx=) > $@
+
+%.c : %.pyx
+	$(CYTHON) $(CYTHONFLAGS) $^
+
+clean:
+	$(RM) *.o *.c $(TARGET)
+
+.PHONY: clean
+.SECONDARY: $(CYTHON_SOURCE:.pyx=.c)
diff --git a/Demos/freeze/README.rst b/Demos/freeze/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cc81722f5a8971258d28ce4a252d559983a759e9
--- /dev/null
+++ b/Demos/freeze/README.rst
@@ -0,0 +1,82 @@
+NAME
+====
+
+cython_freeze.py - create a C file for embedding Cython modules
+
+
+SYNOPSIS
+========
+
+cython_freeze.py module [...]
+
+
+DESCRIPTION
+===========
+
+**cython_freeze.py** generates a C source file to embed a Python interpreter
+with one or more Cython modules built in.  This allows one to create a single
+executable from Cython code, without having to have separate shared objects
+for each Cython module.
+
+A major advantage of this approach is that it allows debuging with gprof(1),
+which does not work with shared objects.
+
+Note that this method differs from ``cython --embed``.  The ``--embed`` options
+modifies the resulting C source file to include a ``main()`` function, so it
+can only be used on a single Cython module.  The advantage ``--embed`` is
+simplicity.  This module, on the other hand, can be used with multiple
+modules, but it requires another C source file to be created.
+
+
+EXAMPLE
+=======
+
+In the example directory, there exist two Cython modules:
+
+cmath.pyx
+    A module that interfaces with the -lm library.
+
+combinatorics.pyx
+    A module that implements n-choose-r using cmath.
+
+Both modules have the Python idiom ``if __name__ == "__main__"``, which only
+execute if that module is the "main" module.  If run as main, cmath prints the
+factorial of the argument, while combinatorics prints n-choose-r.
+
+The provided Makefile creates an executable, *nCr*, using combinatorics as the
+"main" module.  It basically performs the following (ignoring the compiler
+flags)::
+
+    $ cython_freeze.py combintorics cmath > nCr.c
+    $ cython combinatorics.pyx
+    $ cython cmath.pyx
+    $ gcc nCr.c -o nCr.o
+    $ gcc combinatorics.c -o combinatorics.o
+    $ gcc cmath.c -o cmath.o
+    $ gcc nCr.o combinatorics.o cmath.o -o nCr
+
+Because the combinatorics module was listed first, its ``__name__`` is set
+to ``"__main__"``, while cmath's is set to ``"cmath"``.  The executable now
+contains a Python interpreter and both Cython modules. ::
+
+    $ ./nCr
+    USAGE: ./nCr n r
+    Prints n-choose-r.
+    $ ./nCr 15812351235 12
+    5.10028093999e+113
+
+
+
+
+PREREQUISITES
+=============
+
+Cython 0.11.2 (or newer, assuming the API does not change)
+
+
+SEE ALSO
+========
+
+* `Python <http://www.python.org>`_
+* `Cython <http://www.cython.org>`_
+* `freeze.py <http://wiki.python.org/moin/Freeze>`_
diff --git a/Demos/freeze/cmath.pyx b/Demos/freeze/cmath.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..cc3f0521ed9a64494798c7f13bfbda00c4055998
--- /dev/null
+++ b/Demos/freeze/cmath.pyx
@@ -0,0 +1,24 @@
+cdef extern from "math.h":
+    double c_lgamma "lgamma" (double)
+    double c_exp "exp" (double)
+
+def exp(n):
+    """Return e**n."""
+    return c_exp(n)
+
+def lfactorial(n):
+    """Return an estimate of the log factorial of n."""
+    return c_lgamma(n+1)
+
+def factorial(n):
+    """Return an estimate of the factorial of n."""
+    return c_exp( c_lgamma(n+1) )
+
+
+if __name__ == "__main__":
+    import sys
+    if len(sys.argv) != 2:
+        sys.stderr.write("USAGE: %s n\nPrints n!.\n" % sys.argv[0])
+        sys.exit(1)
+    n = map(float, sys.argv[1:])
+    print factorial(n)
diff --git a/Demos/freeze/combinatorics.pyx b/Demos/freeze/combinatorics.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..f3a23ece55bd606f0f30e08f563b26e6689894c1
--- /dev/null
+++ b/Demos/freeze/combinatorics.pyx
@@ -0,0 +1,14 @@
+import cmath
+
+def nCr(n, r):
+    """Return the number of ways to choose r elements of a set of n."""
+    return cmath.exp( cmath.lfactorial(n) - cmath.lfactorial(r)
+                      - cmath.lfactorial(n-r) )
+
+if __name__ == "__main__":
+    import sys
+    if len(sys.argv) != 3:
+        sys.stderr.write("USAGE: %s n r\nPrints n-choose-r.\n" % sys.argv[0])
+        sys.exit(1)
+    n, r = map(float, sys.argv[1:])
+    print nCr(n, r)
diff --git a/Demos/setup.py b/Demos/setup.py
index 75b05af0fce37948d547cb1fb88ae7303ba7712c..60cbeb817a1bec070cdafdecae6c1c422e6c5c81 100644
--- a/Demos/setup.py
+++ b/Demos/setup.py
@@ -4,6 +4,12 @@ from distutils.core import setup
 from distutils.extension import Extension
 from Cython.Distutils import build_ext
 
+try:
+    from numpy.distutils.misc_util import get_numpy_include_dirs
+    numpy_include_dirs = get_numpy_include_dirs()
+except:
+    numpy_include_dirs = []
+
 ext_modules=[ 
     Extension("primes",       ["primes.pyx"]),
     Extension("spam",         ["spam.pyx"]),
@@ -11,7 +17,7 @@ ext_modules=[
 
 for file in glob.glob("*.pyx"):
     if file != "numeric_demo.pyx":
-        ext_modules.append(Extension(file[:-4], [file]))
+        ext_modules.append(Extension(file[:-4], [file], include_dirs = numpy_include_dirs))
 
 setup(
   name = 'Demos',
diff --git a/bin/cython_freeze.py b/bin/cython_freeze.py
new file mode 100644
index 0000000000000000000000000000000000000000..184c4a89ea406df38a8fc59b2e2158c6c2106999
--- /dev/null
+++ b/bin/cython_freeze.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+"""
+Create a C file for embedding one or more Cython source files.
+Requires Cython 0.11.2 (or perhaps newer).
+
+See README.rst for more details.
+"""
+
+import sys
+
+if len(sys.argv) < 2:
+    print >>sys.stderr, "USAGE: %s module [module ...]" % sys.argv[0]
+    sys.exit(1)
+
+def format_modname(name):
+    if name.endswith('.pyx'):
+        name = name[:-4]
+    return name.replace('.','_')
+
+modules = [format_modname(x) for x in sys.argv[1:]]
+
+print """
+#include <Python.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if PY_MAJOR_VERSION < 3
+# define MODINIT(name)  init ## name
+#else
+# define MODINIT(name)  PyInit_ ## name
+#endif
+"""
+
+for name in modules:
+    print "PyMODINIT_FUNC MODINIT(%s) (void);" % name
+
+print """
+static struct _inittab inittab[] = {"""
+
+for name in modules:
+    print '    {"%(name)s", MODINIT(%(name)s)},' % {'name' : name}
+
+print """    {NULL, NULL}
+};
+
+extern int __pyx_module_is_main_%(main)s;
+
+#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
+int main(int argc, char** argv) {
+#else
+int wmain(int argc, wchar_t **argv) {
+#endif
+    int r = 0;
+    PyObject *m = NULL;
+    if (PyImport_ExtendInittab(inittab)) {
+        fprintf(stderr, "No memory\\n");
+        exit(1);
+    }
+    Py_SetProgramName(argv[0]);
+    Py_Initialize();
+    PySys_SetArgv(argc, argv);
+    __pyx_module_is_main_%(main)s = 1;
+    m = PyImport_ImportModule(inittab[0].name);
+    if (!m) {
+        r = 1;
+        PyErr_Print(); /* This exits with the right code if SystemExit. */
+        if (Py_FlushLine()); PyErr_Clear();
+    }
+    Py_XDECREF(m);
+    Py_Finalize();
+    return r;
+}
+""" % {'main' : modules[0]}
diff --git a/tests/bugs.txt b/tests/bugs.txt
index ce41eb17f4b15d8b255bdbe0f03b17091747cda2..3d934c578270625e6ca9c70fd0b99684180e6aa8 100644
--- a/tests/bugs.txt
+++ b/tests/bugs.txt
@@ -14,3 +14,6 @@ large_consts_T237
 bad_c_struct_T252
 missing_baseclass_in_predecl_T262
 ifelseexpr_T267
+
+# Not yet enabled
+profile_test
diff --git a/tests/compile/shipped_pxds.pyx b/tests/compile/shipped_pxds.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..711484a5619f00191bbf2e4938e7b4c9c0f5240d
--- /dev/null
+++ b/tests/compile/shipped_pxds.pyx
@@ -0,0 +1,30 @@
+cimport python_bool
+cimport python_buffer
+cimport python_complex
+cimport python_dict
+cimport python_exc
+cimport python_float
+cimport python_function
+cimport python_instance
+cimport python_int
+cimport python_iterator
+cimport python_list
+cimport python_long
+cimport python_mapping
+cimport python_mem
+cimport python_method
+cimport python_module
+cimport python_number
+cimport python_object
+cimport python_parse
+cimport python
+cimport python_ref
+cimport python_sequence
+cimport python_set
+cimport python_string
+cimport python_tuple
+cimport python_type
+cimport python_unicode
+cimport python_version
+cimport stdio
+cimport stdlib
diff --git a/tests/errors/callingnonexisting_T307.pyx b/tests/errors/callingnonexisting_T307.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..b66f64641111510b066193bf308d6297ec6fcc78
--- /dev/null
+++ b/tests/errors/callingnonexisting_T307.pyx
@@ -0,0 +1,5 @@
+nonexisting(3, with_kw_arg=4)
+
+_ERRORS = u"""
+1:11: undeclared name not builtin: nonexisting
+"""
diff --git a/tests/run/delete.pyx b/tests/run/delete.pyx
index 961967455340bd9e2aaffa520e8f89fbd1ae5f7b..917df2fcc0ecb6ba3136a3bb3e86f420becc27f7 100644
--- a/tests/run/delete.pyx
+++ b/tests/run/delete.pyx
@@ -4,6 +4,21 @@
 [2, 1]
 >>> a.g()
 (False, True)
+>>> del_item({1: 'a', 2: 'b'}, 1)
+{2: 'b'}
+>>> del_item(range(10), 2)
+[0, 1, 3, 4, 5, 6, 7, 8, 9]
+
+>>> del_dict({1: 'a', 2: 'b'}, 1)
+{2: 'b'}
+>>> del_list(range(5), 3)
+[0, 1, 2, 4]
+>>> del_int(range(5), 3)
+[0, 1, 2, 4]
+>>> del_list_int(range(5), 3)
+[0, 1, 2, 4]
+>>> del_int({-1: 'neg', 1: 'pos'}, -1)
+{1: 'pos'}
 """
 
 class A:
@@ -16,3 +31,23 @@ class A:
         self.a = 3
         del self.a
         return (hasattr(self, u"a"), hasattr(self, u"g"))
+
+def del_item(L, o):
+    del L[o]
+    return L
+
+def del_dict(dict D, o):
+    del D[o]
+    return D
+
+def del_list(list L, o):
+    del L[o]
+    return L
+
+def del_int(L, int i):
+    del L[i]
+    return L
+
+def del_list_int(L, int i):
+    del L[i]
+    return L
diff --git a/tests/run/external_defs.h b/tests/run/external_defs.h
index a6f22cf088bc504264b5ec33c4d16b686c8cf625..aea5539f8072c0f9d8bd9d718267fded9168903a 100644
--- a/tests/run/external_defs.h
+++ b/tests/run/external_defs.h
@@ -1,3 +1,24 @@
 
-
+typedef float FloatTypedef;
 typedef double DoubleTypedef;
+typedef long double LongDoubleTypedef;
+
+typedef char CharTypedef;
+typedef short ShortTypedef;
+typedef int IntTypedef;
+typedef long LongTypedef;
+#if defined(T_LONGLONG)
+typedef PY_LONG_LONG LongLongTypedef;
+#else
+typedef long LongLongTypedef;
+#endif
+
+typedef unsigned char UCharTypedef;
+typedef unsigned short UShortTypedef;
+typedef unsigned int UIntTypedef;
+typedef unsigned long ULongTypedef;
+#if defined(T_LONGLONG)
+typedef unsigned PY_LONG_LONG ULongLongTypedef;
+#else
+typedef unsigned long ULongLongTypedef;
+#endif
diff --git a/tests/run/hash_T326.pyx b/tests/run/hash_T326.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..bd850e9867df81a0c4cf718e6c5d402c32061343
--- /dev/null
+++ b/tests/run/hash_T326.pyx
@@ -0,0 +1,29 @@
+__doc__ = u"""
+
+    >>> hash(A(5))
+    5
+    >>> hash(A(-1))
+    -2
+    >>> hash(A(-2))
+    -2
+    >>> hash(A(100))
+    Traceback (most recent call last):
+    ...
+    TypeError: That's kind of a round number...
+    
+    >>> __hash__(-1)
+    -1
+"""
+
+cdef class A:
+    cdef long a
+    def __init__(self, a):
+        self.a = a
+    def __hash__(self):
+        if self.a == 100:
+            raise TypeError, "That's kind of a round number..."
+        else:
+            return self.a
+
+cpdef long __hash__(long x):
+    return x
diff --git a/tests/run/numpy_test.pyx b/tests/run/numpy_test.pyx
index a5cf19d0de11747f4b36dd78b1d5d4c39fbf4c60..ec3909c40a5d0f54d1575a7049b25025ab4aab74 100644
--- a/tests/run/numpy_test.pyx
+++ b/tests/run/numpy_test.pyx
@@ -194,6 +194,11 @@ try:
     Traceback (most recent call last):
         ...
     ValueError: Item size of buffer (1 byte) does not match size of 'int' (4 bytes)
+
+    >>> test_complextypes()
+    1,1
+    1,1
+    8,16
     
 """
 except:
@@ -376,3 +381,15 @@ def test_unpacked_align(np.ndarray[UnpackedStruct] arr):
     arr[0].a = 22
     arr[0].b = 23    
     return repr(arr).replace('<', '!').replace('>', '!')
+
+def test_complextypes():
+    cdef np.complex64_t x64 = 1, y64 = 1j
+    cdef np.complex128_t x128 = 1, y128 = 1j
+    x64 = x64 + y64
+    print "%.0f,%.0f" % (x64.real, x64.imag)
+    x128 = x128 + y128
+    print "%.0f,%.0f" % (x128.real, x128.imag)
+    print "%d,%d" % (sizeof(x64), sizeof(x128))
+
+
+    
diff --git a/tests/run/profile_test.pyx b/tests/run/profile_test.pyx
new file mode 100644
index 0000000000000000000000000000000000000000..db433a5e004fbdd5c88c73efa8f20f24962c4af8
--- /dev/null
+++ b/tests/run/profile_test.pyx
@@ -0,0 +1,60 @@
+__doc__ = u"""
+    >>> import os, tempfile, cProfile as profile, pstats
+    >>> statsfile = tempfile.mkstemp()[1]
+    >>> profile.runctx("test_profile(100)", locals(), globals(), statsfile)
+    >>> s = pstats.Stats(statsfile)
+    >>> short_stats = dict([(k[2], v[1]) for k,v in s.stats.items()])
+    >>> short_stats['f_def']
+    100
+    >>> short_stats['f_cdef']
+    100
+    >>> short_stats['f_inline']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'f_inline'
+    >>> short_stats['f_inline_prof']
+    100
+    >>> short_stats['f_noprof']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'f_noprof'
+    >>> short_stats['f_raise']
+    100
+    >>> os.unlink(statsfile)
+"""
+
+cimport cython
+
+def test_profile(long N):
+    cdef long i, n = 0
+    for i from 0 <= i < N:
+        n += f_def(i)
+        n += f_cdef(i)
+        n += f_inline(i)
+        n += f_inline_prof(i)
+        n += f_noprof(i)
+        try:
+            n += f_raise(i+2)
+        except RuntimeError:
+            pass
+    return n
+
+def f_def(long a):
+    return a
+
+cdef long f_cdef(long a):
+    return a
+
+cdef inline long f_inline(long a):
+    return a
+
+@cython.profile(True)
+cdef inline long f_inline_prof(long a):
+    return a
+
+@cython.profile(False)
+cdef int f_noprof(long a):
+    return a
+
+cdef long f_raise(long) except -2:
+    raise RuntimeError
diff --git a/tests/run/typedfieldbug_T303.pyx b/tests/run/typedfieldbug_T303.pyx
index d892b8ec5446473f5294a9ad61a2560aaec0d4c7..14410bd71edb95d0e1a703fb79bb1e30257c4554 100644
--- a/tests/run/typedfieldbug_T303.pyx
+++ b/tests/run/typedfieldbug_T303.pyx
@@ -1,31 +1,55 @@
 """
 >>> f()
-42.0 42.0 42.0
+42.0
+42.0
+>>> global_vars(12.0)
+12.0 12.0
 >>> readonly()
 Traceback (most recent call last):
     ...
-AttributeError: attribute 'var_nf' of 'typedfieldbug_T303.MyClass' objects is not writable
+TypeError: readonly attribute
+>>> longdouble_access()
+Traceback (most recent call last):
+    ...
+SystemError: bad memberdescr type
+
 """
 
 cdef extern from "external_defs.h":
     ctypedef float DoubleTypedef
+    ctypedef float LongDoubleTypedef
+
+cdef public DoubleTypedef global_tdef
+cdef public double global_double
 
 cdef class MyClass:
     cdef readonly:
-        double var_d
-        DoubleTypedef var_nf
-    cdef public:
-        DoubleTypedef var_mutable
+        double actual_double
+        DoubleTypedef float_isreally_double
+        LongDoubleTypedef float_isreally_longdouble
+        
     def __init__(self):
-        self.var_d = 42.0
-        self.var_nf = 42.0
-        self.var_mutable = 1
+        self.actual_double = 42.0
+        self.float_isreally_double = 42.0
+        self.float_isreally_longdouble = 42.0
+
+def global_vars(x):
+    global global_tdef, global_double
+    global_tdef = x
+    global_double = x
+    print global_tdef, global_double
 
 def f():
     c = MyClass()
-    c.var_mutable = 42.0
-    print c.var_d, c.var_nf, c.var_mutable
+    print c.actual_double
+    print c.float_isreally_double
+
+def longdouble_access():
+    c = MyClass()
+    print c.float_isreally_longdouble
+
 
 def readonly():
     c = MyClass()
-    c.var_nf = 3
+    c.actual_double = 3
+