[Zope-CVS] CVS: PythonNet/src/runtime - ArrayObject.cs:1.1 AssemblyInfo.cs:1.1 AssemblyManager.cs:1.1 CLRObject.cs:1.1 CallbackThunks.cs:1.1 ClassBase.cs:1.1 ClassManager.cs:1.1 ClassObject.cs:1.1 CodeGenerator.cs:1.1 ConstructorBinder.cs:1.1 Converter.cs:1.1 DebugHelper.cs:1.1 DelegateManager.cs:1.1 DelegateObject.cs:1.1 EventBinding.cs:1.1 EventObject.cs:1.1 Exceptions.cs:1.1 ExtensionType.cs:1.1 FieldObject.cs:1.1 ImportHook.cs:1.1 IndexerObject.cs:1.1 InterfaceObject.cs:1.1 ManagedType.cs:1.1 MetaType.cs:1.1 MethodBinder.cs:1.1 MethodBinding.cs:1.1 MethodObject.cs:1.1 MethodWrapper.cs:1.1 ModuleObject.cs:1.1 NativeCall.cs:1.1 PropertyObject.cs:1.1 PythonException.cs:1.1 PythonInterpreter.cs:1.1 Runtime.cs:1.1 TypeGenerator.cs:1.1 TypeManager.cs:1.1 TypeMethod.cs:1.1 makefile:1.1

Brian Lloyd brian@zope.com
Mon, 14 Jul 2003 16:00:20 -0400


Update of /cvs-repository/PythonNet/src/runtime
In directory cvs.zope.org:/tmp/cvs-serv4259/src/runtime

Added Files:
	ArrayObject.cs AssemblyInfo.cs AssemblyManager.cs CLRObject.cs 
	CallbackThunks.cs ClassBase.cs ClassManager.cs ClassObject.cs 
	CodeGenerator.cs ConstructorBinder.cs Converter.cs 
	DebugHelper.cs DelegateManager.cs DelegateObject.cs 
	EventBinding.cs EventObject.cs Exceptions.cs ExtensionType.cs 
	FieldObject.cs ImportHook.cs IndexerObject.cs 
	InterfaceObject.cs ManagedType.cs MetaType.cs MethodBinder.cs 
	MethodBinding.cs MethodObject.cs MethodWrapper.cs 
	ModuleObject.cs NativeCall.cs PropertyObject.cs 
	PythonException.cs PythonInterpreter.cs Runtime.cs 
	TypeGenerator.cs TypeManager.cs TypeMethod.cs makefile 
Log Message:
refactor repository

=== Added File PythonNet/src/runtime/ArrayObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Python.Runtime {

    /// <summary>
    /// Implements a Python type for managed arrays. This type is essentially
    /// the same as a ClassObject, except that it provides sequence semantics 
    /// to support natural array usage (indexing) from Python.
    /// </summary>

    internal class ArrayObject : ClassBase {

	internal ArrayObject(Type tp) : base(tp) {}

	internal override bool CanSubclass() {
	    return false;
	}

	[CallConvCdecl()]
	public static IntPtr tp_new(IntPtr ob, IntPtr args, IntPtr kw) {
	    Exceptions.SetError(Exceptions.TypeError,
				"cannot instantiate array wrapper"
				);
	    return IntPtr.Zero;
	}

	[CallConvCdecl()]
	public static IntPtr tp_init(IntPtr ob, IntPtr args, IntPtr kw) {
	    Exceptions.SetError(Exceptions.TypeError,
				"cannot instantiate array wrapper"
				);
	    return IntPtr.Zero;
	}

	/*
	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    ArrayObject self = (ArrayObject)GetManagedObject(ob);
	    string s = String.Format("<array '{0}'>", self.type.Name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}
	*/

    }	

}


=== Added File PythonNet/src/runtime/AssemblyInfo.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Reflection;
using System.Security.Permissions;

[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
[assembly: AssemblyKeyFileAttribute("../../Python.Runtime.key")]
[assembly: AssemblyTitleAttribute("Python.Runtime")]
[assembly: AssemblyDefaultAliasAttribute("Python.Runtime.dll")]

// need to assert some permissions here!
[assembly:PermissionSetAttribute(SecurityAction.RequestMinimum, 
				 Name = "FullTrust")]

    // Need strongname for mscorlib.dll
//  [assembly:StrongNameIdentityPermissionAttribute(
//  	  SecurityAction.RequestMinimum,
//  	  PublicKey="00000000000000000400000000000000")]


=== Added File PythonNet/src/runtime/AssemblyManager.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    /// <summary>
    /// The AssemblyManager maintains information about the assemblies and 
    /// namespaces that have been loaded, and provides a simplified internal 
    /// interface for finding and obtaining Type objects by qualified names.
    /// </summary>

    internal class AssemblyManager {

	static Hashtable namespaces;
	static ArrayList assemblies;
	static Hashtable probed;

	private AssemblyManager() {}

	static AssemblyManager() {
	    namespaces = new Hashtable();
	    assemblies = new ArrayList();
	    probed = new Hashtable();

	    AppDomain domain = AppDomain.CurrentDomain;
	    domain.AssemblyLoad += new AssemblyLoadEventHandler(
				       AssemblyLoadHandler
				       );
	
	    Assembly[] items = domain.GetAssemblies();
	    for (int i = 0; i < items.Length; i++) {
		Assembly a = items[i];
		assemblies.Add(a);
		ScanAssembly(a);
	    }
	}

	//===================================================================
	// Event handler for assembly load events. At the time the Python 
	// runtime loads, we scan the app domain to map the assemblies that
	// are loaded at the time. We also have to register this event handler
	// so that we can know about assemblies that get loaded after the 
	// Python runtime is initialized.
	//===================================================================

	static void AssemblyLoadHandler(Object ob, AssemblyLoadEventArgs args){
	    Assembly assembly = args.LoadedAssembly;
	    assemblies.Add(assembly);
	    ScanAssembly(assembly);
	}

	//===================================================================
	// Loads an assembly from the application directory or the GAC
	// given a simple assembly name. Returns true if an assembly was 
	// loaded, false if the assembly was not found or already loaded.
	//===================================================================

	public static bool LoadAssembly(string name) {
	    Assembly assembly = null;
	    try {
		assembly = Assembly.LoadWithPartialName(name);
	    }
	    catch {
	    }
	    return (assembly != null);
	}

	//===================================================================
	// Given a qualified name of the form A.B.C.D, attempt to load 
	// an assembly named after each of A.B.C.D, A.B.C, A.B, A. This
	// will only actually probe for the assembly once for each unique
	// namespace. Returns true if any assemblies were loaded.
	//===================================================================

	public static bool LoadImplicit(string name) {
	    string[] names = name.Split('.');
	    bool loaded = false;
	    string s = "";
	    for (int i = 0; i < names.Length; i++) {
		s = (i == 0) ? names[0] : s + "." + names[i];
		if (probed[s] == null) {
		    if (LoadAssembly(s)) {
			loaded = true;
		    }
		    probed[s] = 1;
		}
	    }
	    return loaded;
	}

	//===================================================================
	// Scans an assembly for exported namespaces, adding them to the
	// mapping of valid namespaces. Note that for a given namespace
	// a.b.c.d, each of a, a.b, a.b.c and a.b.c.d are considered to 
	// be valid namespaces (to better match Python import semantics).
	//===================================================================

	static void ScanAssembly(Assembly assembly) {
	    Type[] types = assembly.GetTypes();
	    for (int i = 0; i < types.Length; i++) {
		string type_ns = types[i].Namespace;
		if ((type_ns != null) && (!namespaces.ContainsKey(type_ns))) {
		    string[] names = type_ns.Split('.');
		    string s = "";
		    for (int n = 0; n < names.Length; n++) {
			s = (n == 0) ? names[0] : s + "." + names[n];
			if (!namespaces.ContainsKey(s)) {
			    namespaces.Add(s, String.Empty);
			}
		    }
		}
	    }
	}

	//===================================================================
	// Returns true if the given qualified name matches a namespace
	// exported by an assembly loaded in the current app domain.
	//===================================================================

	public static bool IsValidNamespace(string name) {
	    return namespaces.ContainsKey(name);
	}

	//===================================================================
	// Returns the System.Type object for a given qualified name,
	// looking in the currently loaded assemblies for the named
	// type. Returns null if the named type cannot be found.
	//===================================================================

	public static Type LookupType(string qualifiedName) {
	    for (int i = 0; i < assemblies.Count; i++) {
		Assembly assembly = (Assembly)assemblies[i];
		Type type = assembly.GetType(qualifiedName);
		if (type != null) {
		    return type;
		}
	    }
	    return null;
	}

    }


}


=== Added File PythonNet/src/runtime/CLRObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Python.Runtime {


    internal class CLRObject : ManagedType {

	internal Object inst;

	internal CLRObject(Object ob, IntPtr pyType) : base() {
	    PyObjectHead pyObj = new PyObjectHead();
	    this.gcHandle = GCHandle.Alloc(this);
	    pyObj.ob_data = (IntPtr) this.gcHandle;
	    pyObj.ob_refcnt = (IntPtr) 0;
	    pyObj.ob_type = pyType;
	    this.tpHandle = pyType;
	    Runtime.Incref(pyType); //??

	    this.pyHandle = Runtime.PyMem_Malloc((4 * IntPtr.Size));
	    Marshal.StructureToPtr(pyObj, this.pyHandle, false);
	    inst = ob;
	}


	// todo: caching of ref types?
	internal static CLRObject GetInstance(Object ob, IntPtr pyType) {
	    return new CLRObject(ob, pyType);
	}

	internal static CLRObject GetInstance(Object ob) {
	    ClassBase cc = ClassManager.GetClass(ob.GetType());
	    return GetInstance(ob, cc.tpHandle);
	}

	internal static IntPtr GetInstHandle(Object ob, IntPtr pyType) {
	    CLRObject co = GetInstance(ob, pyType);
	    return co.pyHandle;
	}

	internal static IntPtr GetInstHandle(Object ob, Type type) {
	    ClassBase cc = ClassManager.GetClass(type);
	    CLRObject co = GetInstance(ob, cc.tpHandle);
	    return co.pyHandle;
	}


	internal static IntPtr GetInstHandle(Object ob) {
	    CLRObject co = GetInstance(ob);
	    return co.pyHandle;
	}


    }


}



=== Added File PythonNet/src/runtime/CallbackThunks.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Python.Runtime {


    // This file defines support objects for the various forms of trickery
    // we use to connect Python to the CLR. This is all considered private.


    [Serializable()]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
    internal class CallConvCdeclAttribute : Attribute {
	public CallConvCdeclAttribute() {}
    }

    [Serializable()]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
    internal class PythonMethodAttribute : Attribute {
	public PythonMethodAttribute() {}
    }


    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    internal class PyObjectHead {
	public IntPtr ob_refcnt;
	public IntPtr ob_type;
	public IntPtr ob_data;
	// public IntPtr ob_dict;
    }


    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    internal class PyTypeObject {
	public IntPtr ob_refcnt = IntPtr.Zero;
	public IntPtr ob_type = IntPtr.Zero;
	public IntPtr ob_size = IntPtr.Zero;
	public IntPtr tp_name = IntPtr.Zero;
	public IntPtr tp_basicsize = IntPtr.Zero;
	public IntPtr tp_itemsize = IntPtr.Zero;
	public IntPtr tp_dealloc = IntPtr.Zero;
	public IntPtr tp_print = IntPtr.Zero;
	public IntPtr tp_getattr = IntPtr.Zero;
	public IntPtr tp_setattr = IntPtr.Zero;
	public IntPtr tp_compare = IntPtr.Zero;
	public IntPtr tp_repr = IntPtr.Zero;
	public IntPtr tp_as_number = IntPtr.Zero;
	public IntPtr tp_as_sequence = IntPtr.Zero;
	public IntPtr tp_as_mapping = IntPtr.Zero;
	public IntPtr tp_hash = IntPtr.Zero;
	public IntPtr tp_call = IntPtr.Zero;
	public IntPtr tp_str = IntPtr.Zero;
	public IntPtr tp_getattro = IntPtr.Zero;
	public IntPtr tp_setattro = IntPtr.Zero;
	public IntPtr tp_as_buffer = IntPtr.Zero;
	public IntPtr tp_flags = IntPtr.Zero;
	public IntPtr tp_doc = IntPtr.Zero;
	public IntPtr tp_traverse = IntPtr.Zero;
	public IntPtr tp_clear = IntPtr.Zero;
	public IntPtr tp_richcompare = IntPtr.Zero;
	public IntPtr tp_weaklistoffset = IntPtr.Zero;
	public IntPtr tp_iter = IntPtr.Zero;
	public IntPtr tp_iternext = IntPtr.Zero;
	public IntPtr tp_methods = IntPtr.Zero;
	public IntPtr tp_members = IntPtr.Zero;
	public IntPtr tp_getset = IntPtr.Zero;
	public IntPtr tp_base = IntPtr.Zero;
	public IntPtr tp_dict = IntPtr.Zero;
	public IntPtr tp_descr_get = IntPtr.Zero;
	public IntPtr tp_descr_set = IntPtr.Zero;
	public IntPtr tp_dictoffset = IntPtr.Zero;
	public IntPtr tp_init = IntPtr.Zero;
	public IntPtr tp_alloc = IntPtr.Zero;
	public IntPtr tp_new = IntPtr.Zero;
	public IntPtr tp_free = IntPtr.Zero;
	public IntPtr tp_is_gc = IntPtr.Zero;
	public IntPtr tp_bases = IntPtr.Zero;
	public IntPtr tp_mro = IntPtr.Zero;
	public IntPtr tp_cache = IntPtr.Zero;
	public IntPtr tp_subclasses = IntPtr.Zero;
	public IntPtr tp_weaklist = IntPtr.Zero;
	//    }

	//    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	//    internal class PyNumberMethods {
	public IntPtr nb_add = IntPtr.Zero;
	public IntPtr nb_subtract = IntPtr.Zero;
	public IntPtr nb_multiply = IntPtr.Zero;
	public IntPtr nb_divide = IntPtr.Zero;
	public IntPtr nb_remainder = IntPtr.Zero;
	public IntPtr nb_divmod = IntPtr.Zero;
	public IntPtr nb_power = IntPtr.Zero;
	public IntPtr nb_negative = IntPtr.Zero;
	public IntPtr nb_positive = IntPtr.Zero;
	public IntPtr nb_absolute = IntPtr.Zero;
	public IntPtr nb_nonzero = IntPtr.Zero;
        public IntPtr nb_invert = IntPtr.Zero;
	public IntPtr nb_lshift = IntPtr.Zero;
	public IntPtr nb_rshift = IntPtr.Zero;
	public IntPtr nb_and = IntPtr.Zero;
	public IntPtr nb_xor = IntPtr.Zero;
	public IntPtr nb_or = IntPtr.Zero;
        public IntPtr nb_coerce = IntPtr.Zero;
	public IntPtr nb_int = IntPtr.Zero;
	public IntPtr nb_long = IntPtr.Zero;
	public IntPtr nb_float = IntPtr.Zero;
	public IntPtr nb_oct = IntPtr.Zero;
	public IntPtr nb_hex = IntPtr.Zero;
	public IntPtr nb_inplace_add = IntPtr.Zero;
	public IntPtr nb_inplace_subtract = IntPtr.Zero;
	public IntPtr nb_inplace_multiply = IntPtr.Zero;
	public IntPtr nb_inplace_divide = IntPtr.Zero;
	public IntPtr nb_inplace_remainder = IntPtr.Zero;
	public IntPtr nb_inplace_power = IntPtr.Zero;
	public IntPtr nb_inplace_lshift = IntPtr.Zero;
	public IntPtr nb_inplace_rshift = IntPtr.Zero;
	public IntPtr nb_inplace_and = IntPtr.Zero;
	public IntPtr nb_inplace_xor = IntPtr.Zero;
	public IntPtr nb_inplace_or = IntPtr.Zero;
	public IntPtr nb_floor_divide = IntPtr.Zero;
	public IntPtr nb_true_divide = IntPtr.Zero;
	public IntPtr nb_inplace_floor_divide = IntPtr.Zero;
	public IntPtr nb_inplace_true_divide = IntPtr.Zero;
	//    }

	//    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	//    internal class PySequenceMethods {
	public IntPtr sq_length = IntPtr.Zero;
	public IntPtr sq_concat = IntPtr.Zero;
	public IntPtr sq_repeat = IntPtr.Zero;
	public IntPtr sq_item = IntPtr.Zero;
	public IntPtr sq_slice = IntPtr.Zero;
	public IntPtr sq_ass_item = IntPtr.Zero;
	public IntPtr sq_ass_slice = IntPtr.Zero;
	public IntPtr sq_contains = IntPtr.Zero;
	public IntPtr sq_inplace_concat = IntPtr.Zero;
	public IntPtr sq_inplace_repeat = IntPtr.Zero;
	//    }

	//    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	//    internal class PyMappingMethods {
	public IntPtr mp_length = IntPtr.Zero;
	public IntPtr mp_subscript = IntPtr.Zero;
	public IntPtr mp_ass_subscript = IntPtr.Zero;
	//    }

	//    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	//    internal class PyBufferMethods {
	public IntPtr bf_getreadbuffer = IntPtr.Zero;
	public IntPtr bf_getwritebuffer = IntPtr.Zero;
	public IntPtr bf_getsegcount = IntPtr.Zero;
	public IntPtr bf_getcharbuffer = IntPtr.Zero;
    }






    internal enum PyTypeFlags {
	HaveGetCharBuffer = (1 << 0),
	HaveSequenceIn = (1 << 1),
	GC = 0,
	HaveInPlaceOps = (1 << 3),
	CheckTypes = (1 << 4),
	HaveRichCompare = (1 << 5),
	HaveWeakRefs = (1 << 6),
	HaveIter = (1 << 7),
	HaveClass = (1 << 8),
	HeapType = (1 << 9),
	BaseType = (1 << 10),
	Ready = (1 << 12),
	Readying = (1 << 13),
	HaveGC = (1 << 14),
	Managed = (1 << 30),
	Default = HaveGetCharBuffer |
	          HaveSequenceIn |
	          HaveInPlaceOps |
	          HaveRichCompare |
	          HaveWeakRefs | 
                  HaveIter |
                  HaveClass | 0
    }



    // Get thunk should be here, not in type gen / manager!

    // This class defines the function prototypes (delegates) used for low
    // level integration with the CPython runtime. It also provides name 
    // based lookup of the correct prototype for a particular slot name.

    internal class Prototypes {


	static ArrayList keepAlive;
	static Hashtable pmap;
 	static IntPtr temp;

	static Prototypes() {

	    // Here we build a mapping of PyTypeObject slot names to the
	    // appropriate prototype (delegate) type to use for the slot.

	    Type[] items = typeof(Prototypes).GetNestedTypes();
	    Hashtable p = new Hashtable();

	    for (int i = 0; i < items.Length; i++) {
		Type item = items[i];
		p[item.Name] = item;
	    }

	    keepAlive = new ArrayList();
	    temp = Marshal.AllocHGlobal(IntPtr.Size);
	    pmap = new Hashtable();

	    pmap["tp_dealloc"] = p["DestructorFunc"];
	    pmap["tp_print"] = p["PrintFunc"];
	    pmap["tp_getattr"] = p["BinaryFunc"];
	    pmap["tp_setattr"] = p["ObjObjArgFunc"];
	    pmap["tp_compare"] = p["ObjObjFunc"];
	    pmap["tp_repr"] = p["UnaryFunc"];
	    pmap["tp_hash"] = p["UnaryFunc"];
	    pmap["tp_call"] = p["TernaryFunc"];
	    pmap["tp_str"] = p["UnaryFunc"];
	    pmap["tp_getattro"] = p["BinaryFunc"];
	    pmap["tp_setattro"] = p["ObjObjArgFunc"];
	    pmap["tp_traverse"] = p["ObjObjArgFunc"];
	    pmap["tp_clear"] = p["InquiryFunc"];
	    pmap["tp_richcompare"] = p["RichCmpFunc"];
	    pmap["tp_iter"] = p["UnaryFunc"];
	    pmap["tp_iternext"] = p["UnaryFunc"];
	    pmap["tp_descr_get"] = p["TernaryFunc"];
	    pmap["tp_descr_set"] = p["ObjObjArgFunc"];
	    pmap["tp_init"] = p["ObjObjArgFunc"];
	    pmap["tp_alloc"] = p["IntArgFunc"];
	    pmap["tp_new"] = p["TernaryFunc"];
	    pmap["tp_free"] = p["DestructorFunc"];
	    pmap["tp_is_gc"] = p["InquiryFunc"];

	    pmap["nb_add"] = p["BinaryFunc"];
	    pmap["nb_subtract"] = p["BinaryFunc"];
	    pmap["nb_multiply"] = p["BinaryFunc"];
	    pmap["nb_divide"] = p["BinaryFunc"];
	    pmap["nb_remainder"] = p["BinaryFunc"];
	    pmap["nb_divmod"] = p["BinaryFunc"];
	    pmap["nb_power"] = p["TernaryFunc"];
	    pmap["nb_negative"] = p["UnaryFunc"];
	    pmap["nb_positive"] = p["UnaryFunc"];
	    pmap["nb_absolute"] = p["UnaryFunc"];
	    pmap["nb_nonzero"] = p["InquiryFunc"];
	    pmap["nb_invert"] = p["UnaryFunc"];
	    pmap["nb_lshift"] = p["BinaryFunc"];
	    pmap["nb_rshift"] = p["BinaryFunc"];
	    pmap["nb_and"] = p["BinaryFunc"];
	    pmap["nb_xor"] = p["BinaryFunc"];
	    pmap["nb_or"] = p["BinaryFunc"];
	    pmap["nb_coerce"] = p["ObjObjFunc"];
	    pmap["nb_int"] = p["UnaryFunc"];
	    pmap["nb_long"] = p["UnaryFunc"];
	    pmap["nb_float"] = p["UnaryFunc"];
	    pmap["nb_oct"] = p["UnaryFunc"];
	    pmap["nb_hex"] = p["UnaryFunc"];
	    pmap["nb_inplace_add"] = p["BinaryFunc"];
	    pmap["nb_inplace_subtract"] = p["BinaryFunc"];
	    pmap["nb_inplace_multiply"] = p["BinaryFunc"];
	    pmap["nb_inplace_divide"] = p["BinaryFunc"];
	    pmap["nb_inplace_remainder"] = p["BinaryFunc"];
	    pmap["nb_inplace_power"] = p["TernaryFunc"];
	    pmap["nb_inplace_lshift"] = p["BinaryFunc"];
	    pmap["nb_inplace_rshift"] = p["BinaryFunc"];
	    pmap["nb_inplace_and"] = p["BinaryFunc"];
	    pmap["nb_inplace_xor"] = p["BinaryFunc"];
	    pmap["nb_inplace_or"] = p["BinaryFunc"];
	    pmap["nb_floor_divide"] = p["BinaryFunc"];
	    pmap["nb_true_divide"] = p["BinaryFunc"];
	    pmap["nb_inplace_floor_divide"] = p["BinaryFunc"];
	    pmap["nb_inplace_true_divide"] = p["BinaryFunc"];

	    pmap["sq_length"] = p["InquiryFunc"];
	    pmap["sq_concat"] = p["BinaryFunc"];
	    pmap["sq_repeat"] = p["IntArgFunc"];
	    pmap["sq_item"] = p["IntArgFunc"];
	    pmap["sq_slice"] = p["IntIntArgFunc"];
	    pmap["sq_ass_item"] = p["IntObjArgFunc"];
	    pmap["sq_ass_slice"] = p["IntIntObjArgFunc"];
	    pmap["sq_contains"] = p["ObjObjFunc"];
	    pmap["sq_inplace_concat"] = p["BinaryFunc"];
	    pmap["sq_inplace_repeat"] = p["IntArgFunc"];

	    pmap["mp_length"] = p["InquiryFunc"];
	    pmap["mp_subscript"] = p["BinaryFunc"];
	    pmap["mp_ass_subscript"] = p["ObjObjArgFunc"];
	    
	    pmap["bf_getreadbuffer"] = p["IntObjArgFunc"];
	    pmap["bf_getwritebuffer"] = p["IntObjArgFunc"];
	    pmap["bf_getsegcount"] = p["ObjObjFunc"];
	    pmap["bf_getcharbuffer"] = p["IntObjArgFunc"];
	}

	internal static Type GetPrototype(string name) {
	    return pmap[name] as Type;
	}


	internal static IntPtr GetThunk(MethodInfo method) {
	    // WARNING: this probably needs a thread lock!
	    //Type dt = typeof(CallbackThunks).GetNestedType(method.Name);
	    Type dt = Prototypes.GetPrototype(method.Name);
	    if (dt != null) {
		Delegate d = Delegate.CreateDelegate(dt, method);
		CallbackThunk cb = new CallbackThunk(d);
		Marshal.StructureToPtr(cb, temp, false);
		IntPtr fp = Marshal.ReadIntPtr(temp);
		keepAlive.Add(d);
		return fp;
	    }
	    return IntPtr.Zero;
	}

	[CallConvCdecl()]
	public delegate IntPtr UnaryFunc(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr BinaryFunc(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr TernaryFunc(IntPtr ob, IntPtr a1, IntPtr a2);

	[CallConvCdecl()]
	public delegate int InquiryFunc(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr IntArgFunc(IntPtr ob, int arg);

	[CallConvCdecl()]
	public delegate IntPtr IntIntArgFunc(IntPtr ob, int a1, int a2);

	[CallConvCdecl()]
	public delegate int IntObjArgFunc(IntPtr ob, int a1, IntPtr a2);

	[CallConvCdecl()]
	public delegate int IntIntObjArgFunc(IntPtr o, int a, int b, IntPtr c);

	[CallConvCdecl()]
	public delegate int ObjObjArgFunc(IntPtr o, IntPtr a, IntPtr b);

	[CallConvCdecl()]
	public delegate int ObjObjFunc(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate void DestructorFunc(IntPtr ob);

	[CallConvCdecl()]
	public delegate int PrintFunc(IntPtr ob, IntPtr a, int b);

	[CallConvCdecl()]
	public delegate IntPtr RichCmpFunc(IntPtr ob, IntPtr a, int b);

    }


    internal class CallbackThunks {

	[CallConvCdecl()]
	public delegate void tp_dealloc(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr tp_print(IntPtr ob, IntPtr file, IntPtr flags);

	[CallConvCdecl()]
	public delegate IntPtr tp_getattr(IntPtr ob, IntPtr key);

	[CallConvCdecl()]
	public delegate int tp_setattr(IntPtr ob, IntPtr key, IntPtr val);

	[CallConvCdecl()]
	public delegate IntPtr tp_getattro(IntPtr ob, IntPtr key);

	[CallConvCdecl()]
	public delegate int tp_setattro(IntPtr ob, IntPtr key, IntPtr val);

	[CallConvCdecl()]
	public delegate int tp_compare(IntPtr ob, IntPtr other);

	[CallConvCdecl()]
	public delegate IntPtr tp_repr(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr tp_hash(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw);

	[CallConvCdecl()]
	public delegate IntPtr tp_str(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr tp_iter(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr tp_iternext(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr tp_descr_get(IntPtr desc, IntPtr ob, IntPtr tp);

	[CallConvCdecl()]
	public delegate int tp_descr_set(IntPtr desc, IntPtr ob, IntPtr tp);

	[CallConvCdecl()]
	public delegate int tp_init(IntPtr ob, IntPtr args, IntPtr kw);

	[CallConvCdecl()]
	public delegate IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw);

	[CallConvCdecl()]
	public delegate IntPtr tp_alloc(IntPtr tp, int sz);

	[CallConvCdecl()]
	public delegate void tp_free(IntPtr ob);

	[CallConvCdecl()]
	public delegate int tp_is_gc(IntPtr type);


	// PyNumberMethods prototypes

	[CallConvCdecl()]
	public delegate IntPtr nb_add(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_subtract(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_multiply(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_divide(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_remainder(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_divmod(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_power(IntPtr ob, IntPtr arg, IntPtr arg2);

	[CallConvCdecl()]
	public delegate IntPtr nb_negative(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr nb_positive(IntPtr ob);

	[CallConvCdecl()]
	public delegate IntPtr nb_absolute(IntPtr ob);



	[CallConvCdecl()]
	public delegate IntPtr nb_inplace_add(IntPtr ob, IntPtr arg);

	[CallConvCdecl()]
	public delegate IntPtr nb_inplace_subtract(IntPtr ob, IntPtr arg);


	[CallConvCdecl()]
	public delegate IntPtr generic(IntPtr ob, IntPtr args, IntPtr kw);
	
    }


    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    internal struct CallbackThunk {
	public Delegate fn;

	public CallbackThunk(Delegate d) {
	    fn = d;
	}
    }







}


=== Added File PythonNet/src/runtime/ClassBase.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Python.Runtime {

    /// <summary>
    /// Base class for Python types that reflect managed types / classes.
    /// Concrete subclasses include ClassObject and DelegateObject. This
    /// class provides common attributes and common machinery for doing
    /// class initialization (initialization of the class __dict__). The
    /// concrete subclasses provide slot implementations appropriate for
    /// each variety of reflected type.
    /// </summary>

    internal class ClassBase : ManagedType {

	internal Type type;

	internal ClassBase(Type tp) : base() {
	    tpHandle = TypeManager.GetTypeHandle(this, tp);
	    type = tp;
	    InitializeClass();
	}

	internal virtual bool CanSubclass() {
	    return (!this.type.IsEnum);
	}

	//====================================================================
	// Reflected type initialization. This uses reflection to populate the
	// __dict__ of the Python type object with descriptors that reflect
	// the attributes of the reflected type.
	//====================================================================

	protected void InitializeClass() {
	    // todo: name discrimination!
	    Hashtable methods = new Hashtable();
	    IntPtr pp = Runtime._PyObject_GetDictPtr(this.tpHandle);
	    IntPtr op = Marshal.ReadIntPtr(pp);
	    IntPtr dict = op;

	    Type type = this.type;
	    ArrayList list;
	    MethodInfo mInfo;
	    String name;
	    Object item;
	    Type tp;

	    ManagedType mt;
	    // may want to use DeclaredOnly here to match Python inheritance.

	    BindingFlags flags = BindingFlags.Static | 
		                 BindingFlags.Instance | 
	                         BindingFlags.Public | 
                                 BindingFlags.NonPublic;

	    MemberInfo[] info = type.GetMembers(flags);

	    int ilen = info.Length;
	    for (int i=0; i < ilen; i++) {

		MemberInfo mi = info[i];


		switch(mi.MemberType) {

	        case MemberTypes.Method:
		    mInfo = (MethodInfo) mi;
		    if (!(mInfo.IsPublic || mInfo.IsFamily || 
			  mInfo.IsFamilyOrAssembly))
			continue;
		    name = mInfo.Name;
		    item = methods[name];
		    if (item == null) {
			item = methods[name] = new ArrayList();
		    }
		    list = (ArrayList) item;
		    list.Add(mInfo);
		    continue;

	        case MemberTypes.Property:
		    PropertyInfo pi = (PropertyInfo) mi;

		    MethodInfo mm = null;
		    try {
			mm = pi.GetGetMethod(true);
			if (mm == null) {
			    mm = pi.GetSetMethod(true);
			}
		    }
		    catch (System.Security.SecurityException) {
			// GetGetMethod may try to get a method protected by
			// StrongNameIdentityPermission - effectively private.
			continue;
		    }

		    if (mm == null) {
			continue;
		    }

		    if (!(mm.IsPublic || mm.IsFamily || mm.IsFamilyOrAssembly))
			continue;
		    mt = new PropertyObject((PropertyInfo) mi);

		    Runtime.PyDict_SetItemString(dict, mi.Name, mt.Handle);
		    continue;

	        case MemberTypes.Field:
		    FieldInfo fi = (FieldInfo) mi;
		    if (!(fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly))
			continue;
		    mt = new FieldObject((FieldInfo) mi);
		    Runtime.PyDict_SetItemString(dict, mi.Name, mt.Handle);
		    continue;

	        case MemberTypes.Event:
		    mt = new EventObject((EventInfo) mi);
		    Runtime.PyDict_SetItemString(dict, mi.Name, mt.Handle);
		    continue;

	        case MemberTypes.NestedType:
		    tp = (Type) mi;
		    if (!(tp.IsNestedPublic || tp.IsNestedFamily || 
			  tp.IsNestedFamORAssem))
			continue;
		    mt = ClassManager.GetClass(tp);
		    Runtime.PyDict_SetItemString(dict, mi.Name, mt.Handle);
		    continue;

	        case MemberTypes.TypeInfo:
		    continue;

	        case MemberTypes.Constructor:
		    continue;

	        case MemberTypes.Custom:
		    continue;
		}
	    }

	    IDictionaryEnumerator dictIter = methods.GetEnumerator();

	    while(dictIter.MoveNext()) {
		name = (string) dictIter.Key;
		list = (ArrayList) dictIter.Value;

		MethodInfo[] mlist = (MethodInfo[])list.ToArray(typeof(MethodInfo));

		mt = new MethodObject(name, mlist);
		Runtime.PyDict_SetItemString(dict, name, mt.Handle);

	    }
	}


	//====================================================================
	// Standard comparison implementation for instances of reflected types.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_compare(IntPtr ob, IntPtr other) {
	    if (ob == other) {
		return 0;
	    }
	    CLRObject co1 = GetManagedObject(ob) as CLRObject;
	    CLRObject co2 = GetManagedObject(other) as CLRObject;
	    Object o1 = co1.inst;
	    Object o2 = co2.inst;
	    // Console.WriteLine("cmp: {0} {1}", o1, o2);
	    if (Object.Equals(o1, o2)) {
		return 0;
	    }
	    return -1;
	}

	//====================================================================
	// Standard dealloc implementation for instances of reflected types.
	//====================================================================

	[CallConvCdecl()]
	public static void tp_dealloc(IntPtr ob) {
	    ManagedType self = GetManagedObject(ob);
	    //Console.WriteLine("dealloc: {0}", self.GetType());
	    Runtime.PyMem_Free(self.pyHandle);
	    Runtime.Decref(self.tpHandle);
	    self.gcHandle.Free();
	}


    }	

}


=== Added File PythonNet/src/runtime/ClassManager.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    /// <summary>
    /// The ClassManager is responsible for creating and managing Python
    /// types that reflect managed classes, structs, interfaces, enums
    /// and delegates.
    /// </summary>

    internal class ClassManager {

	static Hashtable cache;
	static Type dtype;

	private ClassManager() {}

	static ClassManager() {
	    cache = new Hashtable();
	    dtype = typeof(System.Delegate);
	}

	/// <summary>
	/// GetClass Method
	/// </summary>
	///
	/// <remarks>
	/// Return a ClassObject that reflects the given CLR type, or null
	/// if the ClassObject cannot be created. Ref behavior??
	/// </remarks>

	internal static ClassBase GetClass(Type type) {
	    Object ob = cache[type];
	    if (ob == null) {
		ClassBase c = CreateClass(type);
		cache.Add(type, c);
		return c;
	    }
	    return (ClassBase) ob;
	}

	private static ClassBase CreateClass(Type type) {
	    if (type.IsSubclassOf(dtype)) {
		return new DelegateObject(type);
	    }

	    if (type.IsArray) {
		return new ArrayObject(type);
	    }

	    if (type.IsInterface) {
		return new InterfaceObject(type);
	    }

	    return new ClassObject(type);

	}

    }	

}


=== Added File PythonNet/src/runtime/ClassObject.cs ===
// Copyright (c) 2003 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Reflection;

namespace Python.Runtime {

    /// <summary>
    /// Managed class that provides the implementation for reflected types.
    /// Managed classes and value types are represented in Python by actual 
    /// Python type objects. Each of those type objects is associated with 
    /// an instance of ClassObject, which provides its implementation.
    /// </summary>

    internal class ClassObject : ClassBase {

	ConstructorBinder binder;

	internal ClassObject(Type tp) : base(tp) {
	    ConstructorInfo[] ctors = type.GetConstructors();
	    binder = new ConstructorBinder();

	    for (int i = 0; i < ctors.Length; i++) {
		binder.AddMethod(ctors[i]);
	    }
	}

	//====================================================================
	// Implements __new__ for reflected classes and value types.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {
	    ClassObject self = (ClassObject)GetManagedObject(tp);
	    Type type = self.type;

	    // Primitive types do not have constructors, but they look like
	    // they do from Python. If the ClassObject represents one of the 
	    // convertible primitive types, just convert the arg directly.

	    if (type.IsPrimitive || type == typeof(String)) {
		if (Runtime.PyTuple_Size(args) != 1) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "no constructors match given arguments"
			       );
		    return IntPtr.Zero;
		}

		IntPtr op = Runtime.PyTuple_GetItem(args, 0);
		Object result;

		if (!Converter.ToManaged(op, type, out result, true)) {
		    return IntPtr.Zero;
		}
		op = CLRObject.GetInstHandle(result, tp);
		Runtime.Incref(op);
		return op;
	    }

	    if (type.IsAbstract) {
		Exceptions.SetError(Exceptions.TypeError, 
			   "cannot instantiate abstract class"
			   );
		return IntPtr.Zero;
	    }

	    if (type.IsEnum) {
		Exceptions.SetError(Exceptions.TypeError, 
			   "cannot instantiate enumeration"
			   );
		return IntPtr.Zero;
	    }

	    return self.binder.Invoke(IntPtr.Zero, args, kw);
	}

	//====================================================================
	// Implements __init__ for reflected classes and value types.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw) {
	    return 0;
	}


    }	

}


=== Added File PythonNet/src/runtime/CodeGenerator.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

namespace Python.Runtime {

    /// <summary>
    /// Several places in the runtime generate code on the fly to support
    /// dynamic functionality. The CodeGenerator class manages the dynamic
    /// assembly used for code generation and provides utility methods for
    /// certain repetitive tasks.
    /// </summary>

    internal class CodeGenerator {

	static AssemblyBuilder aBuilder;
	static ModuleBuilder mBuilder;

	static CodeGenerator() {
	    AssemblyName aname = new AssemblyName();
	    aname.Name = "__CodeGenerator_Assembly";
	    AssemblyBuilderAccess aa = AssemblyBuilderAccess.Run;

	    aBuilder = Thread.GetDomain().DefineDynamicAssembly(aname, aa);
	    mBuilder = aBuilder.DefineDynamicModule("__CodeGenerator_Module");

	}

	//====================================================================
	// DefineType is a shortcut utility to get a new TypeBuilder.
	//====================================================================

	internal static TypeBuilder DefineType(string name) {
	    TypeAttributes attrs = TypeAttributes.Public;
	    return mBuilder.DefineType(name, attrs);
	}

	//====================================================================
	// DefineType is a shortcut utility to get a new TypeBuilder.
	//====================================================================

	internal static TypeBuilder DefineType(string name, Type basetype) {
	    TypeAttributes attrs = TypeAttributes.Public;
	    return mBuilder.DefineType(name, attrs, basetype);
	}

    }


}


=== Added File PythonNet/src/runtime/ConstructorBinder.cs ===
// Copyright (c) 2003 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // A ConstructorBinder encapsulates information about one or more managed
    // constructors, and is responsible for selecting the right constructor
    // given a set of Python arguments. This is slightly different than the
    // standard MethodBinder because of a difference in invoking constructors
    // using reflection (which is seems to be a CLR bug).
    //========================================================================

    internal class ConstructorBinder : MethodBinder {

	internal ConstructorBinder () : base() {}

	internal override IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {
	    Binding binding = this.Bind(inst, args, kw);
	    Object result;

	    if (binding == null) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "no constructor matches given arguments"
				    );
		return IntPtr.Zero;
	    }

	    ConstructorInfo ci = (ConstructorInfo)binding.info;
	    try {
		result = ci.Invoke(binding.args);
	    }
	    catch (Exception e) {
		if (e.InnerException != null) {
		    e = e.InnerException;
		}
		Exceptions.SetError(e);
		return IntPtr.Zero;
	    }

	    return Converter.ToPython(result, result.GetType());
	}

    }


}


=== Added File PythonNet/src/runtime/Converter.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;

namespace Python.Runtime {

    //========================================================================
    // Performs data conversions between managed types and Python types.
    //========================================================================

    [SuppressUnmanagedCodeSecurityAttribute()]

    internal class Converter {

	private Converter() {}

	static Type objectType;
	static Type flagsType;

	static Converter () {
	    objectType = typeof(Object);
	    flagsType = typeof(FlagsAttribute);
	}


	//====================================================================
	// Return a Python object for the given native object, converting
	// basic types (string, int, etc.) into equivalent Python objects.
	// This always returns a new reference. Note that the System.Decimal 
	// type has no Python equivalent and converts to a managed instance.
	//====================================================================

	internal static IntPtr ToPython(Object value, Type type) {
	    IntPtr result = IntPtr.Zero;

	    // Null always converts to None in Python.

	    if (value == null) {
		result = Runtime.PyNone;
		Runtime.Incref(result);
		return result;
	    }

	    // Special case: if the input conversion type is 'Object', we
	    // convert to the actual runtime type of the input value.

	    if (type == objectType) {
		type = value.GetType();
	    }

	    TypeCode tc = Type.GetTypeCode(type);

	    switch(tc) {

	    case TypeCode.Object:
		result = CLRObject.GetInstHandle(value, type);
		Runtime.Incref(result);
		return result;

	    case TypeCode.String:
		return Runtime.PyUnicode_FromString((string)value);

	    case TypeCode.Int32:
		return Runtime.PyInt_FromLong((int)value);

	    case TypeCode.Boolean:
		int i = (bool) value ? 1 : 0;
		return Runtime.PyInt_FromLong(i);

	    case TypeCode.Byte:
		return Runtime.PyInt_FromLong((int)((byte)value));

	    case TypeCode.Char:
		return Runtime.PyUnicode_FromOrdinal((int)((char)value));
	      
	    case TypeCode.Int16:
		return Runtime.PyInt_FromLong((int)((short)value));

	    case TypeCode.Int64:
		return Runtime.PyLong_FromLongLong((long)value);

	    case TypeCode.Single:
	        string ss = ((float)value).ToString();
		IntPtr ps = Runtime.PyString_FromString(ss);
	        IntPtr op = Runtime.PyFloat_FromString(ps, IntPtr.Zero);
		Runtime.Decref(ps);
		return op;

	    case TypeCode.Double:
		return Runtime.PyFloat_FromDouble((double)value);

	    case TypeCode.SByte:
		return Runtime.PyInt_FromLong((int)((sbyte)value));

	    case TypeCode.UInt16:
		return Runtime.PyInt_FromLong((int)((ushort)value));

	    case TypeCode.UInt32:
		return Runtime.PyLong_FromUnsignedLong((uint)value);

	    case TypeCode.UInt64:
		return Runtime.PyLong_FromUnsignedLongLong((ulong)value);

	    default:
		result = CLRObject.GetInstHandle(value, type);
		Runtime.Incref(result);
		return result;
	    }

	}

	//====================================================================
	// Return a managed object for the given Python object, converting
	// basic types (string, int, etc.) into required managed objects.
	//====================================================================

	internal static bool ToManaged(IntPtr value, Type obType, 
				      out Object result, bool setError) {

	    // Common case: if the Python value is a wrapped managed object
	    // instance, just return the wrapped object.

	    ManagedType mt = ManagedType.GetManagedObject(value);
	    result = null;

	    if (mt != null) {
		if (mt is CLRObject) {
		    result = ((CLRObject)mt).inst;
		    return true;
		}
		if (mt is ClassBase) {
		    result = ((ClassBase)mt).type;
		    return true;
		}
		// shouldnt happen
		return false;
	    }

	    if (obType.IsEnum) {
		return ToEnum(value, obType, out result, setError);
	    }

	    if (value == Runtime.PyNone && !obType.IsPrimitive) {
		result = null;
		return true;
	    }

	    return ToPrimitive(value, obType, out result, setError);

	}

	//====================================================================
	// Convert a Python value to an instance of a primitive managed type.
	//====================================================================

	static bool ToPrimitive(IntPtr value, Type obType, out Object result, 
				bool setError) {

	    IntPtr overflow = Exceptions.OverflowError;
	    TypeCode tc = Type.GetTypeCode(obType);
	    result = null;
	    IntPtr op;
	    int ival;

	    switch(tc) {

	    case TypeCode.String:
		string st = Runtime.GetManagedString(value);
		if (st == null) {
		    goto type_error;
		}
		result = st;
		return true;

	    case TypeCode.Int32:
		// Trickery to support 64-bit platforms.
	        if (IntPtr.Size == 4) {
		    op = Runtime.PyNumber_Int(value);
		    if (op == IntPtr.Zero) {
		        if (Exceptions.ExceptionMatches(overflow)) {
			    goto overflow;
		      }
		      goto type_error;
		    }
		    ival = (int)Runtime.PyInt_AsLong(op);
		    Runtime.Decref(op);
		    result = ival;
		    return true;
		}
		else {
		    op = Runtime.PyNumber_Long(value);
		    if (op == IntPtr.Zero) {
		        if (Exceptions.ExceptionMatches(overflow)) {
			    goto overflow;
			}
			goto type_error;
		    }
		    long ll = (long)Runtime.PyLong_AsLongLong(op);
		    Runtime.Decref(op);
		    if ((ll == -1) && Exceptions.ErrorOccurred()) {
		        goto overflow;
		    }
		    if (ll > Int32.MaxValue || ll < Int32.MinValue) {
		        goto overflow;
		    }
		    result = (int)ll;
		    return true;
		}

	    case TypeCode.Boolean:
		result = (Runtime.PyObject_IsTrue(value) != 0);
		return true;

	    case TypeCode.Byte:
		op = Runtime.PyNumber_Int(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		ival = (int) Runtime.PyInt_AsLong(op);
		Runtime.Decref(op);

		if (ival > Byte.MaxValue || ival < Byte.MinValue) {
		    goto overflow;
		}
		byte b = (byte) ival;
		result = b;
		return true;

	    case TypeCode.SByte:
		op = Runtime.PyNumber_Int(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		ival = (int) Runtime.PyInt_AsLong(op);
		Runtime.Decref(op);

		if (ival > SByte.MaxValue || ival < SByte.MinValue) {
		    goto overflow;
		}
		sbyte sb = (sbyte) ival;
		result = sb;
		return true;

	    case TypeCode.Char:

		if (Runtime.PyObject_TypeCheck(value, Runtime.PyStringType)) {
		    if (Runtime.PyString_Size(value) == 1) {
			op = Runtime.PyString_AS_STRING(value);
			result = (char)Marshal.ReadByte(op);
			return true;
		    }
		    goto type_error;
		}

		else if (Runtime.PyObject_TypeCheck(value, 
				 Runtime.PyUnicodeType)) {
		    if (Runtime.PyUnicode_GetSize(value) == 1) {
			op = Runtime.PyUnicode_AS_UNICODE(value);
			result = (char)Marshal.ReadInt16(op);
			return true;
		    }
		    goto type_error;
		}

		op = Runtime.PyNumber_Int(value);
		if (op == IntPtr.Zero) {
		    goto type_error;
		}
		ival = Runtime.PyInt_AsLong(op);
		if (ival > Char.MaxValue || ival < Char.MinValue) {
		    goto overflow;
		}
		Runtime.Decref(op);
		result = (char)ival;
		return true;

	    case TypeCode.Int16:
		op = Runtime.PyNumber_Int(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		ival = (int) Runtime.PyInt_AsLong(op);
		Runtime.Decref(op);
		if (ival > Int16.MaxValue || ival < Int16.MinValue) {
		    goto overflow;
		}
		short s = (short) ival;
		result = s;
		return true;

	    case TypeCode.Int64:
		op = Runtime.PyNumber_Long(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		long l = (long)Runtime.PyLong_AsLongLong(op);
		Runtime.Decref(op);
		if ((l == -1) && Exceptions.ErrorOccurred()) {
		    goto overflow;
		}
		result = l;
		return true;

	    case TypeCode.UInt16:
		op = Runtime.PyNumber_Int(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		ival = (int) Runtime.PyInt_AsLong(op);
		Runtime.Decref(op);
		if (ival > UInt16.MaxValue || ival < UInt16.MinValue) {
		    goto overflow;
		}
		ushort us = (ushort) ival;
		result = us;
		return true;

	    case TypeCode.UInt32:
		op = Runtime.PyNumber_Long(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		uint ui = (uint)Runtime.PyLong_AsUnsignedLong(op);
		Runtime.Decref(op);
		if (Exceptions.ErrorOccurred()) {
		    goto overflow;
		}
		result = ui;
		return true;

	    case TypeCode.UInt64:
		op = Runtime.PyNumber_Long(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		ulong ul = (ulong)Runtime.PyLong_AsUnsignedLongLong(op);
		Runtime.Decref(op);
		if (Exceptions.ErrorOccurred()) {
		    goto overflow;
		}
		result = ul;
		return true;


	    case TypeCode.Single:
		op = Runtime.PyNumber_Float(value);
		if (op == IntPtr.Zero) {
		    if (Exceptions.ExceptionMatches(overflow)) {
			goto overflow;
		    }
		    goto type_error;
		}
		double dd = Runtime.PyFloat_AsDouble(value);
		if (dd > Single.MaxValue || dd < Single.MinValue) {
		    goto overflow;
		}
		result = (float)dd;
		return true;

	    case TypeCode.Double:
		op = Runtime.PyNumber_Float(value);
		if (op == IntPtr.Zero) {
		    goto type_error;
		}
		double d = Runtime.PyFloat_AsDouble(op);
		Runtime.Decref(op);
		if (d > Double.MaxValue || d < Double.MinValue) {
		    goto overflow;
		}
		result = d;
		return true;

	    }


	type_error:

	    if (setError) {
		string format = "'{0}' value cannot be converted to {1}";
		string tpName = Runtime.PyObject_GetTypeName(value);
		string error = String.Format(format, tpName, obType);
		Exceptions.SetError(Exceptions.TypeError, error);
	    }

	    return false;

	overflow:

	    if (setError) {
		string error = "value too large to convert";
		Exceptions.SetError(Exceptions.OverflowError, error);
	    }

	    return false;

	}

	//====================================================================
	// Convert a Python value to a correctly typed managed enum instance.
	//====================================================================

	static bool ToEnum(IntPtr value, Type obType, out Object result, 
			   bool setError) {

	    Type etype = Enum.GetUnderlyingType(obType);
	    result = null;

	    if (!ToPrimitive(value, etype, out result, setError)) {
		return false;
	    }

	    if (Enum.IsDefined(obType, result)) {
		result = Enum.ToObject(obType, result);		
		return true;
	    }

	    if (obType.GetCustomAttributes(flagsType, true).Length > 0) {
		result = Enum.ToObject(obType, result);
		return true;
	    }

	    if (setError) {
		string error = "invalid enumeration value";
		Exceptions.SetError(Exceptions.ValueError, error);
	    }

	    return false;

	}

    }


}


=== Added File PythonNet/src/runtime/DebugHelper.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace Python.Runtime {

    /// <summary>
    /// Debugging helper utilities.
    /// </summary>

    internal class DebugUtil {

	public static void Print(string msg, params IntPtr[] args) {
	    string result = msg;
	    result += " ";

	    for (int i = 0; i < args.Length; i++) {
		IntPtr ob = Runtime.PyObject_Repr(args[i]);
		result += Runtime.PyString_AsString(ob);
		Runtime.Decref(ob);
		result += " ";
	    }
	    Console.WriteLine(result);
	    return;
	}



    }


}



=== Added File PythonNet/src/runtime/DelegateManager.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

namespace Python.Runtime {

    /// <summary>
    /// The DelegateManager class manages the creation of delegate instances
    /// that dispatch calls to Python methods and other callable objects.
    /// </summary>

    internal class DelegateManager {

	static Hashtable cache;
	static Type basetype;
	static Type listtype;
	static Type voidtype;
	static Type typetype;
	static Type ptrtype;

	static DelegateManager() {
	    basetype = typeof(Dispatcher);
	    listtype = typeof(ArrayList);
	    voidtype = typeof(void);
	    typetype = typeof(Type);
	    ptrtype = typeof(IntPtr);
	    cache = new Hashtable();
	}

	//====================================================================
	// Given a true delegate instance, return the PyObject handle of the
	// Python object implementing the delegate (or IntPtr.Zero if the
	// delegate is not implemented in Python code.
	//====================================================================

	public static IntPtr GetPythonHandle(Delegate d) {
	    if ((d != null) && (d.Target is Dispatcher)) {
		Dispatcher disp = d.Target as Dispatcher;
		return disp.target;
	    }
	    return IntPtr.Zero;
	}

	//====================================================================
	// GetDispatcher is responsible for creating a class that provides
	// an appropriate managed callback method for a given delegate type.
	//====================================================================
	
	private static Type GetDispatcher(Type dtype) {

	    // If a dispatcher type for the given delegate type has already 
	    // been generated, get it from the cache. The cache maps delegate
	    // types to generated dispatcher types. A possible optimization
	    // for the future would be to generate dispatcher types based on
	    // unique signatures rather than delegate types, since multiple
	    // delegate types with the same sig could use the same dispatcher.

	    Object item = cache[dtype];
	    if (item != null) {
		return (Type)item;
	    }

	    string name = "__" + dtype.FullName + "Dispatcher";
	    name = name.Replace('.', '_');
	    name = name.Replace('+', '_');
	    TypeBuilder tb = CodeGenerator.DefineType(name, basetype);

	    // Generate a constructor for the generated type that calls the
	    // appropriate constructor of the Dispatcher base type.

	    MethodAttributes ma = MethodAttributes.Public |
		                  MethodAttributes.HideBySig |
		                  MethodAttributes.SpecialName | 
		                  MethodAttributes.RTSpecialName;
	    CallingConventions cc = CallingConventions.Standard;
	    Type[] args = {ptrtype, typetype};
	    ConstructorBuilder cb = tb.DefineConstructor(ma, cc, args);
	    ConstructorInfo ci = basetype.GetConstructor(args);
	    ILGenerator il = cb.GetILGenerator();
	    il.Emit(OpCodes.Ldarg_0);
	    il.Emit(OpCodes.Ldarg_1);
	    il.Emit(OpCodes.Ldarg_2);
	    il.Emit(OpCodes.Call, ci);
	    il.Emit(OpCodes.Ret);

	    // Method generation: we generate a method named "Invoke" on the
	    // dispatcher type, whose signature matches the delegate type for
	    // which it is generated. The method body simply packages the
	    // arguments and hands them to the Dispatch() method, which deals
	    // with converting the arguments, calling the Python method and
	    // converting the result of the call.

	    MethodInfo method = dtype.GetMethod("Invoke");
	    ParameterInfo[] pi = method.GetParameters();

	    Type[] signature = new Type[pi.Length];
	    for (int i = 0; i < pi.Length; i++) {
		signature[i] = pi[i].ParameterType;
	    }

	    MethodBuilder mb = tb.DefineMethod(
				  "Invoke",
				  MethodAttributes.Public, 
				  method.ReturnType,
				  signature
				  );

	    ConstructorInfo ctor = listtype.GetConstructor(Type.EmptyTypes);
	    MethodInfo dispatch = basetype.GetMethod("Dispatch");
	    MethodInfo add = listtype.GetMethod("Add");

	    il = mb.GetILGenerator();
	    il.DeclareLocal(listtype);
	    il.Emit(OpCodes.Newobj, ctor);
	    il.Emit(OpCodes.Stloc_0);

	    for (int c = 0; c < signature.Length; c++) {
		Type t = signature[c];
		il.Emit(OpCodes.Ldloc_0);
		il.Emit(OpCodes.Ldarg_S, (byte)(c + 1));

		if (t.IsValueType) {
		    il.Emit(OpCodes.Box, t);
		}

		il.Emit(OpCodes.Callvirt, add);
		il.Emit(OpCodes.Pop);
	    }

	    il.Emit(OpCodes.Ldarg_0);
	    il.Emit(OpCodes.Ldloc_0);
	    il.Emit(OpCodes.Call, dispatch);

	    if (method.ReturnType == voidtype) {
		il.Emit(OpCodes.Pop);
	    }

	    il.Emit(OpCodes.Ret);

	    Type disp = tb.CreateType();
	    cache[dtype] = disp;
	    return disp;
	}

	//====================================================================
	// Given a delegate type and a callable Python object, GetDelegate
	// returns an instance of the delegate type. The delegate instance
	// returned will dispatch calls to the given Python object.
	//====================================================================

	internal static Delegate GetDelegate(Type dtype, IntPtr callable) {
	    Type dispatcher = GetDispatcher(dtype);
	    object[] args = {callable, dtype};
	    object o = Activator.CreateInstance(dispatcher, args);
	    return Delegate.CreateDelegate(dtype, o, "Invoke");
	}



    }


    /* When a delegate instance is created that has a Python implementation,
       the delegate manager generates a custom subclass of Dispatcher and
       instantiates it, passing the IntPtr of the Python callable.

       The "real" delegate is created using CreateDelegate, passing the 
       instance of the generated type and the name of the (generated)
       implementing method (Invoke).

       The true delegate instance holds the only reference to the dispatcher
       instance, which ensures that when the delegate dies, the Finalize 
       of the referenced instance will be able to decref the Python 
       callable.

       A possible alternate strategy would be to create custom subclasses
       of the required delegate type, storing the IntPtr in it directly.
       This would be slightly cleaner, but I'm not sure if delegates are
       too "special" for this to work. It would be more work, so for now
       the 80/20 rule applies :)

       TODO: how does async invokation of a delegate work w/Python?
    */

    public class Dispatcher {

	public IntPtr target;
	public Type dtype;

	public Dispatcher(IntPtr target, Type dtype) {

	    // method / target object. 
	    Runtime.Incref(target);
	    this.target = target;
	    this.dtype = dtype;
	}

	public object Dispatch(ArrayList args) {
	    // check refs

	    // TODO: Should probably check here to see if we are being called 
	    // on an async thread. If so, need to register with Python.

	    MethodInfo method = dtype.GetMethod("Invoke");
	    ParameterInfo[] pi = method.GetParameters();
	    IntPtr pyargs = Runtime.PyTuple_New(pi.Length);
	    Type rtype = method.ReturnType;

	    for (int i = 0; i < pi.Length; i++) {
		IntPtr arg = Converter.ToPython(args[i], pi[i].ParameterType);
		int r = Runtime.PyTuple_SetItem(pyargs, i, arg);
	    }

	    IntPtr op = Runtime.PyObject_Call(target, pyargs, IntPtr.Zero);

	    Runtime.Decref(pyargs);
	    if (op == IntPtr.Zero) {
		PythonException e = new PythonException();
		throw e;
	    }

	    if (rtype == typeof(void)) {
		return null;
	    }

	    Object result = null;
	    if (!Converter.ToManaged(op, rtype, out result, false)) {
		string s = "could not convert Python result to " +
		           rtype.ToString();
		Runtime.Decref(op);
		throw new ConversionException(s);
	    }

	    Runtime.Decref(op);
	    return result;
	}

	public void Finalize() {
	    // The dispatcher instance owns the reference to the Python
	    // method. When the true delegate dies, we die and can decref.
	    Runtime.Decref(target);
	}

	/*
	public object InvokeTemplate(int a1, int a2, int a3) {
	    ArrayList args = new ArrayList();
	    args.Add(a1);
	    args.Add(a2);
	    args.Add(a3);
	    return this.Dispatch(args);
	}
	*/
	
    }


    public class ConversionException : System.Exception {

	public ConversionException() : base() {}

	public ConversionException(string msg) : base(msg) {}

    }


}


=== Added File PythonNet/src/runtime/DelegateObject.cs ===
// Copyright (c) 2003 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Reflection;

namespace Python.Runtime {

    /// <summary>
    /// Managed class that provides the implementation for reflected delegate
    /// types. Delegates are represented in Python by generated type objects. 
    /// Each of those type objects is associated an instance of this class, 
    /// which provides its implementation.
    /// </summary>

    internal class DelegateObject : ClassBase {

	MethodBinder binder;

	internal DelegateObject(Type tp) : base(tp) {
	    binder = new MethodBinder(tp.GetMethod("Invoke"));
	}

	//====================================================================
	// Given a PyObject pointer to an instance of a delegate type, return
	// the true managed delegate the Python object represents (or null).
	//====================================================================

	private static Delegate GetTrueDelegate(IntPtr op) {
	    CLRObject o = GetManagedObject(op) as CLRObject;
	    if (o != null) {
		Delegate d = o.inst as Delegate;
		return d;
	    }
	    return null;
	}

	internal override bool CanSubclass() {
	    return false;
	}

	//====================================================================
	// DelegateObject __new__ implementation. The result of this is a new
	// PyObject whose type is DelegateObject and whose ob_data is a handle
	// to an actual delegate instance. The method wrapped by the actual
	// delegate instance belongs to an object generated to relay the call
	// to the Python callable passed in.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {
	    DelegateObject self = (DelegateObject)GetManagedObject(tp);

	    if (Runtime.PyTuple_Size(args) != 1) {
		Exceptions.SetError(Exceptions.TypeError,
				    "class takes exactly one argument"
				    );
		return IntPtr.Zero;
	    }

	    IntPtr method = Runtime.PyTuple_GetItem(args, 0);

	    if (Runtime.PyCallable_Check(method) != 1) {
		Exceptions.SetError(Exceptions.TypeError,
				    "argument must be callable"
				    );
		return IntPtr.Zero;
	    }

	    Delegate d = DelegateManager.GetDelegate(self.type, method);
	    IntPtr op = CLRObject.GetInstHandle(d, self.Handle);
	    Runtime.Incref(op);
	    return op;
	}

	//====================================================================
	// Implements __init__ for reflected delegate types.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw) {
	    return 0;
	}

	//====================================================================
	// Implements __call__ for reflected delegate types.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) {
	    // todo: add fast type check!
	    IntPtr pytype = Runtime.PyObject_Type(ob);
	    DelegateObject self = (DelegateObject)GetManagedObject(pytype);
	    CLRObject o = GetManagedObject(ob) as CLRObject;

	    if (o == null) {
		Exceptions.SetError(Exceptions.TypeError, "invalid argument");
		return IntPtr.Zero;
	    }
	    
	    Delegate d = o.inst as Delegate;

	    if (d == null) {
		Exceptions.SetError(Exceptions.TypeError, "invalid argument");
		return IntPtr.Zero;
	    }

	    return self.binder.Invoke(ob, args, kw);
	}

	//====================================================================
	// Implements __cmp__ for reflected delegate types.
	//====================================================================

	[CallConvCdecl()]
	public static new int tp_compare(IntPtr ob, IntPtr other) {
	    Delegate d1 = GetTrueDelegate(ob);
	    Delegate d2 = GetTrueDelegate(other);
	    if (d1 == d2) {
		return 0;
	    }
	    return -1;
	}


	/*
	public override IntPtr ClassRepr() {
	    string s = String.Format("<delegate '{0}'>", this.type.FullName);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}
	*/

    }	

}


=== Added File PythonNet/src/runtime/EventBinding.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python event binding type, similar to a method binding.
    //========================================================================

    internal class EventBinding : ExtensionType {

	EventObject e;
	IntPtr target;

	public EventBinding(EventObject e, IntPtr target) : base() {
	    Runtime.Incref(target);
	    this.target = target;
	    this.e = e;
	}

	//====================================================================
	// EventBinding += operator implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr nb_inplace_add(IntPtr ob, IntPtr arg) {
	    EventBinding self = (EventBinding)GetManagedObject(ob);
	    int result = self.e.AddEventHandler(self.target, arg);
	    if (result == -1) {
		return IntPtr.Zero;
	    }
	    Runtime.Incref(self.Handle);
	    return self.Handle;
	}

	//====================================================================
	// EventBinding -= operator implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr nb_inplace_subtract(IntPtr ob, IntPtr arg) {
	    EventBinding self = (EventBinding)GetManagedObject(ob);
	    int result = self.e.RemoveEventHandler(self.target, arg);
	    if (result == -1) {
		return IntPtr.Zero;
	    }
	    Runtime.Incref(self.Handle);
	    return self.Handle;
	}

	//====================================================================
	// EventBinding __call__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) {
	    EventBinding self = (EventBinding)GetManagedObject(ob);
	    return self.e.Invoke(self.target, args, kw);
	}

	//====================================================================
	// EventBinding __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    EventBinding self = (EventBinding)GetManagedObject(ob);
	    string type = (self.target == IntPtr.Zero) ? "unbound" : "bound";
	    string s = String.Format("<{0} event '{1}'>", type, self.e.name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

	//====================================================================
	// EventBinding dealloc implementation.
	//====================================================================

	[CallConvCdecl()]
	public static new void tp_dealloc(IntPtr ob) {
	    EventBinding self = (EventBinding)GetManagedObject(ob);
	    Runtime.Decref(self.target);
	    ExtensionType.FinalizeObject(self);
	}

    }


}


=== Added File PythonNet/src/runtime/EventObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python descriptor type that provides access to CLR events.
    //========================================================================

    internal class EventObject : ExtensionType {

	static Hashtable registry;

	internal string name;
	EventBinding unbound;
	EventInfo info;

	public EventObject(EventInfo info) : base() {
	    this.name = info.Name;
	    this.info = info;
	}

	static EventObject() {
	    registry = new Hashtable();
	}



	public int AddEventHandler(IntPtr target, IntPtr handler) {
	    Object obj = null;
	    if (target != IntPtr.Zero) {
		CLRObject co = (CLRObject)ManagedType.GetManagedObject(target);
		obj = co.inst;
	    }

	    //try {
		Type htype = this.info.EventHandlerType;
		Delegate d = DelegateManager.GetDelegate(htype, handler);
		this.info.AddEventHandler(obj, d);
//  	    }
//  	    catch(Exception e) {
//  		Exceptions.SetError(Exceptions.TypeError, e.Message);
//  		return -1;
//  	    }

	    return 0;
	}

	public int RemoveEventHandler(IntPtr target, IntPtr arg) {
	    return -1;
	}

	public IntPtr Invoke(IntPtr target, IntPtr args, IntPtr kw) {
	    MethodInfo method = info.GetRaiseMethod();
	    MethodBinder binder = new MethodBinder(method);
	    return binder.Invoke(target, args, kw);
	}

	//====================================================================
	// Descriptor __get__ implementation. A getattr on an event returns
	// a "bound" event that keeps a reference to the object instance,
	// making events first-class Python objects similar to methods.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
	    EventObject self = (EventObject)GetManagedObject(ds);
	    EventBinding binding;

	    // If the event is accessed through its type (rather than via
	    // an instance) we return an 'unbound' EventBinding that will
	    // cached for future accesses through the type.

	    if (ob == IntPtr.Zero) {
		if (self.unbound == null) {
		    self.unbound = new EventBinding(self, IntPtr.Zero);
		}
		binding = self.unbound;
		Runtime.Incref(binding.Handle);
		return binding.Handle;
	    }

	    if (Runtime.PyObject_IsInstance(ob, tp) == 0) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "invalid descriptor argument"
				    );
		return IntPtr.Zero;
	    }

	    binding = new EventBinding(self, ob);
	    return binding.Handle;
	}

	//====================================================================
	// Descriptor __set__ implementation. This actually never allows you
	// to set anything; it exists solely to support the '+=' spelling of
	// event handler registration. The reason is that given code like:
	// 'ob.SomeEvent += method', Python will attempt to set the attribute
	// SomeEvent on ob to the result of the '+=' operation.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) {
	    EventObject self = (EventObject)GetManagedObject(ds);
	    ManagedType m = GetManagedObject(val);
	    // fix to make this a simple type check...
	    if (m is EventBinding) {
		return 0;
	    }
	    string message = "cannot set event attributes";
	    Exceptions.SetError(Exceptions.TypeError, message);
	    return -1;
	}


	//====================================================================
	// Descriptor __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    EventObject self = (EventObject)GetManagedObject(ob);
	    string s = String.Format("<event '{0}'>", self.info.Name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

	//====================================================================
	// Descriptor dealloc implementation.
	//====================================================================

	[CallConvCdecl()]
	public static new void tp_dealloc(IntPtr ob) {
	    EventObject self = (EventObject)GetManagedObject(ob);
	    if (self.unbound != null) {
		Runtime.Decref(self.unbound.Handle);
	    }
	    ExtensionType.FinalizeObject(self);
	}

    }


}


=== Added File PythonNet/src/runtime/Exceptions.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Reflection;

namespace Python.Runtime {

    /// <summary>
    /// Encapsulates the Python exception APIs.
    /// </summary>

    public class Exceptions {

	private Exceptions() {}

	// This is called when the Python runtime is intitialized. It 
	// uses reflection to populate static fields that expose handles
	// to the standard Python exception types.

	internal static void Initialize() {
	    IntPtr module = Runtime.PyImport_ImportModule("exceptions");
	    Type type = typeof(Exceptions);

	    foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | 
						    BindingFlags.Static)) {
		IntPtr op = Runtime.PyObject_GetAttrString(module, fi.Name);
		if (op != IntPtr.Zero) {
		    fi.SetValue(type, op);
		}
	    }
	    Runtime.Decref(module);
	    Runtime.PyErr_Clear();
	}

	/// <summary>
	/// GetException Method
	/// </summary>
	///
	/// <remarks>
	/// Retrieve Python exception information as a PythonException
	/// instance. The properties of the PythonException may be used
	/// to access the exception type, value and traceback info.
	/// </remarks>

	public static PythonException GetException() {
	    // TODO: implement this.
	    return null;
	}

	/// <summary>
	/// ExceptionMatches Method
	/// </summary>
	///
	/// <remarks>
	/// Returns true if the current Python exception matches the given
	/// Python object. This is a wrapper for PyErr_ExceptionMatches.
	/// </remarks>

	public static bool ExceptionMatches(IntPtr ob) {
	    return Runtime.PyErr_ExceptionMatches(ob) != 0;
	}

	/// <summary>
	/// ExceptionMatches Method
	/// </summary>
	///
	/// <remarks>
	/// Returns true if the given Python exception matches the given
	/// Python object. This is a wrapper for PyErr_GivenExceptionMatches.
	/// </remarks>

	public static bool ExceptionMatches(IntPtr exc, IntPtr ob) {
	    int i = Runtime.PyErr_GivenExceptionMatches(exc, ob);
	    return (i != 0);
	}

	/// <summary>
	/// SetError Method
	/// </summary>
	///
	/// <remarks>
	/// Sets the current Python exception given a native string.
	/// This is a wrapper for the Python PyErr_SetString call.
	/// </remarks>

	public static void SetError(IntPtr ob, string value) {
	    Runtime.PyErr_SetString(ob, value);
	}

	/// <summary>
	/// SetError Method
	/// </summary>
	///
	/// <remarks>
	/// Sets the current Python exception given a Python object.
	/// This is a wrapper for the Python PyErr_SetObject call.
	/// </remarks>

	public static void SetError(IntPtr ob, IntPtr value) {
	    Runtime.PyErr_SetObject(ob, value);
	}

	/// <summary>
	/// SetError Method
	/// </summary>
	///
	/// <remarks>
	/// Sets the current Python exception given a CLR exception
	/// object. The CLR exception instance is wrapped as a Python
	/// object, allowing it to be handled naturally from Python.
	/// </remarks>

	public static void SetError(Exception e) {
	    Runtime.PyErr_Clear();
	    IntPtr op = CLRObject.GetInstHandle(e);
	    Runtime.Incref(op);
	    Runtime.PyErr_SetString(op, e.Message);
	}

	/// <summary>
	/// SetFromErrno Method
	/// </summary>
	///
	/// <remarks>
	/// Sets the current Python exception based on the C errno.
	/// This is a wrapper for the Python PyErr_SetFromErrno call.
	/// </remarks>

	//public static void SetFromErrno(PyObject ob) {
	//    Runtime.PyErr_SetFromErrno(ob.Handle);
	//}

	/// <summary>
	/// ErrorOccurred Method
	/// </summary>
	///
	/// <remarks>
	/// Returns true if an exception occurred in the Python runtime.
	/// This is a wrapper for the Python PyErr_Occurred call.
	/// </remarks>

	public static bool ErrorOccurred() {
	    return Runtime.PyErr_Occurred() != 0;
	}

	/// <summary>
	/// Clear Method
	/// </summary>
	///
	/// <remarks>
	/// Clear any exception that has been set in the Python runtime.
	/// </remarks>

	public static void Clear() {
	    Runtime.PyErr_Clear();
	}

	/// <summary>
	/// Restore Method
	/// </summary>
	///
	/// <remarks>
	/// Set Python exception information from the given Python objects.
	/// This is a wrapper for the Python PyErr_Restore call.
	/// </remarks>

	//public static void Restore(PyObject type, PyObject val, PyObject tb) {
	//Runtime.PyErr_Restore(type.Handle, val.Handle, tb.Handle);
	//}


	public static IntPtr ArithmeticError;
	public static IntPtr AssertionError;
	public static IntPtr AttributeError;
	public static IntPtr DeprecationWarning;
	public static IntPtr EOFError;
	public static IntPtr EnvironmentError;
	public static IntPtr Exception;
	public static IntPtr FloatingPointError;
	public static IntPtr IOError;
	public static IntPtr ImportError;
	public static IntPtr IndentationError;
	public static IntPtr IndexError;
	public static IntPtr KeyError;
	public static IntPtr KeyboardInterrupt;
	public static IntPtr LookupError;
	public static IntPtr MemoryError;
	public static IntPtr NameError;
	public static IntPtr NotImplementedError;
	public static IntPtr OSError;
	public static IntPtr OverflowError;
	public static IntPtr OverflowWarning;
	public static IntPtr ReferenceError;
	public static IntPtr RuntimeError;
	public static IntPtr RuntimeWarning;
	public static IntPtr StandardError;
	public static IntPtr StopIteration;
	public static IntPtr SyntaxError;
	public static IntPtr SyntaxWarning;
	public static IntPtr SystemError;
	public static IntPtr SystemExit;
	public static IntPtr TabError;
	public static IntPtr TypeError;
	public static IntPtr UnboundLocalError;
	public static IntPtr UnicodeError;
	public static IntPtr UserWarning;
	public static IntPtr ValueError;
	public static IntPtr Warning;
	public static IntPtr WindowsError;
	public static IntPtr ZeroDivisionError;

    }


}


=== Added File PythonNet/src/runtime/ExtensionType.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Base class for extensions whose instances *share* a single Python
    // type object, such as the types that represent CLR methods, fields, 
    // etc. Instances implemented by this class do not support subtyping.
    //========================================================================

    internal abstract class ExtensionType : ManagedType {

	public ExtensionType() : base() {

	    // Get the Python type pointer for this extension type. This
	    // will return a cached handle after the first call per type.

	    this.tpHandle = TypeManager.GetTypeHandle(this.GetType());

	    // Create a PyObject struct to associate this object with Python.
	    // We store a GCHandle to the CLR object in the PyObject struct  
	    // and store the PyObject * in the CLR object, which lets us find 
	    // the associated object given either the Python or CLR version.

	    PyObjectHead pyObj = new PyObjectHead();
	    this.gcHandle = GCHandle.Alloc(this);
	    pyObj.ob_data = (IntPtr)this.gcHandle;
	    pyObj.ob_refcnt = (IntPtr) 1;
	    pyObj.ob_type = tpHandle;
	    Runtime.Incref(tpHandle);

	    // Now we blit this to unmanaged memory to avoid having to pin
	    // CLR objects, which would interfere with the managed GC.

	    this.pyHandle = Runtime.PyMem_Malloc((3 * IntPtr.Size));
	    GCHandle gch = GCHandle.Alloc(pyObj, GCHandleType.Pinned);
	    Marshal.StructureToPtr(pyObj, pyHandle, false);
	    gch.Free();
	}


	[CallConvCdecl()]
	public static int tp_is_gc(IntPtr type) {
	    return 0;
	}

	[CallConvCdecl()]
	public static int tp_setattro(IntPtr ob, IntPtr key, IntPtr val) {
	    string message = "type does not support setting attributes";
	    if (val == IntPtr.Zero) {
		message = "readonly attribute";
	    }
	    Exceptions.SetError(Exceptions.TypeError, message);
	    return -1;
	}

	[CallConvCdecl()]
	public static void tp_dealloc(IntPtr ob) {
	    // Clean up a Python instance of this extension type. This 
	    // frees the allocated Python object and decrefs the type.
	    ManagedType self = GetManagedObject(ob);
	    FinalizeObject(self);
	}

	public static void FinalizeObject(ManagedType self) {
	    // Perform standard base-class level finalization.
	    Runtime.PyMem_Free(self.pyHandle);
	    Runtime.Decref(self.tpHandle);
	    self.gcHandle.Free();
	}



    }


}


=== Added File PythonNet/src/runtime/FieldObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python descriptor type that provides access to CLR fields.
    //========================================================================

    internal class FieldObject : ExtensionType {

	FieldInfo info;

	public FieldObject(FieldInfo info) : base() {
	    this.info = info;
	}

	//====================================================================
	// Descriptor __get__ implementation. This method returns the 
	// value of the field on the given object. The returned value
	// is converted to an appropriately typed Python object.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
	    FieldObject self = (FieldObject)GetManagedObject(ds);
	    Object result;

	    if (self == null) {
		return IntPtr.Zero;
	    }

	    FieldInfo info = self.info;

	    if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) {
		if (!info.IsStatic) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "instance attribute must be accessed " + 
			       "through a class instance"
			       );
		    return IntPtr.Zero;
		}
		try {
		    result = info.GetValue(null);
		    return Converter.ToPython(result, info.FieldType);
		}
		catch(Exception e) {
		    Exceptions.SetError(Exceptions.TypeError, e.Message);
		    return IntPtr.Zero;
		}
	    }

	    try {
	        CLRObject co = (CLRObject)GetManagedObject(ob);
		result = info.GetValue(co.inst);
		return Converter.ToPython(result, info.FieldType);
	    }
	    catch(Exception e) {
		Exceptions.SetError(Exceptions.TypeError, e.Message);
		return IntPtr.Zero;
	    }
	}

	//====================================================================
	// Descriptor __set__ implementation. This method sets the value of
	// a field based on the given Python value. The Python value must be
	// convertible to the type of the field.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) {
	    FieldObject self = (FieldObject)GetManagedObject(ds);
	    Object newval;

	    if (self == null) {
		return -1;
	    }

	    if (val == IntPtr.Zero) {
		Exceptions.SetError(Exceptions.TypeError, 
			            "cannot delete field"
				    );
		return -1;
	    }

	    FieldInfo info = self.info;

	    if (info.IsLiteral || info.IsInitOnly) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "field is read-only"
				    );
		return -1;
	    }

	    bool is_static = info.IsStatic;

	    if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) {
		if (!is_static) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "instance attribute must be set " + 
			       "through a class instance"
			       );
		    return -1;
		}
	    }

	    if (!Converter.ToManaged(val, info.FieldType, out newval, 
				      true)) {
		return -1;
	    }

	    try {
		if (!is_static) {
		    CLRObject co = (CLRObject)GetManagedObject(ob);
		    info.SetValue(co.inst, newval);
		}
		else {
		    info.SetValue(null, newval);
		}
		return 0;
	    }
	    catch(Exception e) {
		Exceptions.SetError(Exceptions.TypeError, e.Message);
		return -1;
	    }
	}

	//====================================================================
	// Descriptor __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    FieldObject self = (FieldObject)GetManagedObject(ob);
	    string s = String.Format("<field '{0}'>", self.info.Name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

    }


}


=== Added File PythonNet/src/runtime/ImportHook.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;

namespace Python.Runtime {

    //========================================================================
    // Implements the "import hook" used to integrate Python with the CLR.
    //========================================================================

    internal class ImportHook {

	static IntPtr py_import;
	static ModuleObject root;
	static StaticMethodWrapper hook;
	public static void Initialize() {

	    // Initialize the Python <--> CLR module hook. We replace the
	    // built-in Python __import__ with our own. This isn't ideal, 
	    // but it provides the most "Pythonic" way of dealing with CLR
	    // modules (Python doesn't provide a way to emulate packages).

	    IntPtr dict = Runtime.PyImport_GetModuleDict();
	    IntPtr mod = Runtime.PyDict_GetItemString(dict, "__builtin__");

	    py_import = Runtime.PyObject_GetAttrString(mod, "__import__");

	    // should never die
	    hook = new StaticMethodWrapper(
					      typeof(ImportHook),
					      "__import__"
					      );

	    Runtime.PyObject_SetAttrString(mod, "__import__", hook.pyHandle);
	    Runtime.Decref(hook.pyHandle);

	    root = new ModuleObject("");
	}


	[CallConvCdecl()]
	public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) {

	    // Replacement for the builtin __import__. The original import
	    // hook is saved as this.importFunc. This version handles CLR 
	    // import and defers to the normal builtin for everything else.

	    int num_args = Runtime.PyTuple_Size(args);

	    if (num_args < 1) {
		Exceptions.SetError(
			   Exceptions.TypeError, 
			   "__import__() takes at least 1 argument (0 given)"
			   );
		return IntPtr.Zero;
	    }

	    // borrowed reference
	    IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0);

	    if (!Runtime.PyString_Check(py_mod_name)) {
		Exceptions.SetError(Exceptions.TypeError, "string expected");
		return IntPtr.Zero;
	    }

	    // If not a CLR module, defer to the standard Python import.
	    // Could use Python here to avoid a string conversion.

	    string mod_name = Runtime.PyString_AsString(py_mod_name);

	    if (!(mod_name.StartsWith("CLR.") || mod_name == "CLR")) {
		return Runtime.PyObject_Call(py_import, args, kw);
	    }

	    // Check whether the import is of the form 'from x import y'.
	    // This determines whether we return the head or tail module.

	    bool from_list = false;
	    if (num_args >= 4) {
		IntPtr fromList = Runtime.PyTuple_GetItem(args, 3);
		if ((fromList != IntPtr.Zero) && 
		    (Runtime.PyObject_IsTrue(fromList) == 1)) {
		    from_list = true;
		}
	    }

	    // See if sys.modules for this interpreter already has the
	    // requested module. If so, just return the exising module.

	    IntPtr sys_modules = Runtime.PyImport_GetModuleDict();
	    IntPtr module = Runtime.PyDict_GetItem(sys_modules, py_mod_name);

	    if (module != IntPtr.Zero) {
		if (from_list) {
		    Runtime.Incref(module);
		    return module;
		}
		Runtime.Incref(root.pyHandle);
		return root.pyHandle;
	    }

	    // Special case handling: if the qualified module name would
	    // cause an implicit assembly load, we need to do that first
	    // to make sure that each of the steps in the qualified name
	    // is recognized as a valid namespace. Otherwise the import
	    // process can encounter unknown namespaces before it gets to
	    // load the assembly that would them valid.

	    if (mod_name.StartsWith("CLR.")) {
		string real_name = mod_name.Substring(4);
		AssemblyManager.LoadImplicit(real_name);
	    }

	    // Traverse the qualified module name to get the requested
	    // module and place references in sys.modules as we go.

	    string[] names = mod_name.Split('.');
	    ModuleObject tail = root;

	    for (int i = 0; i < names.Length; i++) {
		string name = names[i];
		if (name == "CLR") {
		    tail = root;
		}
		else {
		    ManagedType mt = tail.GetAttribute(name);
		    if (!(mt is ModuleObject)) {
			string error = String.Format("No module named {0}",
						     name
						     );
			Exceptions.SetError(Exceptions.ImportError, error); 
			return IntPtr.Zero;
		    }
		    tail = (ModuleObject) mt;
		}

		Runtime.PyDict_SetItemString(
			       sys_modules, tail.ModuleName, tail.pyHandle
			       );
	    }

	    ModuleObject mod = from_list ? tail : root;
	    Runtime.Incref(mod.pyHandle);
	    return mod.pyHandle;
	}

    }


}


=== Added File PythonNet/src/runtime/IndexerObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;
using System.Security.Permissions;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python descriptor type that manages CLR indexers.
    //========================================================================

    // TODO: not started yet!!

    internal class IndexerObject : ExtensionType {

	PropertyInfo info;
	MethodInfo getter;
	MethodInfo setter;

	[StrongNameIdentityPermissionAttribute(SecurityAction.Assert)]
	public IndexerObject(PropertyInfo md) : base() {
	    getter = md.GetGetMethod(true);
	    setter = md.GetSetMethod(true);
	    info = md;
	}


	//====================================================================
	// Descriptor __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    IndexerObject self = (IndexerObject)GetManagedObject(ob);
	    string s = String.Format("<indexer '{0}'>", self.info.Name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

    }


}


=== Added File PythonNet/src/runtime/InterfaceObject.cs ===
// Copyright (c) 2003 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Reflection;

namespace Python.Runtime {

    /// <summary>
    /// Provides the implementation for reflected interface types. Managed
    /// interfaces are represented in Python by actual Python type objects.
    /// Each of those type objects is associated with an instance of this
    /// class, which provides the implementation for the Python type.
    /// </summary>

    internal class InterfaceObject : ClassBase {

	internal InterfaceObject(Type tp) : base(tp) {}

	//====================================================================
	// Implements __new__ for reflected interface types.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {
	    InterfaceObject self = (InterfaceObject)GetManagedObject(tp);

	    if (Runtime.PyTuple_Size(args) != 1) {
		Exceptions.SetError(Exceptions.TypeError,
				    "interface takes exactly one argument"
				    );
		return IntPtr.Zero;
	    }

	    IntPtr inst = Runtime.PyTuple_GetItem(args, 0);
	    CLRObject co = GetManagedObject(inst) as CLRObject;
	    Type type = self.type;

	    if ((co == null) || (!type.IsInstanceOfType(co.inst))) {
		string msg = "object does not implement " + type.Name;
		Exceptions.SetError(Exceptions.TypeError, msg);
		return IntPtr.Zero;
	    }

	    Object obj = co.inst;

	    if (obj.GetType() != type) {
		// this probably isn't needed anymore...
		//obj = CastHelper.CastObject(obj, type);
	    }

	    IntPtr op = CLRObject.GetInstHandle(obj, self.pyHandle);
	    Runtime.Incref(op);
	    return op;
	}

	//====================================================================
	// Implements __init__ for reflected interface types.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw) {
	    return 0;
	}

	/*
	public override IntPtr ClassRepr() {
	    string s = String.Format("<delegate '{0}'>", this.type.FullName);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}
	*/




    }	




}


=== Added File PythonNet/src/runtime/ManagedType.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Common base class for all objects that are implemented in managed 
    // code. It defines the common fields that associate CLR and Python
    // objects and common utilities to convert between those identities.
    //========================================================================

    internal abstract class ManagedType {

	internal GCHandle gcHandle; // Native handle
	internal IntPtr pyHandle;   // PyObject *
	internal IntPtr tpHandle;   // PyType *

	public IntPtr Handle {
	    get { return pyHandle; }
	}

	public IntPtr TypeHandle {
	    get { return tpHandle; }
	}

	internal static ManagedType GetManagedObject(IntPtr ob) {

	    // Given a PyObject *, return the managed object associated with
	    // the Python object or null if the object is not managed. We do
	    // this by looking at the __mro__ of the object's type to see if
	    // the object is an instance of a reflected managed type or is a
	    // (direct, or subclass of a) reflected managed type.

	    if (ob == IntPtr.Zero) {
		return null;
	    }

	    IntPtr tp = Marshal.ReadIntPtr(ob, IntPtr.Size);
	    if (tp == Runtime.PyTypeType) {
		tp = ob;
	    }

	    // If ob->ob_type->tp_mro is null then this is not a new style
	    // class (type object), so it cannot be a CLR based object.

	    IntPtr mro = Marshal.ReadIntPtr(tp, (43 * IntPtr.Size));
	    if (mro == IntPtr.Zero) {
		return null;
	    }

	    // This gets called a lot, so this effectively inlines the std
	    // PyTuple_GET_SIZE / GET_ITEM macros to avoid making a lot of
	    // function calls across the managed / unmanaged code boundary.

	    int num = (int)Marshal.ReadIntPtr(mro, (2 * IntPtr.Size));
	    
	    for (int i = 0; i < num; i++) {
		IntPtr item = Marshal.ReadIntPtr(mro, ((3 + i) * IntPtr.Size));
		int flags = (int)Marshal.ReadIntPtr(item, (21 * IntPtr.Size));
		if ((flags & (1 << 30)) != 0) {
		    IntPtr handle = (tp == ob) ?
			Marshal.ReadIntPtr(item, (2 * IntPtr.Size)) :
			Marshal.ReadIntPtr(ob, (2 * IntPtr.Size));
		    GCHandle gch = (GCHandle)handle;
		    return (ManagedType)gch.Target;
		}
	    }

	    return null;
	}


	internal static ManagedType GetManagedObjectErr(IntPtr ob) {
	    ManagedType result = GetManagedObject(ob);
	    if (result == null) {
		Exceptions.SetError(Exceptions.TypeError, 
			   "invalid argument, expected CLR type"
			   );
	    }
	    return result;
	}


	internal static bool IsManagedType(IntPtr ob) {
	    Object result = GetManagedObject(ob);
	    return (result != null);
	}

    }

}



=== Added File PythonNet/src/runtime/MetaType.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // The managed metatype. This object implements the type of all reflected
    // types. It also provides support for single-inheritance from reflected
    // managed types.
    //========================================================================
    
    internal class MetaType : ManagedType {

	// static Type delegateType;
	static IntPtr PyCLRMetaType;
	static IntPtr stdflags;
	static ArrayList dList;
	static Hashtable cache;
	static int obSize;
	static int tpSize;

	static MetaType() {
	    obSize = Marshal.SizeOf(new PyObjectHead());
	    tpSize = Marshal.SizeOf(new PyTypeObject());
	    cache = new Hashtable();
	    dList = new ArrayList();
	    stdflags = (IntPtr) (PyTypeFlags.Default | 
				 PyTypeFlags.HeapType |
				 PyTypeFlags.Managed);
	}

	//====================================================================
	// Metatype initialization. This bootstraps the CLR metatype to life.
	//====================================================================

	public static IntPtr Initialize() {

	    Type implType = typeof(MetaType);

	    PyTypeObject pyTypeObj = new PyTypeObject();
	    pyTypeObj.tp_name = Marshal.StringToHGlobalAnsi(implType.Name);
	    pyTypeObj.ob_type = Runtime.PyTypeType;
	    pyTypeObj.tp_base = Runtime.PyTypeType;

	    int typeSize = Marshal.SizeOf(typeof(PyTypeObject));
	    pyTypeObj.tp_basicsize = (IntPtr)typeSize;
	    pyTypeObj.ob_refcnt = (IntPtr) 1;
	    pyTypeObj.tp_flags = (IntPtr) (PyTypeFlags.Default | 
					   PyTypeFlags.HeapType |
					   PyTypeFlags.Managed);

	    IntPtr pThunk = Marshal.AllocHGlobal(IntPtr.Size);
	    BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
	    Type th = typeof(CallbackThunks);
	    Type py = pyTypeObj.GetType();
	    Type tp = implType;

	    while (tp != null) {
		foreach (MethodInfo method in tp.GetMethods(flags)) {
		    string methodName = method.Name;
		    if (! methodName.StartsWith("tp_") ) {
			continue;
		    }

		    FieldInfo slot = py.GetField(methodName);
		    if (slot != null && 
			(IntPtr)slot.GetValue(pyTypeObj) == IntPtr.Zero) {

			Type dt = th.GetNestedType(methodName);
			if (dt != null) {
			    Delegate d = Delegate.CreateDelegate(dt, method);
			    CallbackThunk cb = new CallbackThunk(d);

			    Marshal.StructureToPtr(cb, pThunk, false);
			    IntPtr fp = Marshal.ReadIntPtr(pThunk);
			    slot.SetValue(pyTypeObj, fp);
			    dList.Add(d);
			}
		    }
		}
		tp = tp.BaseType;
	    }

	    Marshal.FreeHGlobal(pThunk);

	    // Now blit the PyTypeObject instance to the unmanaged heap. This
	    // bit lets us avoid pinning objects, which would disrupt the GC.

	    IntPtr typePtr = Runtime.PyMem_Malloc(tpSize);
	    GCHandle gch = GCHandle.Alloc(pyTypeObj, GCHandleType.Pinned);
	    Marshal.StructureToPtr(pyTypeObj, typePtr, false);
	    gch.Free();
	    Runtime.PyType_Ready(typePtr);


	    PyCLRMetaType = typePtr;
	    return typePtr;
	}



	//====================================================================
	// Type __setattr__ implementation for reflected types. Note that this
	// is slightly different than the standard setattr implementation for
	// the normal Python metatype (PyTypeType). We need to look first in
	// the type object of a reflected type for a descriptor in order to 
	// support the right setattr behavior for static fields and properties.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_setattro(IntPtr tp, IntPtr name, IntPtr value) {
	    IntPtr descr = Runtime._PyType_Lookup(tp, name);

	    if (descr != IntPtr.Zero) {
		IntPtr dt = Runtime.PyObject_Type(descr);
		IntPtr fp = Marshal.ReadIntPtr(dt, (35 * IntPtr.Size));
		Runtime.Decref(dt);
		if (fp != IntPtr.Zero) {
		    return NativeCall.Impl.Int_Call_3(fp, descr, name, value);
		}
		Exceptions.SetError(Exceptions.AttributeError,
				    "attribute is read-only");
		return -1;
	    }
	    
	    if (Runtime.PyObject_GenericSetAttr(tp, name, value) < 0) {
		return -1;
	    }

	    return 0;
	}


	//====================================================================
	// Metatype __new__ implementation. This is called to create a new 
	// class / type when a reflected class is subclassed. 
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {

	    // check for non-subclassable type here.

	    int len = Runtime.PyTuple_Size(args);
	    if (len < 3) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "invalid argument list"
				    );
		return IntPtr.Zero;
	    }

	    IntPtr name = Runtime.PyTuple_GetItem(args, 0);
	    IntPtr bases = Runtime.PyTuple_GetItem(args, 1);
	    IntPtr dict = Runtime.PyTuple_GetItem(args, 2);

	    // We do not support multiple inheritance, so the bases argument
	    // should be a 1-item tuple containing the type we are subtyping.
	    // That type must itself have a managed implementation. We check
	    // that by making sure its metatype is the CLR metatype.

	    if (Runtime.PyTuple_Size(bases) != 1) {
		Exceptions.SetError(Exceptions.TypeError, 
		"cannot use multiple inheritance with managed classes"
				    );
		return IntPtr.Zero;
	    }

	    IntPtr basetype = Runtime.PyTuple_GetItem(bases, 0);
	    if (Runtime.PyObject_Type(basetype) != PyCLRMetaType) {
		Exceptions.SetError(Exceptions.TypeError, 
		"metatype is not managed metatype - should not happen!"
				    );
		return IntPtr.Zero;

	    }

	    // Ensure that the reflected type is appropriate for subclassing,
	    // disallowing subclassing of delegates, enums and array types.

	    ClassBase cb = (ClassBase)GetManagedObject(basetype);
	    if (! cb.CanSubclass() ) {
		Exceptions.SetError(Exceptions.TypeError,
		"delegates, enums and array types cannot be subclassed"
				    );
		return IntPtr.Zero;
	    }


	    IntPtr slots = Runtime.PyDict_GetItemString(dict, "__slots__");
	    if (slots != IntPtr.Zero) {
		Exceptions.SetError(Exceptions.TypeError, 
		"subclasses of managed classes do not support __slots__"
				    );
		return IntPtr.Zero;

	    }

	    dict = Runtime.PyDict_Copy(dict);

	    // todo: set module

	    // todo: set doc

	    // todo: kill __new__ or error

	    // Create the subtype. Note that this does not go through the
	    // standard protocols (tp_alloc, etc.) because we allow only
	    // single inheritance and don't interoperate with other types.

	    PyTypeObject sub = new PyTypeObject();
	    string tp_name = Runtime.PyString_AsString(name);
	    sub.tp_name = Marshal.StringToHGlobalAnsi(tp_name);
	    sub.ob_type = PyCLRMetaType;
	    sub.ob_refcnt = (IntPtr) 1;
	    sub.tp_flags = stdflags;
	    sub.tp_basicsize = (IntPtr)tpSize;

	    sub.tp_base = basetype;
	    Runtime.Incref(basetype);

	    sub.tp_bases = bases;
	    Runtime.Incref(bases);

	    sub.tp_dict = dict;

	    // get/set attr copy?

	    // copy hidden obj
  	    sub.ob_size = Marshal.ReadIntPtr(basetype, 2 * IntPtr.Size);

	    IntPtr op = Runtime.PyMem_Malloc(tpSize);
	    GCHandle gc = GCHandle.Alloc(sub, GCHandleType.Pinned);
	    Marshal.StructureToPtr(sub, op, false);
	    gc.Free();

	    TypeManager.FixupOffsets(op);

	    if (Runtime.PyType_Ready(op) < 0) {
		Runtime.Decref(op);
		return IntPtr.Zero;
	    }

	    return op;
	}


	//====================================================================
	// Dealloc implementation. This is called when a subclass generated
	// by this metatype is no longer referenced in Python.
	//====================================================================

	[CallConvCdecl()]
	public static void tp_dealloc(IntPtr tp) {
	    // Free tp->tp_name, dealloc tp_dict, free type memory.
	    IntPtr op = Marshal.ReadIntPtr(tp, 3 * IntPtr.Size);
	    Marshal.FreeHGlobal(op);
	    op = Marshal.ReadIntPtr(tp, 33 * IntPtr.Size);
	    Runtime.Decref(op);
	    Runtime.PyMem_Free(tp);
	}

	/*
	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    ClassBase self = (ClassBase)GetManagedObject(ob);
	    return self.ClassRepr();
	}
	*/

    }


}


=== Added File PythonNet/src/runtime/MethodBinder.cs ===
// Copyright (c) 2003 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // A MethodBinder encapsulates information about a (possibly overloaded) 
    // managed method, and is responsible for selecting the right method given
    // a set of Python arguments. This is also used as a base class for the
    // ConstructorBinder, a minor variation used to invoke constructors.
    //========================================================================

    internal class MethodBinder {

	// MethodInfo info;
	ArrayList list;

	internal MethodBinder () {
	    // this.info = null;
	    this.list = new ArrayList();
	}
	
	internal MethodBinder(MethodInfo mi) : base () {
	    // this.info = null;
	    this.list = new ArrayList();
	    this.list.Add(mi);
	}

	internal void AddMethod(MethodBase m) {
	    // if more than one, use complex ds, else use info
	    this.list.Add(m);
	}

	internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw) {
	    // loop to find match, return invoker w/ or /wo error
	    int nargs = Runtime.PyTuple_Size(args);
	    MethodBase[] methods = (MethodBase[])list.ToArray(typeof(MethodBase));
	    
	    for (int i = 0; i < methods.Length; i++) {
		MethodBase mi = methods[i];
		ParameterInfo[] pi = mi.GetParameters();
		int count = pi.Length;

		if ( nargs == count ) {
		    Object[] margs = new Object[count];

		    for (int n = 0; n < count; n++) {
			IntPtr op = Runtime.PyTuple_GetItem(args, n);
			Type type = pi[n].ParameterType;
			Object arg;
			if (!Converter.ToManaged(op, type, out arg, false)) {
			    margs = null;
			    break;
			}
			margs[n] = arg;
		    }
		    
		    if (margs == null) {
			continue;
		    }

		    Object target = null;
		    if ((!mi.IsStatic) && (inst != IntPtr.Zero)) {
			CLRObject co = (CLRObject)ManagedType.GetManagedObject(
                                                  inst
						  );
			target = co.inst;
		    }

		    return new Binding(mi, target, margs);
		}

	    }

	    return null;
	}

	internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {
	    Binding binding = this.Bind(inst, args, kw);
	    Object result;

	    if (binding == null) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "no method matches given arguments"
				    );
		return IntPtr.Zero;
	    }

	    try {
		result = binding.info.Invoke(binding.inst, 
					     BindingFlags.Default, 
					     null, 
					     binding.args, 
					     null);
	    }
	    catch (Exception e) {
		if (e.InnerException != null) {
		    e = e.InnerException;
		}
		Exceptions.SetError(e);
		return IntPtr.Zero;
	    }

	    MethodInfo mi = (MethodInfo)binding.info;
	    return Converter.ToPython(result, mi.ReturnType);
	}

    }


    //========================================================================
    // A Binding is a utility instance that bundles together a MethodInfo
    // representing a method to call, a (possibly null) target instance for
    // the call, and the arguments for the call (all as managed values).
    //========================================================================

    internal class Binding {

	public MethodBase info;
	public Object[] args;
	public Object inst;

	internal Binding(MethodBase info, Object inst, Object[] args) {
	    this.info = info;
	    this.inst = inst;
	    this.args = args;
	}

    }

}


=== Added File PythonNet/src/runtime/MethodBinding.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python binding type for CLR methods. These work much like
    // standard Python method bindings, but the same type is used to bind
    // both static and instance methods.
    //========================================================================

    internal class MethodBinding : ExtensionType {

	MethodObject m;
	IntPtr target;

	public MethodBinding(MethodObject m, IntPtr target) : base() {
	    Runtime.Incref(target);
	    this.target = target;
	    this.m = m;
	}

	//====================================================================
	// MethodBinding  __call__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) {
	    MethodBinding self = (MethodBinding)GetManagedObject(ob);
	    return self.m.Invoke(self.target, args, kw);
	}

	//====================================================================
	// MethodBinding  __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    MethodBinding self = (MethodBinding)GetManagedObject(ob);
	    string type = (self.target == IntPtr.Zero) ? "unbound" : "bound";
	    string s = String.Format("<{0} method '{1}'>", type, self.m.name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

	//====================================================================
	// MethodBinding dealloc implementation.
	//====================================================================

	[CallConvCdecl()]
	public static new void tp_dealloc(IntPtr ob) {
	    MethodBinding self = (MethodBinding)GetManagedObject(ob);
	    Runtime.Decref(self.target);
	    ExtensionType.FinalizeObject(self);
	}

    }


}


=== Added File PythonNet/src/runtime/MethodObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python type that provides access to CLR object methods.
    //========================================================================

    internal class MethodObject : ExtensionType {

	internal MethodInfo[] info;
	internal string name;
	MethodBinding unbound;
	MethodBinder binder;

	public MethodObject(string name, MethodInfo[] info) : base() {
	    this.name = name;
	    this.info = info;
	    binder = new MethodBinder();
	    for (int i = 0; i < info.Length; i++) {
		binder.AddMethod((MethodInfo)info[i]);
	    }
	}

	public virtual IntPtr Invoke(IntPtr target, IntPtr args, IntPtr kw) {
	    // TODO: should probably release GIL around the method call
	    return binder.Invoke(target, args, kw);
	}

	//====================================================================
	// Descriptor __get__ implementation. Accessing a CLR method returns
	// a "bound" method similar to a Python bound method. 
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
	    MethodObject self = (MethodObject)GetManagedObject(ds);
	    MethodBinding binding;

	    // If the method is accessed through its type (rather than via
	    // an instance) we return an 'unbound' MethodBinding that will
	    // cached for future accesses through the type.

	    if (ob == IntPtr.Zero) {
		if (self.unbound == null) {
		    self.unbound = new MethodBinding(self, IntPtr.Zero);
		}
		binding = self.unbound;
		Runtime.Incref(binding.Handle);;
		return binding.Handle;
	    }

	    if (Runtime.PyObject_IsInstance(ob, tp) != 1) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "invalid descriptor argument"
				    );
		return IntPtr.Zero;
	    }

	    binding = new MethodBinding(self, ob);
	    return binding.Handle;
	}

	//====================================================================
	// Descriptor __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    MethodObject self = (MethodObject)GetManagedObject(ob);
	    string s = String.Format("<method '{0}'>", self.name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

	//====================================================================
	// Descriptor dealloc implementation.
	//====================================================================

	[CallConvCdecl()]
	public static new void tp_dealloc(IntPtr ob) {
	    MethodObject self = (MethodObject)GetManagedObject(ob);
	    if (self.unbound != null) {
		Runtime.Decref(self.unbound.Handle);
	    }
	    ExtensionType.FinalizeObject(self);
	}


    }


}


=== Added File PythonNet/src/runtime/MethodWrapper.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace Python.Runtime {

    /// <summary>
    /// A StaticMethodWrapper wraps a static method of a managed type,
    /// making it callable by Python as a PyCFunction object. This is
    /// currently used mainly to implement special cases like the CLR
    /// import hook.
    /// </summary>

    internal class StaticMethodWrapper {

	public Delegate mDelegate;
	public IntPtr methodDef;
	public IntPtr pyHandle;

	private static ArrayList keepAlive;

	static StaticMethodWrapper() {
	    keepAlive = new ArrayList();
	}

	public StaticMethodWrapper(Type obType, string name) {

	    // Allocate and initialize a PyMethodDef structure to represent 
	    // the managed method, then create a PyCFunction. 

	    // Currently, these are never released. need to think harder.

	    mDelegate = Delegate.CreateDelegate(
				 typeof(Prototypes.TernaryFunc), 
				 //CallbackThunks.generic),
				 obType.GetMethod(name)
				 );
	    CallbackThunk cb = new CallbackThunk(mDelegate);
	    IntPtr pThunk = Marshal.AllocHGlobal(IntPtr.Size);
	    Marshal.StructureToPtr(cb, pThunk, false);
	    IntPtr fp = Marshal.ReadIntPtr(pThunk);
	    Marshal.FreeHGlobal(pThunk);

	    methodDef = Runtime.PyMem_Malloc(4 * IntPtr.Size);
	    Marshal.WriteIntPtr(methodDef, Marshal.StringToHGlobalAnsi(name));
	    Marshal.WriteIntPtr(methodDef, (1 * IntPtr.Size), fp);
	    Marshal.WriteIntPtr(methodDef, (2 * IntPtr.Size), (IntPtr)0x0002);
	    Marshal.WriteIntPtr(methodDef, (3 * IntPtr.Size), IntPtr.Zero);
	    pyHandle = Runtime.PyCFunction_New(methodDef, IntPtr.Zero);

	    keepAlive.Add(this);
	}

	public IntPtr Handle {
	    get { return pyHandle; }
	}

	public IntPtr Call(IntPtr args, IntPtr kw) {
	    return Runtime.PyCFunction_Call(pyHandle, args, kw);
	}

    }


}



=== Added File PythonNet/src/runtime/ModuleObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections.Specialized;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    // TODO: decide whether to support __all__ and / or whether to impl
    // a 'preload' method to force names to be pre-loaded.

    //========================================================================
    // Implements a Python type that provides access to CLR namespaces. The 
    // type behaves like a Python module, and can contain other sub-modules.
    //========================================================================

    internal class ModuleObject : ExtensionType {

	string moduleName;
	string _namespace;
	Hashtable cache;
	IntPtr dict;

	public ModuleObject(string name) : base() {

	    moduleName = (name == String.Empty) ? "CLR" : "CLR." + name;
	    cache = new Hashtable();
	    _namespace = name;

	    dict = Runtime.PyDict_New();
	    IntPtr pyname = Runtime.PyString_FromString(moduleName);
	    Runtime.PyDict_SetItemString(dict, "__name__", pyname);
	    Runtime.PyDict_SetItemString(dict, "__doc__", Runtime.PyNone);
	    Runtime.Decref(pyname);
	}

	public string ModuleName {
	    get { 
		return moduleName; 
	    }
	}

	//===================================================================
	// Returns a ClassBase object representing a type that appears in
	// this module's namespace or a ModuleObject representing a child 
	// namespace (or null if the name is not found). This method does
	// not increment the Python refcount of the returned object.
	//===================================================================

	public ManagedType GetAttribute(string name) {
	    Object ob = this.cache[name];
	    if (ob != null) {
		return (ManagedType) ob;
	    }

	    string qname = (_namespace == String.Empty) ? name : 
		            _namespace + "." + name;

	    ModuleObject m;
	    ClassBase c;

	    // If the fully-qualified name of the requested attribute is 
	    // a namespace exported by a currently loaded assembly, return 
	    // a new ModuleObject representing that namespace.

	    if (AssemblyManager.IsValidNamespace(qname)) {
		m = new ModuleObject(qname);
		StoreAttribute(name, m);
		return (ManagedType) m;
	    }

	    // Look for a type in the current namespace. Note that this 
	    // includes types, delegates, enums, interfaces and structs.
	    // Only public namespace members are exposed to Python.

	    Type type = AssemblyManager.LookupType(qname);
	    if (type != null) {
		if (!type.IsPublic) {
		    return null;
		}
		c = ClassManager.GetClass(type);
		StoreAttribute(name, c);
		return (ManagedType) c;
	    }

	    // This is a little repetitive, but it ensures that the right
	    // thing happens with implicit assembly loading at a reasonable
	    // cost. Ask the AssemblyManager to do implicit loading for each 
	    // of the steps in the qualified name, then try it again.

	    if (AssemblyManager.LoadImplicit(qname)) {
		if (AssemblyManager.IsValidNamespace(qname)) {
		    m = new ModuleObject(qname);
		    StoreAttribute(name, m);
		    return (ManagedType) m;
		}

		type = AssemblyManager.LookupType(qname);
		if (type != null) {
		    if (!type.IsPublic) {
			return null;
		    }
		    c = ClassManager.GetClass(type);
		    StoreAttribute(name, c);
		    return (ManagedType) c;
		}
	    }

	    return null;
	}

	//===================================================================
	// Stores an attribute in the instance dict for future lookups.
 	//===================================================================

	private void StoreAttribute(string name, ManagedType ob) {
	    Runtime.PyDict_SetItemString(dict, name, ob.Handle);
	    cache[name] = ob;
	}




	[PythonMethod]
	public static IntPtr _preload(IntPtr ob, IntPtr args, IntPtr kw) {

	    ModuleObject self = (ModuleObject)GetManagedObject(ob);


	    string module_ns = self._namespace;


	    AppDomain domain = AppDomain.CurrentDomain;
	    Assembly[] assemblies = domain.GetAssemblies();
	    for (int i = 0; i < assemblies.Length; i++) {
		Assembly assembly = assemblies[i];
		Type[] types = assembly.GetTypes();
		for (int n = 0; n < types.Length; n++) {
		    Type type = types[n];

		    string ns = type.Namespace;
		    if ((ns != null) && (ns == module_ns)) {
			if (type.IsPublic) {
			    ClassBase c = ClassManager.GetClass(type);
			    self.StoreAttribute(type.Name, c);
			}
		    }
		}
	    }
	    Runtime.Incref(Runtime.PyNone);
	    return Runtime.PyNone;
	}



	//====================================================================
	// ModuleObject __getattribute__ implementation. Module attributes
	// are always either classes or sub-modules representing subordinate 
	// namespaces. CLR modules implement a lazy pattern - the sub-modules
	// and classes are created when accessed and cached for future use.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_getattro(IntPtr ob, IntPtr key) {
	    ModuleObject self = (ModuleObject)GetManagedObject(ob);

	    if (!Runtime.PyString_Check(key)) {
		Exceptions.SetError(Exceptions.TypeError, "string expected");
		return IntPtr.Zero;
	    }

	    IntPtr op = Runtime.PyDict_GetItem(self.dict, key);
	    if (op != IntPtr.Zero) {
		Runtime.Incref(op);
		return op;
	    }
 
	    string name = Runtime.PyString_AsString(key);
	    if (name == "__dict__") {
		return Runtime.PyDictProxy_New(self.dict);
	    }

	    ManagedType attr = self.GetAttribute(name);

	    if (attr != null) {
		Runtime.Incref(attr.Handle);
		return attr.Handle;
	    }

	    Exceptions.SetError(Exceptions.AttributeError, name);
	    return IntPtr.Zero;
	}

	//====================================================================
	// ModuleObject __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    ModuleObject self = (ModuleObject)GetManagedObject(ob);
	    string s = String.Format("<module '{0}' (clr)>", self.moduleName);
	    return Runtime.PyString_FromString(s);
	}

    }


}


=== Added File PythonNet/src/runtime/NativeCall.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

namespace Python.Runtime {

    /// <summary>
    /// Provides support for calling native code indirectly through 
    /// function pointers. Most of the important parts of the Python
    /// C API can just be wrapped with p/invoke, but there are some
    /// situations (specifically, calling functions through Python
    /// type structures) where we need to call functions indirectly.
    ///
    /// This class uses Reflection.Emit to generate IJW thunks that
    /// support indirect calls to native code using various common
    /// call signatures. This is mainly a workaround for the fact 
    /// that you can't spell an indirect call in C# (but can in IL).
    ///
    /// Another approach that would work is for this to be turned 
    /// into a separate utility program that could be run during the
    /// build process to generate the thunks as a separate assembly 
    /// that could then be referenced by the main Python runtime.
    /// </summary>

    internal class NativeCall {

	static AssemblyBuilder aBuilder;
	static ModuleBuilder mBuilder;

	public static INativeCall Impl;

	static NativeCall() {

	    // The static constructor is responsible for generating the
	    // assembly and the methods that implement the IJW thunks.
	    //
	    // To do this, we actually use reflection on the INativeCall
	    // interface (defined below) and generate the required thunk 
	    // code based on the method signatures.

	    AssemblyName aname = new AssemblyName();
	    aname.Name = "e__NativeCall_Assembly";
	    AssemblyBuilderAccess aa = AssemblyBuilderAccess.Run;

	    aBuilder = Thread.GetDomain().DefineDynamicAssembly(aname, aa);
	    mBuilder = aBuilder.DefineDynamicModule("e__NativeCall_Module");

	    TypeAttributes ta = TypeAttributes.Public;
	    TypeBuilder tBuilder = mBuilder.DefineType("e__NativeCall", ta);

	    Type iType = typeof(INativeCall);
	    tBuilder.AddInterfaceImplementation(iType);

	    // Use reflection to loop over the INativeCall interface methods, 
	    // calling GenerateThunk to create a managed thunk for each one.

	    foreach (MethodInfo method in iType.GetMethods()) {
		GenerateThunk(tBuilder, method);
	    }
	    
	    Type theType = tBuilder.CreateType();

	    Impl = (INativeCall)Activator.CreateInstance(theType);

	}

	private static void GenerateThunk(TypeBuilder tb, MethodInfo method) {

	    ParameterInfo[] pi = method.GetParameters();
	    int count = pi.Length;
	    int argc = count - 1;

	    Type[] args = new Type[count];
	    for (int i = 0; i < count; i++) {
		args[i] = pi[i].ParameterType;
	    }

	    MethodBuilder mb = tb.DefineMethod(
				  method.Name,
				  MethodAttributes.Public | 
				  MethodAttributes.Virtual,
				  method.ReturnType,
				  args
				  );

	    // Build the method signature for the actual native function.
	    // This is essentially the signature of the wrapper method
	    // minus the first argument (the passed in function pointer).

	    Type[] nargs = new Type[argc];
	    for (int i = 1; i < count; i++) {
		nargs[(i - 1)] = args[i];
	    }

	    // IL generation: the (implicit) first argument of the method 
	    // is the 'this' pointer and the second is the function pointer.
	    // This code pushes the real args onto the stack, followed by
	    // the function pointer, then the calli opcode to make the call.

	    ILGenerator il = mb.GetILGenerator();

	    for (int i = 0; i < argc; i++) {
		il.Emit(OpCodes.Ldarg_S, (i + 2));
	    }

	    il.Emit(OpCodes.Ldarg_1);

	    il.EmitCalli(OpCodes.Calli, 
			 CallingConvention.Cdecl, 
			 method.ReturnType, 
			 nargs
			 );

	    il.Emit(OpCodes.Ret);

	    tb.DefineMethodOverride(mb, method);
	    return;
	}


	public static void Void_Call_1(IntPtr fp, IntPtr a1) {
	    Impl.Void_Call_1(fp, a1);
	}

    }


    /// <summary>
    /// Defines native call signatures to be generated by NativeCall.
    /// </summary>

    public interface INativeCall {

	void Void_Call_0(IntPtr funcPtr);

	void Void_Call_1(IntPtr funcPtr, IntPtr arg1);

	int Int_Call_3(IntPtr funcPtr, IntPtr t, IntPtr n, IntPtr v);

	IntPtr Call_3(IntPtr funcPtr, IntPtr a1, IntPtr a2, IntPtr a3);

    }

}


=== Added File PythonNet/src/runtime/PropertyObject.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;
using System.Security.Permissions;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python descriptor type that manages CLR properties.
    //========================================================================

    internal class PropertyObject : ExtensionType {

	PropertyInfo info;
	MethodInfo getter;
	MethodInfo setter;

	[StrongNameIdentityPermissionAttribute(SecurityAction.Assert)]
	public PropertyObject(PropertyInfo md) : base() {
	    getter = md.GetGetMethod(true);
	    setter = md.GetSetMethod(true);
	    info = md;
	}

	//====================================================================
	// Descriptor __get__ implementation. This method returns the 
	// value of the property on the given object. The returned value
	// is converted to an appropriately typed Python object.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
	    PropertyObject self = (PropertyObject)GetManagedObject(ds);
	    MethodInfo getter = self.getter;
	    Object result;

	    if (getter == null) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "property cannot be read"
				    );
		return IntPtr.Zero;
	    }

	    if (getter.IsAbstract) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "cannot use abstract property"
				    );
		return IntPtr.Zero;
	    }

	    if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) {
		if (!(getter.IsStatic)) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "instance property must be accessed through " + 
			       "a class instance"
			       );
		    return IntPtr.Zero;
		}
		try {
		    result = self.info.GetValue(null, null);
		    return Converter.ToPython(result, self.info.PropertyType);
		}
		catch(Exception e) {
		    Exceptions.SetError(Exceptions.TypeError, e.Message);
		    return IntPtr.Zero;
		}
	    }

	    try {
	        CLRObject co = (CLRObject)GetManagedObject(ob);
		result = self.info.GetValue(co.inst, null);
		return Converter.ToPython(result, self.info.PropertyType);
	    }
	    catch(Exception e) {
		Exceptions.SetError(Exceptions.TypeError, e.Message);
		return IntPtr.Zero;
	    }
	}

	//====================================================================
	// Descriptor __set__ implementation. This method sets the value of
	// a property based on the given Python value. The Python value must 
	// be convertible to the type of the property.
	//====================================================================

	[CallConvCdecl()]
	public static int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) {
	    PropertyObject self = (PropertyObject)GetManagedObject(ds);
	    MethodInfo setter = self.setter;
	    Object newval;

	    if (val == IntPtr.Zero) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "cannot delete property"
				    );
		return -1;
	    }

	    if (setter == null) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "property is read-only"
				    );
		return -1;
	    }

	    if (setter.IsAbstract) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "cannot set abstract property"
				    );
		return -1;
	    }

	    if (!Converter.ToManaged(val, self.info.PropertyType, out newval, 
				      true)) {
		return -1;
	    }

	    bool is_static = setter.IsStatic;

	    if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) {
		if (!(is_static)) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "instance property must be set on an instance"
			       );
		    return -1;
		}
	    }

	    try {
		if (!is_static) {
		    CLRObject co = (CLRObject)GetManagedObject(ob);
		    self.info.SetValue(co.inst, newval, null);
		}
		else {
		    self.info.SetValue(null, newval, null);		    
		}
		return 0;
	    }
	    catch(Exception e) {
		Exceptions.SetError(Exceptions.TypeError, e.Message);
		return -1;
	    }

	}


	// mp_subscript should handle index params.

	//====================================================================
	// Descriptor __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    PropertyObject self = (PropertyObject)GetManagedObject(ob);
	    string s = String.Format("<property '{0}'>", self.info.Name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

    }


}


=== Added File PythonNet/src/runtime/PythonException.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;

namespace Python.Runtime {

    /// <summary>
    /// Provides an interface to exceptions thrown by the Python runtime.
    ///
    /// Managed wrappers for the Python APIs will propagate exceptions
    /// thrown in the Python runtime by throwing a PythonException that
    /// wraps and provides access to the Python exception information.
    /// </summary>

    public class PythonException : System.Exception {

	private IntPtr excType = IntPtr.Zero;
	private IntPtr excValue = IntPtr.Zero;
	private IntPtr excTb = IntPtr.Zero;

	public PythonException() : base() {
	    // According to the SDK docs, because IntPtr is blittable the
	    // interop marshaller will pin automatically for byref calls.
	    Runtime.PyErr_Fetch(ref excType, ref excValue, ref excTb);
	}

	/// <summary>
	/// Traceback Property
	/// </summary>
	///
	/// <remarks>
	/// Returns the message associated with the exception.
	/// </remarks>

	string _message;

	public override string Message {
	    get {
		if (_message != null) {
		    return _message;
		}
		IntPtr ob = Runtime.PyObject_Str(excValue);
		_message = Runtime.PyString_AsString(ob);
		return _message;
	    }
	}

	/// <summary>
	/// Type Property
	/// </summary>
	///
	/// <remarks>
	/// Returns the exception type as a Python object.
	/// </remarks>

	public IntPtr Type {
	    get {
		return IntPtr.Zero;
	    }
	}

	/// <summary>
	/// Value Property
	/// </summary>
	///
	/// <remarks>
	/// Returns the exception value as a Python object.
	/// </remarks>

	public IntPtr Value {
	    get {
		return IntPtr.Zero;
	    }
	}

	/// <summary>
	/// Traceback Property
	/// </summary>
	///
	/// <remarks>
	/// Returns the exception traceback as a Python object.
	/// </remarks>

	public IntPtr Traceback {
	    get {
		return IntPtr.Zero;
	    }
	}

	/// <summary>
	/// Dispose Method
	/// </summary>
	///
	/// <remarks>
	/// The Dispose method provides a way to explicitly release the 
	/// Python objects associated with the current Python exception.
	/// The PythonException cannot be used after calling Dispose().
	/// </remarks>

	public void Dispose() {
	    GC.SuppressFinalize(this);
	    Runtime.Decref(excType);
	    Runtime.Decref(excValue);
	    Runtime.Decref(excTb);
	}

	/// <summary>
	/// Finalize Method
	/// </summary>
	///
	/// <remarks>
	/// Ensures that a PythonException releases the Python objects
	/// associated with an exception when it is garbage-collected.
	/// </remarks>

	public void Finalize() {
	    Dispose();
	}

	/// <summary>
	/// Matches Method
	/// </summary>
	///
	/// <remarks>
	/// Returns true if the Python exception type represented by the 
	/// PythonException instance matches the given exception type.
	/// </remarks>

	public static bool Matches(IntPtr ob) {
	    return Runtime.PyErr_ExceptionMatches(ob) != 0;
	}

    } 


}


=== Added File PythonNet/src/runtime/PythonInterpreter.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Threading;
using System.Collections;

namespace Python.Runtime {


    public class PythonInterpreter {

	private static Hashtable threads;
	public static bool initialized;

	public static void Initialize() {
	    if (!initialized) {
		Runtime.Initialize();

		threads = new Hashtable();
		IntPtr ts = Runtime.PyThreadState_Get();
		threads[Thread.CurrentThread] = ts;

		initialized = true;
	    }
	}

	public static void Finalize() {
	    if (initialized) {
		Runtime.Py_Finalize();
		initialized = false;
	    }
	}


	// NOTE: all of the thread state stuff is just notes to myself
	// at the moment... Implementing async delegates will help to 
	// sort it out.

	//====================================================================
	// Register the calling thread with the interpreter.
	//====================================================================

	public static void RegisterThread() {
	    IntPtr ts = Runtime.PyThreadState_Get();
	    Thread t = Thread.CurrentThread;
	    threads[t] = ts;
	}

	
	//====================================================================
	// Finalize a thread finished with the interpreter.
	//====================================================================

	public static void FinalizeThread() {
	    /*
	    IntPtr threadState = (IntPtr)threads[Thread.CurrentThread];
	    if (threadState == null) {
		// ???
	    }
	    Runtime.PyEval_AcquireLock();
	    Runtime.PyThreadState_Swap(IntPtr.Zero);
	    Runtime.PyThreadState_Clear(threadState);
	    Runtime.PyThreadState_Delete(threadState);
	    // remove it!
	    Runtime.PyEval_ReleaseLock();
	    */
	}


	//====================================================================
	// Acquire the Python global interpreter lock.
	//====================================================================

	public static void AcquireLock() {
	    Object o = threads[Thread.CurrentThread];
	    if (o != null) {
		return;
	    }
	    Runtime.PyEval_AcquireLock();
	    
	}



	//====================================================================
	// Interpreter properties
	//====================================================================

	public static bool IsInitialized {
	    get {
		return initialized;
	    }
	}

	public static string ProgramName {
	    get {
		string result = Runtime.Py_GetProgramName();
		if (result == null) {
		    return "";
		}
		return result;
	    }
	    set {
		Runtime.Py_SetProgramName(value);
	    }
	}

	public static string PythonHome {
	    get {
		string result = Runtime.Py_GetPythonHome();
		if (result == null) {
		    return "";
		}
		return result;
	    }
	    set {
		Runtime.Py_SetPythonHome(value);
	    }
	}

	public static string Version {
	    get { 
		return Runtime.Py_GetVersion(); 
	    }
	}

	public static string BuildInfo {
	    get { 
		return Runtime.Py_GetBuildInfo(); 
	    }
	}

	public static string Platform {
	    get { 
		return Runtime.Py_GetPlatform(); 
	    }
	}

	public static string Copyright {
	    get { 
		return Runtime.Py_GetCopyright(); 
	    }
	}





	public static int RunSimpleString(string code) {
	    return Runtime.PyRun_SimpleString(code);
	}

//  	public static PyModule ImportModule(string name) {
//  	    PyString moduleName = new PyString(name);
//  	    IntPtr pointer = Runtime.PyImport_Import(moduleName.Handle);
//  	    return new PyModule(pointer);
//  	}

//  	public static PyModule ReloadModule(PyModule module) {
//  	    IntPtr pointer = Runtime.PyImport_ReloadModule(module.Handle);
//  	    return new PyModule(pointer);
//  	}

//  	public static PyModule AddModule(string name) {
//  	    IntPtr result = Runtime.PyImport_AddModule(name);
//  	    if (result == IntPtr.Zero) {
//  		throw new PythonException();
//  	    }
//  	    Runtime.Incref(result);
//  	    return new PyModule(result);
//  	}

    }


}


=== Added File PythonNet/src/runtime/Runtime.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Security;

namespace Python.Runtime {

    [SuppressUnmanagedCodeSecurityAttribute()]

    public class Runtime {

	/// <summary>
	/// Encapsulates the low-level Python C API.
	/// </summary>

	private static IntPtr MainThreadState;

	internal static void Initialize() {

	    Runtime.Py_Initialize();
	    Runtime.PyEval_InitThreads();

	    // Store a reference to the main threadstate.
	    MainThreadState = PyThreadState_Get();


	    IntPtr dict = Runtime.PyImport_GetModuleDict();
	    IntPtr op = Runtime.PyDict_GetItemString(dict, "__builtin__");

	    PyModuleType = Runtime.PyObject_Type(op);
	    PyNone = Runtime.PyObject_GetAttrString(op, "None");
	    PyNoneType = Runtime.PyObject_Type(PyNone);
	    PyTypeType = Runtime.PyObject_Type(PyNoneType);

	    op = Runtime.PyString_FromString("string");
	    PyStringType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyUnicode_FromString("unicode");
	    PyUnicodeType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyTuple_New(0);
	    PyTupleType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyList_New(0);
	    PyListType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyDict_New();
	    PyDictType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyInt_FromLong(0);
	    PyIntType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyLong_FromLong(0);
	    PyLongType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    op = Runtime.PyFloat_FromDouble(0);
	    PyFloatType = Runtime.PyObject_Type(op);
	    Runtime.Decref(op);

	    IntPtr s = Runtime.PyString_FromString("__temp");
	    IntPtr t = Runtime.PyTuple_New(0);
	    IntPtr d = Runtime.PyDict_New();
	    IntPtr c = Runtime.PyClass_New(t, d, s);

	    PyClassType = Runtime.PyObject_Type(c);
	    IntPtr i = Runtime.PyInstance_New(c, t, d);
	    PyInstanceType = Runtime.PyObject_Type(i);

	    Runtime.Decref(s);
	    Runtime.Decref(t);
	    Runtime.Decref(d);
	    Runtime.Decref(i);
	    Runtime.Decref(c);

	    Error = new IntPtr(-1);

	    PyCLRMetaType = MetaType.Initialize();
	    Exceptions.Initialize();
	    ImportHook.Initialize();


	    // TODO: get rid of this! This works around the gc crash
	    // until I have time to dig into it.

	    IntPtr nm = Runtime.PyString_FromString("gc");
	    IntPtr md = Runtime.PyImport_Import(nm);
	    IntPtr fn = Runtime.PyObject_GetAttrString(md, "disable");
	    IntPtr aa = Runtime.PyTuple_New(0);
	    IntPtr rr = Runtime.PyObject_Call(fn, aa, IntPtr.Zero);
	    Runtime.Decref(rr);
	    Runtime.Decref(aa);
	    Runtime.Decref(fn);
	    Runtime.Decref(nm);
	    Runtime.Decref(md);
	}

	internal unsafe static void Incref(IntPtr op) {
	    if (op == IntPtr.Zero) 
		return;
	    (*(int *)op)++;
	}

	private static void LogDecref(IntPtr op) {
	    IntPtr tp = Runtime.PyObject_Type(op);
	    IntPtr fp = Marshal.ReadIntPtr(tp, (6 * IntPtr.Size));
	    if (fp == IntPtr.Zero) {
		return;
	    }

	    IntPtr refs = Marshal.ReadIntPtr(op);

	    IntPtr p1 = Runtime.PyObject_Repr(tp);
	    string s1 = Runtime.PyString_AsString(p1);
	    
	    IntPtr p2 = Runtime.PyObject_Repr(op);
	    string s2 = Runtime.PyString_AsString(p2);

	    Console.WriteLine("decref: {0} {1} {2} {3} {4}", 
			      s1, refs, s2, fp, op
			      );
	}

	internal unsafe static void Decref(IntPtr op) {

	    if (op == IntPtr.Zero) {
		return;
	    }

	    if (--(*(int *)op) == 0) {

		// fp = op -> ob_type -> tp_dealloc
		IntPtr tp = Runtime.PyObject_Type(op);
		IntPtr fp = Marshal.ReadIntPtr(tp, (6 * IntPtr.Size));
		if (fp == IntPtr.Zero) {
		    return;
		}
		//LogDecref(op);
		try {
		    // Fix this - figure out native call / malloc bug.
		    // NativeCall.Impl.Void_Call_1(fp, op);
		} catch {
		    IntPtr ss = Runtime.PyObject_Str(op);
		    string ds = Runtime.PyString_AsString(ss);
		    Console.WriteLine("native call failed!");
		}

		return;
	    }

	}

	internal unsafe static int GetRefCount(IntPtr op) {
	    if (op == IntPtr.Zero) 
		return 0;
	    return *(int *)op;
	}

	// Utility to return the name of an object's type as a string.

	internal static string PyObject_GetTypeName(IntPtr op) {
	    IntPtr pyType = Marshal.ReadIntPtr(op, IntPtr.Size);
	    IntPtr ppName = Marshal.ReadIntPtr(pyType, (3 * IntPtr.Size));
	    return Marshal.PtrToStringAnsi(ppName);
	}





	internal static IntPtr PyModuleType;
	internal static IntPtr PyClassType;
	internal static IntPtr PyInstanceType;
	internal static IntPtr PyCLRMetaType;

	internal static IntPtr PyUnicodeType;
	internal static IntPtr PyStringType;
	internal static IntPtr PyTupleType;
	internal static IntPtr PyListType;	
	internal static IntPtr PyDictType;	
	internal static IntPtr PyIntType;
	internal static IntPtr PyLongType;
	internal static IntPtr PyFloatType;
	internal static IntPtr PyNoneType;
	internal static IntPtr PyTypeType;

	internal static IntPtr PyNone;
	internal static IntPtr Error;


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	Py_Initialize();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	Py_Finalize();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	Py_NewInterpreter();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
	Py_EndInterpreter(IntPtr threadState);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyThreadState_Get();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	public unsafe static extern int
	Py_Main(int argc, string[] argv);


	// Thread state operations

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyEval_InitThreads();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyEval_AcquireLock();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyEval_ReleaseLock();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyEval_AcquireThread(IntPtr tstate);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyEval_ReleaseThread(IntPtr tstate);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyEval_SaveThread();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyEval_RestoreThread(IntPtr tstate);


	// Miscellaneous high-level runtime APIs

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetProgramName();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
        Py_SetProgramName(string name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetPythonHome();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
        Py_SetPythonHome(string home);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetVersion();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetPlatform();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetCopyright();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetCompiler();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern string
        Py_GetBuildInfo();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyRun_SimpleString(string code);


	// Python abstract object API

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern IntPtr
        PyObject_Type(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyObject_HasAttrString(IntPtr pointer, string name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern IntPtr
        PyObject_GetAttrString(IntPtr pointer, string name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyObject_SetAttrString(IntPtr pointer, string name, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyObject_HasAttr(IntPtr pointer, IntPtr name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern IntPtr
        PyObject_GetAttr(IntPtr pointer, IntPtr name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyObject_SetAttr(IntPtr pointer, IntPtr name, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern IntPtr
        PyObject_GetItem(IntPtr pointer, IntPtr key);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyObject_SetItem(IntPtr pointer, IntPtr key, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern int
        PyObject_DelItem(IntPtr pointer, IntPtr key);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern IntPtr
        PyObject_Call(IntPtr pointer, IntPtr args, IntPtr kw);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyObject_CallObject(IntPtr pointer, IntPtr args);

	

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyObject_Compare(IntPtr value1, IntPtr value2);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyObject_IsInstance(IntPtr ob, IntPtr type);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyObject_IsSubclass(IntPtr ob, IntPtr type);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyCallable_Check(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyObject_IsTrue(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyObject_Size(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyObject_Hash(IntPtr op);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyObject_Repr(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyObject_Str(IntPtr pointer);


	// Python numeric methods

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyNumber_Int(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyNumber_Long(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyNumber_Float(IntPtr ob);



	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyInt_FromLong(int value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyInt_AsLong(IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyInt_FromString(string value, IntPtr end, int radix);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyInt_GetMax();


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyLong_FromLong(long value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyLong_FromUnsignedLong(uint value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyLong_FromDouble(double value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyLong_FromLongLong(long value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyLong_FromUnsignedLongLong(ulong value);


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyLong_FromString(string value, IntPtr end, int radix);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyLong_AsLong(IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern uint
	PyLong_AsUnsignedLong(IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern long
	PyLong_AsLongLong(IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern ulong
	PyLong_AsUnsignedLongLong(IntPtr value);



	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyFloat_FromDouble(double value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyFloat_FromString(IntPtr value, IntPtr junk);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern double
	PyFloat_AsDouble(IntPtr ob);







	// Python abstract sequence API

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_Check(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PySequence_GetItem(IntPtr pointer, int index);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_SetItem(IntPtr pointer, int index, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_DelItem(IntPtr pointer, int index);


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_Size(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_Contains(IntPtr pointer, IntPtr item);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PySequence_Concat(IntPtr pointer, IntPtr other);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PySequence_Repeat(IntPtr pointer, int count);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_Index(IntPtr pointer, IntPtr item);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySequence_Count(IntPtr pointer, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PySequence_Tuple(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PySequence_List(IntPtr pointer);



	// Python string methods

	internal static bool IsStringType(IntPtr op) {
	    IntPtr t = PyObject_Type(op);
	    return (t == PyStringType) || (t == PyUnicodeType);
	}

	internal static bool PyString_Check(IntPtr ob) {
	    return PyObject_Type(ob) == Runtime.PyStringType;
	}

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyString_FromString(string value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyString_FromStringAndSize(string value, int size);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern string
	PyString_AsString(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyString_AsString",
		   ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr 
	PyString_AS_STRING(IntPtr op);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyString_Size(IntPtr pointer);


	// Python unicode methods. Note that these support UCS-2 only!

	internal static bool PyUnicode_Check(IntPtr ob) {
	    return PyObject_Type(ob) == Runtime.PyUnicodeType;
	}

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyUnicodeUCS2_FromObject",
		    ExactSpelling=true, CharSet=CharSet.Unicode)]
	internal unsafe static extern IntPtr
	PyUnicode_FromObject(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyUnicodeUCS2_FromEncodedObject",
		    ExactSpelling=true, CharSet=CharSet.Unicode)]
	internal unsafe static extern IntPtr
	PyUnicode_FromEncodedObject(IntPtr ob, IntPtr enc, IntPtr err);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyUnicodeUCS2_FromUnicode",
		   ExactSpelling=true, CharSet=CharSet.Unicode)]
	internal unsafe static extern IntPtr
	PyUnicode_FromUnicode(string s, int size);

	internal static IntPtr PyUnicode_FromString(string s) {
	    return PyUnicode_FromUnicode(s, (s.Length));
	}

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyUnicodeUCS2_GetSize",
		   ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyUnicode_GetSize(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyUnicodeUCS2_AsUnicode",
		   ExactSpelling=true, CharSet=CharSet.Unicode)]
	internal unsafe static extern string
	PyUnicode_AsUnicode(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   EntryPoint="PyUnicodeUCS2_AsUnicode",
		   ExactSpelling=true, CharSet=CharSet.Unicode)]
	internal unsafe static extern IntPtr
	PyUnicode_AS_UNICODE(IntPtr op);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		   ExactSpelling=true, CharSet=CharSet.Unicode)]
	internal unsafe static extern IntPtr 
	PyUnicode_FromOrdinal(int c);

	internal static string GetManagedString(IntPtr op) {
	    IntPtr type = PyObject_Type(op);
	    if (type == Runtime.PyStringType) {
		return Runtime.PyString_AsString(op);
	    }
	    if (type == Runtime.PyUnicodeType) {
		return Runtime.PyUnicode_AsUnicode(op);
	    }
	    return null;
	}


	// Python dict methods

	internal static bool PyDict_Check(IntPtr ob) {
	    return PyObject_Type(ob) == Runtime.PyDictType;
	}

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_New();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDictProxy_New(IntPtr dict);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_GetItem(IntPtr pointer, IntPtr key);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_GetItemString(IntPtr pointer, string key);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyDict_SetItem(IntPtr pointer, IntPtr key, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyDict_SetItemString(IntPtr pointer, string key, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyDict_DelItem(IntPtr pointer, IntPtr key);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyMapping_HasKey(IntPtr pointer, IntPtr key);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_Keys(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_Values(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_Items(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyDict_Copy(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyDict_Update(IntPtr pointer, IntPtr other);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyDict_Clear(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyDict_Size(IntPtr pointer);


	// Python list methods

	internal static bool PyList_Check(IntPtr ob) {
	    return PyObject_Type(ob) == Runtime.PyListType;
	}

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyList_New(int size);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyList_AsTuple(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyList_GetItem(IntPtr pointer, int index);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_SetItem(IntPtr pointer, int index, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_Insert(IntPtr pointer, int index, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_Append(IntPtr pointer, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_Reverse(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_Sort(IntPtr pointer);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyList_GetSlice(IntPtr pointer, int start, int end);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_SetSlice(IntPtr pointer, int start, int end, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyList_Size(IntPtr pointer);


	// Python tuple methods

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyTuple_New(int size);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyTuple_GetItem(IntPtr pointer, int index);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyTuple_SetItem(IntPtr pointer, int index, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyTuple_GetSlice(IntPtr pointer, int start, int end);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyTuple_Size(IntPtr pointer);


	// Python module methods

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern string
	PyModule_GetName(IntPtr module);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyModule_GetDict(IntPtr module);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern string
	PyModule_GetFilename(IntPtr module);




	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyImport_Import(IntPtr name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyImport_ImportModule(string name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyImport_ReloadModule(IntPtr module);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyImport_AddModule(string name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyImport_GetModuleDict();


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PySys_SetArgv(int argc, IntPtr argv);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PySys_GetObject(string name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PySys_SetObject(string name, IntPtr ob);




	// Type related methods

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern bool 
	PyType_IsSubtype(IntPtr t1, IntPtr t2);

        internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp) {
	  IntPtr t = PyObject_Type(ob);
	  return (t == tp) || PyType_IsSubtype(t, tp);
	}

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyType_GenericNew(IntPtr type, IntPtr args, IntPtr kw);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyType_GenericAlloc(IntPtr type, int n);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyType_Ready(IntPtr type);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	_PyType_Lookup(IntPtr type, IntPtr name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyObject_GenericGetAttr(IntPtr obj, IntPtr name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyObject_GenericSetAttr(IntPtr obj, IntPtr name, IntPtr value);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	_PyObject_GetDictPtr(IntPtr obj);


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyCFunction_New(IntPtr ml, IntPtr self);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyCFunction_Call(IntPtr func, IntPtr args, IntPtr kw);


	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyClass_New(IntPtr bases, IntPtr dict, IntPtr name);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyInstance_New(IntPtr cls, IntPtr args, IntPtr kw);



	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyMem_Malloc(int size);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyMem_Realloc(IntPtr ptr, int size);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyMem_Free(IntPtr ptr);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyMethod_New(IntPtr func, IntPtr self, IntPtr cls);




	// Exception APIs

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyErr_SetString(IntPtr ob, string message);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyErr_SetObject(IntPtr ob, IntPtr message);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern IntPtr
	PyErr_SetFromErrno(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern void
	PyErr_SetNone(IntPtr ob);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyErr_ExceptionMatches(IntPtr exception);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyErr_GivenExceptionMatches(IntPtr ob, IntPtr val);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
	PyErr_NormalizeException(IntPtr ob, IntPtr val, IntPtr tb);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
	internal unsafe static extern int
	PyErr_Occurred();

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
	PyErr_Fetch(ref IntPtr ob, ref IntPtr val, ref IntPtr tb);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
	PyErr_Restore(IntPtr ob, IntPtr val, IntPtr tb);

	[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
		    ExactSpelling=true, CharSet=CharSet.Ansi)]
        internal unsafe static extern void
	PyErr_Clear();

    }


}


=== Added File PythonNet/src/runtime/TypeGenerator.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Reflection.Emit;
using System.Collections;
using System.Reflection;
using System.Security;


using System.Threading;

namespace Python.Runtime {

    //=======================================================================
    // The TypeGenerator class is responsible for building binary-compatible
    // Python type objects that are connected to a managed implementation.
    //=======================================================================

    [SuppressUnmanagedCodeSecurityAttribute()]

    internal class TypeGenerator {

	string name;
	Type itype;
	
	internal TypeGenerator(string name, Type implType) {
	    this.name = name;
	    this.itype = implType;
	}

	static ArrayList alive;
	static Hashtable cache;
	static IntPtr p_thunk;
	static int obSize;
	static int tpSize;

	static TypeGenerator() {
	    obSize = Marshal.SizeOf(new PyObjectHead());
	    tpSize = Marshal.SizeOf(new PyTypeObject());
	    p_thunk = Marshal.AllocHGlobal(IntPtr.Size);
	    cache = new Hashtable();
	    alive = new ArrayList();
	}

	internal IntPtr GetTypeHandle() {
	    return IntPtr.Zero;
	}

//  	private static IntPtr GetThunk(MethodInfo method) {
//  	    //Type dt = typeof(CallbackThunks).GetNestedType(method.Name);
//  	    Type dt = Prototypes.GetPrototype(method.Name);
//  	    if (dt != null) {
//  		Delegate d = Delegate.CreateDelegate(dt, method);
//  		CallbackThunk cb = new CallbackThunk(d);
//  		Marshal.StructureToPtr(cb, p_thunk, false);
//  		IntPtr fp = Marshal.ReadIntPtr(p_thunk);
//  		alive.Add(d);
//  		return fp;
//  	    }
//  	    return IntPtr.Zero;
//  	}


	// Given a PyTypeObject instance, fill the slot pointer members of
	// the PyTypeObject with thunks pointing to methods defined by the
	// given implementing type.

	private static void InitializeSlots(PyTypeObject typeObj, Type type) {
	    BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
	    Type typedesc = typeof(PyTypeObject);

	    while (type != null) {
		MethodInfo[] methods = type.GetMethods(flags);
		for (int i = 0; i < methods.Length; i++) {
		    MethodInfo method = methods[i];

		    string name = method.Name;
		    if (! name.StartsWith("tp_") ) {
			continue;
		    }

		    FieldInfo fi = typedesc.GetField(name);
		    IntPtr value = (IntPtr) fi.GetValue(typeObj);
		    if ((fi != null) && (value == IntPtr.Zero)) {
			fi.SetValue(typeObj, Prototypes.GetThunk(method));
		    }
		}
		type = type.BaseType;
	    }
	}


	// Given an initialized PyTypeObject, add type methods (implemented
	// by the passed in managed type) to the type dictionary.

	private static void InitMethods(IntPtr pytype, Type type) {
	    IntPtr ppdict = Runtime._PyObject_GetDictPtr(pytype);
	    IntPtr dict = Marshal.ReadIntPtr(ppdict);
	    Type marker = typeof(PythonMethodAttribute);

	    BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

	    while (type != null) {
		MethodInfo[] methods = type.GetMethods(flags);
		for (int i = 0; i < methods.Length; i++) {
		    MethodInfo method = methods[i];
		    object[] attrs = method.GetCustomAttributes(marker, false);
		    if (attrs.Length > 0) {
			string method_name = method.Name;
			MethodInfo[] mi = new MethodInfo[1];
			mi[0] = method;
			MethodObject m = new TypeMethod(method_name, mi);
			Runtime.PyDict_SetItemString(dict, method_name,
						     m.Handle);
		    }
		}
		type = type.BaseType;
	    }
	}


	// Now blit the PyTypeObject instance to the unmanaged heap. This
	// bit lets us avoid pinning objects, which would disrupt the GC.

	private static IntPtr FinishType(PyTypeObject t) {
	    IntPtr op = Runtime.PyMem_Malloc(tpSize);
	    GCHandle gch = GCHandle.Alloc(t, GCHandleType.Pinned);
	    Marshal.StructureToPtr(t, op, false);
	    Runtime.PyType_Ready(op);
	    gch.Free();
	    return op;
	}



	// Initialize a new binary-compatible PyTypeObject for a simple
	// extension type. A separate overload handles reflected types.

	internal static IntPtr CreateType(Type obType) {

	    PyTypeObject pyTypeObj = new PyTypeObject();
	    pyTypeObj.tp_name = Marshal.StringToHGlobalAnsi(obType.Name);
	    pyTypeObj.ob_type = Runtime.PyTypeType;

	    pyTypeObj.tp_basicsize = (IntPtr)(3 * IntPtr.Size);
	    pyTypeObj.ob_refcnt = (IntPtr) 1;  // ??
	    pyTypeObj.tp_flags = (IntPtr) (PyTypeFlags.Default | 
					   PyTypeFlags.Managed);

	    InitializeSlots(pyTypeObj, obType);

	    IntPtr o = FinishType(pyTypeObj);
	    InitMethods(o, obType);
	    return o;
	}


	// Initialize a new binary-compatible PyTypeObject for a Python
	// type that reflects a managed type.

	internal static IntPtr CreateType(ManagedType obj, Type clrType) {
	    // Cleanup the type name to get rid of funny nested type names.
	    string name = clrType.FullName;
	    int i = name.LastIndexOf('+');
	    if (i > -1) {
		name = name.Substring(i + 1);
	    }

	    // todo - can blit this after first time!
	    PyTypeObject pyTypeObj = new PyTypeObject();
	    pyTypeObj.tp_name = Marshal.StringToHGlobalAnsi(name);

	    pyTypeObj.ob_type = Runtime.PyCLRMetaType;
	    obj.tpHandle = pyTypeObj.ob_type;
	    obj.gcHandle = GCHandle.Alloc(obj);

	    pyTypeObj.ob_size = (IntPtr)obj.gcHandle;
	    pyTypeObj.tp_basicsize = (IntPtr)(3 * IntPtr.Size);
	    pyTypeObj.ob_refcnt = (IntPtr) 1;  // ??
	    pyTypeObj.tp_flags = (IntPtr) (PyTypeFlags.Default | 
					   PyTypeFlags.BaseType |
					   PyTypeFlags.HeapType |
					   PyTypeFlags.Managed);
	    //pyTypeObj.tp_dictoffset = (IntPtr) (3 * IntPtr.Size);

	    InitializeSlots(pyTypeObj, obj.GetType());

	    IntPtr op = FinishType(pyTypeObj);
	    obj.pyHandle = op;
	    return op;
	}


    }






}


=== Added File PythonNet/src/runtime/TypeManager.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Runtime.InteropServices;
using System.Reflection.Emit;
using System.Collections;
using System.Reflection;


using System.Threading;

namespace Python.Runtime {

    //=======================================================================
    // The TypeManager class is responsible for building binary-compatible
    // Python type objects that reflect a managed type.
    //=======================================================================

    internal class TypeManager {

	static ArrayList dList;
	static Hashtable cache;
	static IntPtr p_thunk;
	static int obSize;
	static int tpSize;

	static TypeManager() {
	    obSize = Marshal.SizeOf(new PyObjectHead());
	    tpSize = Marshal.SizeOf(new PyTypeObject());
	    p_thunk = Marshal.AllocHGlobal(IntPtr.Size);
	    cache = new Hashtable();
	    dList = new ArrayList();
	    a = new ArrayList();
	}

	//====================================================================
	// Internal use: given a managed Type object, return the *handle* of 
	// a Python type object that reflects the managed type. The handle is
	// a PyObject *, 

	internal static IntPtr GetTypeHandle(Type obType) {
	    Object ob = cache[obType];
	    if (ob != null) {
		return (IntPtr) ob;
	    }
	    IntPtr tp = CreateType(obType);
	    cache[obType] = tp;
	    return tp;
	}

	internal static IntPtr GetTypeHandle(ManagedType obj, Type clrType) {
	    Object ob = cache[clrType];
	    if (ob != null) {
		return (IntPtr) ob;
	    }
	    IntPtr tp = CreateType(obj, clrType);
	    cache[clrType] = tp;
	    return tp;
	}


	static ArrayList a;



	// Given a PyTypeObject instance, fill the slot pointer members of
	// the PyTypeObject with thunks pointing to methods defined by the
	// given implementing type.

	private static void InitializeSlots(PyTypeObject typeObj, Type type) {
	    BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
	    Type typedesc = typeof(PyTypeObject);

	    while (type != null) {
		MethodInfo[] methods = type.GetMethods(flags);
		for (int i = 0; i < methods.Length; i++) {
		    MethodInfo method = methods[i];

		    string name = method.Name;
		    if (! (name.StartsWith("tp_") ||
			   name.StartsWith("nb_") ||
			   name.StartsWith("sq_") ||
			   name.StartsWith("bf_")
			   ) ) {
			continue;
		    }

		    FieldInfo fi = typedesc.GetField(name);
		    IntPtr value = (IntPtr) fi.GetValue(typeObj);
		    if ((fi != null) && (value == IntPtr.Zero)) {
			fi.SetValue(typeObj, Prototypes.GetThunk(method));
		    }
		}
		type = type.BaseType;
	    }
	}


	// Given an initialized PyTypeObject, add type methods (implemented
	// by the passed in managed type) to the type dictionary.

	private static void InitMethods(IntPtr pytype, Type type) {
	    IntPtr ppdict = Runtime._PyObject_GetDictPtr(pytype);
	    IntPtr dict = Marshal.ReadIntPtr(ppdict);
	    Type marker = typeof(PythonMethodAttribute);

	    BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

	    while (type != null) {
		MethodInfo[] methods = type.GetMethods(flags);
		for (int i = 0; i < methods.Length; i++) {
		    MethodInfo method = methods[i];
		    object[] attrs = method.GetCustomAttributes(marker, false);
		    if (attrs.Length > 0) {
			string method_name = method.Name;
			MethodInfo[] mi = new MethodInfo[1];
			mi[0] = method;
			MethodObject m = new TypeMethod(method_name, mi);
			Runtime.PyDict_SetItemString(dict, method_name,
						     m.Handle);
		    }
		}
		type = type.BaseType;
	    }
	}


	// fixup internal offsets to protocol method structs.

	public static void FixupOffsets(IntPtr op) {
	    IntPtr nboffset = new IntPtr(op.ToInt32() + (47 * IntPtr.Size));
	    Marshal.WriteIntPtr(op, (12 * IntPtr.Size), nboffset);

	    IntPtr sqoffset = new IntPtr(op.ToInt32() + (85 * IntPtr.Size));
	    Marshal.WriteIntPtr(op, (13 * IntPtr.Size), sqoffset);

	    IntPtr mpoffset = new IntPtr(op.ToInt32() + (95 * IntPtr.Size));
	    Marshal.WriteIntPtr(op, (14 * IntPtr.Size), mpoffset);

	    IntPtr bfoffset = new IntPtr(op.ToInt32() + (98 * IntPtr.Size));
	    Marshal.WriteIntPtr(op, (20 * IntPtr.Size), bfoffset);
	}


	// Now blit the PyTypeObject instance to the unmanaged heap. This
	// bit lets us avoid pinning objects, which would disrupt the GC.

	private static IntPtr FinishType(PyTypeObject t) {
	    IntPtr op = Runtime.PyMem_Malloc(tpSize);
	    GCHandle gch = GCHandle.Alloc(t, GCHandleType.Pinned);
	    Marshal.StructureToPtr(t, op, false);

	    FixupOffsets(op);

	    Runtime.PyType_Ready(op);
	    gch.Free();
	    return op;
	}



	// Initialize a new binary-compatible PyTypeObject for a simple
	// extension type. A separate overload handles reflected types.

	internal static IntPtr CreateType(Type obType) {

	    PyTypeObject pyTypeObj = new PyTypeObject();
	    pyTypeObj.tp_name = Marshal.StringToHGlobalAnsi(obType.Name);
	    pyTypeObj.ob_type = Runtime.PyTypeType;

	    pyTypeObj.tp_basicsize = (IntPtr)(3 * IntPtr.Size);
	    pyTypeObj.ob_refcnt = (IntPtr) 1;  // ??
	    pyTypeObj.tp_flags = (IntPtr) (PyTypeFlags.Default | 
					   PyTypeFlags.Managed);

	    InitializeSlots(pyTypeObj, obType);

	    IntPtr o = FinishType(pyTypeObj);
	    InitMethods(o, obType);
	    return o;
	}


	// Initialize a new binary-compatible PyTypeObject for a Python
	// type that reflects a managed type.

	internal static IntPtr CreateType(ManagedType obj, Type clrType) {
	    // Cleanup the type name to get rid of funny nested type names.
	    string name = "CLR." + clrType.FullName;
	    int i = name.LastIndexOf('+');
	    if (i > -1) {
		name = name.Substring(i + 1);
	    }

	    // todo - can blit this after first time!
	    PyTypeObject pyTypeObj = new PyTypeObject();
	    pyTypeObj.tp_name = Marshal.StringToHGlobalAnsi(name);

	    pyTypeObj.ob_type = Runtime.PyCLRMetaType;
	    obj.tpHandle = pyTypeObj.ob_type;
	    obj.gcHandle = GCHandle.Alloc(obj);

	    pyTypeObj.ob_size = (IntPtr)obj.gcHandle;
	    pyTypeObj.tp_basicsize = (IntPtr)(3 * IntPtr.Size);
	    pyTypeObj.ob_refcnt = (IntPtr) 1;  // ??
	    pyTypeObj.tp_flags = (IntPtr) (PyTypeFlags.Default | 
					   PyTypeFlags.BaseType |
					   PyTypeFlags.HeapType |
					   PyTypeFlags.Managed);
	    //pyTypeObj.tp_dictoffset = (IntPtr) (3 * IntPtr.Size);

	    InitializeSlots(pyTypeObj, obj.GetType());

	    IntPtr op = FinishType(pyTypeObj);
	    obj.pyHandle = op;
	    return op;
	}


    }






}


=== Added File PythonNet/src/runtime/TypeMethod.cs ===
// Copyright (c) 2001, 2002 Zope Corporation and Contributors.
//
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python type that provides access to CLR object methods.
    //========================================================================

    internal class TypeMethod : MethodObject {

	public TypeMethod(string name, MethodInfo[] info) : 
	       base(name, info) {}

	public override IntPtr Invoke(IntPtr ob, IntPtr args, IntPtr kw) {
	    MethodInfo mi = this.info[0];
	    Object[] arglist = new Object[3];
	    arglist[0] = ob;
	    arglist[1] = args;
	    arglist[2] = kw;

	    try {	
		Object inst = null;
		if (ob != IntPtr.Zero) {
		    inst = GetManagedObject(ob);
		}
		return (IntPtr)mi.Invoke(inst, BindingFlags.Default, null, arglist, 
				 null);
	    }
	    catch (Exception e) {
		Exceptions.SetError(e);
		return IntPtr.Zero;
	    }
	}



    }


}


=== Added File PythonNet/src/runtime/makefile ===
# Makefile for the PythonRuntime .NET assembly

CSC=csc.exe

all: Python.Runtime.dll

Python.Runtime.dll:
	$(CSC) /nologo /unsafe /target:library /out:../../Python.Runtime.dll \
        /recurse:*.cs

clean:
	rm -f ../../Python.Runtime.dll ../../Python.Runtime.xml
	rm -f ./*~