[Zope-CVS] CVS: PythonNet/src - ArrayObject.cs:1.1 AssemblyInfo.cs:1.1 AssemblyManager.cs:1.1 CLRObject.cs:1.1 CallbackThunks.cs:1.1 CastHelper.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 PyDict.cs:1.1 PyFloat.cs:1.1 PyInteger.cs:1.1 PyList.cs:1.1 PyLong.cs:1.1 PyModule.cs:1.1 PyNumber.cs:1.1 PyObject.cs:1.1 PySequence.cs:1.1 PyString.cs:1.1 PyTuple.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, 17 Feb 2003 22:44:40 -0500


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

Added Files:
	ArrayObject.cs AssemblyInfo.cs AssemblyManager.cs CLRObject.cs 
	CallbackThunks.cs CastHelper.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 PyDict.cs 
	PyFloat.cs PyInteger.cs PyList.cs PyLong.cs PyModule.cs 
	PyNumber.cs PyObject.cs PySequence.cs PyString.cs PyTuple.cs 
	PythonException.cs PythonInterpreter.cs Runtime.cs 
	TypeGenerator.cs TypeManager.cs TypeMethod.cs makefile 
Log Message:
initial commit

=== Added File PythonNet/src/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/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/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>
    /// Manages the tracking of assemblies and namespaces and provides a
    /// simplified internal interface for finding and obtaining Types.
    /// </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. This ensures that we
	// can track all assemblies loaded into the running app domain.
	//===================================================================

	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/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/CallbackThunks.cs === (465/565 lines abridged)
// 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 {


    // 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;

[-=- -=- -=- 465 lines omitted -=- -=- -=-]


    // A NativeMethod object wraps a (static) managed method, making it
    // look like a PyCFunction object. This is used mainly to implement
    // the CLR import hook.

    internal class NativeMethod {

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

	public NativeMethod(Type obType, string name) {

	    // Allocate and initialize a PyMethodDef structure to represent 
	    // the managed method, then create a PyCFunction. The PyMethodDef 
	    // will be cleaned up when the NativeMethod is garbage-collected.

	    mDelegate = Delegate.CreateDelegate(typeof(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);

	}

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

    }









}


=== Added File PythonNet/src/CastHelper.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 {

    // todo: is this actually needed??

    /// <summary>
    /// The CastHelper class does low-level indirect casting of objects.
    /// </summary>

    internal class CastHelper {

	static Hashtable cache;

	static CastHelper() {
	    cache = new Hashtable();
	}

	internal static Object CastObject(Object ob, Type type) {
	    ICastHelper helper = cache[type.FullName] as ICastHelper;
	    if (helper == null) {
		helper = GetCastHelper(type);
		cache[type.FullName] = helper;
	    }
	    return helper.CastObject(ob);
	}

	// todo: avoid using instances

	private static ICastHelper GetCastHelper(Type type) {

	    string name = "__CastHelper_" + type.FullName;
	    name = name.Replace(Type.Delimiter, '_');
	    TypeBuilder tb = CodeGenerator.DefineType(name);

	    Type basetype = typeof(ICastHelper);
	    tb.AddInterfaceImplementation(basetype);

	    MethodInfo mi = basetype.GetMethod("CastObject");
	    
	    ParameterInfo[] pi = mi.GetParameters();
	    int count = pi.Length;

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

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

	    ILGenerator il = mb.GetILGenerator();
	    il.Emit(OpCodes.Ldarg_1);
	    il.Emit(OpCodes.Castclass, type);
	    il.Emit(OpCodes.Ret);

	    tb.DefineMethodOverride(mb, mi);

	    Type impl = tb.CreateType();
	    ICastHelper helper = (ICastHelper)Activator.CreateInstance(impl);
	    return helper;
	}

    }

    public interface ICastHelper {

	object CastObject(object ob);

    }



}


=== Added File PythonNet/src/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);


	    PyDict dict = new PyDict(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);
		    dict[mi.Name] = (PyObject) mt;
		    continue;

	        case MemberTypes.Field:
		    FieldInfo fi = (FieldInfo) mi;
		    if (!(fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly))
			continue;
		    mt = new FieldObject((FieldInfo) mi);
		    dict[mi.Name] = (PyObject) mt;
		    continue;

	        case MemberTypes.Event:
		    mt = new EventObject((EventInfo) mi);
		    dict[mi.Name] = (PyObject) mt;
		    continue;

	        case MemberTypes.NestedType:
		    tp = (Type) mi;
		    if (!(tp.IsNestedPublic || tp.IsNestedFamily || 
			  tp.IsNestedFamORAssem))
			continue;
		    mt = ClassManager.GetClass(tp);
		    dict[mi.Name] = (PyObject) mt;
		    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);
		dict[name] = (PyObject) mt;

	    }
	}


	//====================================================================
	// 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;
	    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/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/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/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/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/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);
	}


//  	internal static IntPtr ToPython(Object value) {
//  	    if (value == null) {
//  		IntPtr result = Runtime.PyNone;
//  		Runtime.Incref(result);
//  		return result;
//  	    }
//  	    return ToPython(value, value.GetType());
//  	}


	//====================================================================
	// 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;

	    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) {

	    PyObject 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/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/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/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/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/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/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() {}

	internal static void Initialize() {
	    // TODO: fix this to use PyObject wrappers correctly (refs!).

	    // This is called when the Python runtime is intitialized. It 
	    // uses reflection to generate PyObject instances to wrap the
	    // standard Python exception types.
	    IntPtr module = Runtime.PyImport_ImportModule("exceptions");

	    Type tp = typeof(Exceptions);
	    foreach (FieldInfo fi in tp.GetFields(BindingFlags.Public | 
						  BindingFlags.Static)) {
		IntPtr op = Runtime.PyObject_GetAttrString(module, fi.Name);
		if (op != IntPtr.Zero) {
		    // owned reference
		    PyObject ob = new PyObject(op);
		    fi.SetValue(tp, ob);
		}
	    }
	    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(PyObject ob) {
	    return Runtime.PyErr_ExceptionMatches(ob.Handle) != 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(PyObject exc, PyObject ob) {
	    int i = Runtime.PyErr_GivenExceptionMatches(exc.Handle, ob.Handle);
	    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(PyObject ob, string value) {
	    Runtime.PyErr_SetString(ob.Handle, 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(PyObject ob, PyObject value) {
	    Runtime.PyErr_SetObject(ob.Handle, value.Handle);
	}

	/// <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.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 PyObject ArithmeticError;
	public static PyObject AssertionError;
	public static PyObject AttributeError;
	public static PyObject DeprecationWarning;
	public static PyObject EOFError;
	public static PyObject EnvironmentError;
	public static PyObject Exception;
	public static PyObject FloatingPointError;
	public static PyObject IOError;
	public static PyObject ImportError;
	public static PyObject IndentationError;
	public static PyObject IndexError;
	public static PyObject KeyError;
	public static PyObject KeyboardInterrupt;
	public static PyObject LookupError;
	public static PyObject MemoryError;
	public static PyObject NameError;
	public static PyObject NotImplementedError;
	public static PyObject OSError;
	public static PyObject OverflowError;
	public static PyObject OverflowWarning;
	public static PyObject ReferenceError;
	public static PyObject RuntimeError;
	public static PyObject RuntimeWarning;
	public static PyObject StandardError;
	public static PyObject StopIteration;
	public static PyObject SyntaxError;
	public static PyObject SyntaxWarning;
	public static PyObject SystemError;
	public static PyObject SystemExit;
	public static PyObject TabError;
	public static PyObject TypeError;
	public static PyObject UnboundLocalError;
	public static PyObject UnicodeError;
	public static PyObject UserWarning;
	public static PyObject ValueError;
	public static PyObject Warning;
	public static PyObject WindowsError;
	public static PyObject ZeroDivisionError;

    }


}


=== Added File PythonNet/src/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/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/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/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/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/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);
	}




	public static explicit operator PyObject (ManagedType ob) {
	    return new PyObject(ob.pyHandle);
	}

    }

}



=== Added File PythonNet/src/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/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/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/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.
    //========================================================================
    // todo: decref unbound on dealloc

    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/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(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/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/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/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/PyDict.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;

namespace Python.Runtime {


    public class PyDict : PyObject {

	public PyDict(IntPtr pointer) : base(pointer) {}

	public PyDict() : base(IntPtr.Zero) {
	    handle = Runtime.PyDict_New();
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public override int Length {
	    get {
		return Runtime.PyDict_Size(handle);
	    }
	}


	public override PyObject GetItem(PyObject key) {
	    IntPtr item = Runtime.PyDict_GetItem(handle, key.handle);
	    if (item == IntPtr.Zero) {
		throw new PythonException();
	    }
	    Runtime.Incref(item);
	    return new PyObject(item);
	}

	public override void SetItem(PyObject key, PyObject item) {
	    int n = Runtime.PyDict_SetItem(handle, key.handle, item.handle);
	    if (n < 0) {
		throw new PythonException();
	    }
	}

	public override void DelItem(PyObject key) {
	    int n = Runtime.PyDict_DelItem(handle, key.handle);
	    if (n < 0) {
		throw new PythonException();
	    }
	}


	public bool HasKey(PyObject key) {
	    return (Runtime.PyMapping_HasKey(handle, key.handle) != 0);
	}

	public bool HasKey(string key) {
	    return HasKey(new PyString(key));
	}

	public PyObject Keys() {
	    IntPtr items = Runtime.PyDict_Keys(handle);
	    if (items == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(items);
	}

	public PyObject Values() {
	    IntPtr items = Runtime.PyDict_Values(handle);
	    if (items == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(items);
	}

	public PyObject Items() {
	    IntPtr items = Runtime.PyDict_Items(handle);
	    if (items == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(items);
	}

	public PyDict Copy() {
	    IntPtr copy = Runtime.PyDict_Copy(handle);
	    if (copy == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyDict(copy);
	}

	public void Update(PyObject other) {
	    int result = Runtime.PyDict_Update(handle, other.handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void Clear() {
	    Runtime.PyDict_Clear(handle);
	}

    }


}


=== Added File PythonNet/src/PyFloat.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;

namespace Python.Runtime {


    public class PyFloat : PyNumber {

	public PyFloat(IntPtr pointer) : base(pointer) {}

	public PyFloat(double value) : base(IntPtr.Zero) {
	    handle = Runtime.PyFloat_FromDouble(value);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public PyFloat(string value) : base(IntPtr.Zero) {
	    PyString pyStr = new PyString(value);
	    handle = Runtime.PyFloat_FromString(pyStr.handle, IntPtr.Zero);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

    }


}


=== Added File PythonNet/src/PyInteger.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;

namespace Python.Runtime {


    public class PyInteger : PyNumber {

	private bool cached = false;
	private int ival = 0;

	public PyInteger(IntPtr pointer) : base(pointer) {}

	public PyInteger(string value) : base(IntPtr.Zero) {
	    handle = Runtime.PyInt_FromString(value, IntPtr.Zero, 0);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public PyInteger(int value) : base(IntPtr.Zero) {
	    handle = Runtime.PyInt_FromLong(value);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	    ival = value;
	    cached = true;
	}

	public PyInteger(long value) : base(IntPtr.Zero) {
	    if (value > Int32.MaxValue || value < Int32.MinValue) {
		throw new OverflowException("Value too large");
	    }
	    handle = Runtime.PyInt_FromLong((int)value);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	    ival = (int)value;
	    cached = true;
	}

	public PyInteger(bool value) : this((int)(value ? 1 : 0)) {}

	public PyInteger(short value) : this((int)value) {}



	public int Value {
	    get {
		if (!cached) {
		    ival = Runtime.PyInt_AsLong(handle);
		}
		return ival;
	    }
	}


	public bool ToBoolean() {
	    return (this.Value != 0);
	}

	public short ToInt16() {
	    return System.Convert.ToInt16(this.Value);
	}

	public int ToInt32() {
	    return this.Value;
	}

	public long ToInt64() {
	    return System.Convert.ToInt64(this.Value);
	}

	public double ToDouble() {
	    return System.Convert.ToDouble(this.Value);
	}

    }


}


=== Added File PythonNet/src/PyList.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 {


    public class PyList : PySequence {

	public PyList(IntPtr pointer) : base(pointer) {}

	public PyList() : base(IntPtr.Zero) {
	    handle = Runtime.PyList_New(0);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public PyList(PyObject[] items) : base(IntPtr.Zero) {
	    int size = items.Length;
	    int result;

	    handle = Runtime.PyList_New(size);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	    for (int i = 0; i < size; i++) {
		Runtime.Incref(items[i].handle);
		result = Runtime.PyList_SetItem(handle, i, items[i].handle);
		if (result < 0) {
		    throw new PythonException();
		}
	    }
	}


	public void Append(PyObject item) {
	    int result = Runtime.PyList_Append(handle, item.Handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void Insert(int index, PyObject item) {
	    int result = Runtime.PyList_Insert(handle, index, item.Handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void Reverse() {
	    int result = Runtime.PyList_Reverse(handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void Sort() {
	    int result = Runtime.PyList_Sort(handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

    }


}


=== Added File PythonNet/src/PyLong.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;

namespace Python.Runtime {


    public class PyLong : PyNumber {

	public PyLong(IntPtr pointer) : base(pointer) {}

	public PyLong(int value) : base(IntPtr.Zero) {
	    handle = Runtime.PyLong_FromLong((long)value);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public PyLong(long value) : base(IntPtr.Zero) {
	    handle = Runtime.PyLong_FromLong(value);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public PyLong(double value) : base(IntPtr.Zero) {
	    handle = Runtime.PyLong_FromDouble(value);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public PyLong(string value) : base(IntPtr.Zero) {
	    handle = Runtime.PyLong_FromString(value, IntPtr.Zero, 0);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

    }


}


=== Added File PythonNet/src/PyModule.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 {


    public class PyModule : PyObject {

	public PyModule(IntPtr pointer) : base(pointer){
	}

	public string Filename {
	    get {
		return Runtime.PyModule_GetFilename(handle);
	    }
	}

	public string Name {
	    get {
		return Runtime.PyModule_GetName(handle);
	    }
	}

	public PyDict GetDict() {
	    IntPtr result = Runtime.PyModule_GetDict(handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    Runtime.Incref(result);
	    return new PyDict(result);
	}

    }


}


=== Added File PythonNet/src/PyNumber.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;

namespace Python.Runtime {


    public class PyNumber : PyObject {

	public PyNumber(IntPtr pointer) : base(pointer) {}


	// Conversions to Python types

	public PyInteger ToPyInteger() {
	    IntPtr result = Runtime.PyNumber_Int(handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyInteger(result);
	}

	public PyLong ToPyLong() {
	    IntPtr result = Runtime.PyNumber_Long(handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyLong(result);
	}

	public PyFloat ToPyFloat() {
	    IntPtr result = Runtime.PyNumber_Float(handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyFloat(result);
	}

    }


}


=== Added File PythonNet/src/PyObject.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>
    /// Represents an arbitrary Python object.
    /// </summary>

    public class PyObject : IDisposable {

	// Reference to the native PyObject pointer.
	internal protected IntPtr handle = IntPtr.Zero;

	/// <summary>
	/// PyObject Constructor
	/// </summary>
	///
	/// <remarks>
	/// Creates a new PyObject from an IntPtr object reference.
	/// </remarks>
	///
	/// <param name='pointer'>
	/// The native PyObject pointer.
	/// </param>
	///
	/// <param name='borrowed'>
	/// A boolean that specifies whether the PyObject pointer is a
	/// borrowed reference. This ensures that the reference count
	/// of the underlying object is handled correctly when the
	/// PyObject instance is garbage collected.
	/// </param>


	public PyObject(IntPtr pointer) {
	    handle = pointer;
	    Runtime.Incref(pointer);
	}

	/// <summary>
	/// Dispose Method
	/// </summary>
	///
	/// <remarks>
	/// The Dispose method provides a way to explicitly release the 
	/// Python object represented by a PyObject instance. Normally
	/// the .NET garbage collector will ensure that Python object
	/// references are managed correctly, but in some cases it is
	/// desirable to release an object reference as soon as possible
	/// (to free an object that holds limited resources, for example)
	/// without waiting for the garbage collector to get around to it.
	/// </remarks>

	public void Dispose() {
	    Console.WriteLine("dispose called: {0}", this.ToString());
	    GC.SuppressFinalize(this);
	    //Runtime.Decref(handle);
	    handle = IntPtr.Zero;
	}

	/// <summary>
	/// Finalize Method
	/// </summary>
	///
	/// <remarks>
	/// Provides support for automatic reference management for 
	/// PyObject instances. This method is called by the runtime
	/// and should not be called by application code.
	/// </remarks>

	public void Finalize() {
	    Dispose();
	}


	// Object Properties

	public PyObject PythonType {
	    get {
		return new PyObject(Runtime.PyObject_Type(handle));
	    }
	}

	public int RefCount {
	    get {
		return Runtime.GetRefCount(handle);
	    }
	}

	/// <summary>
	/// Handle Property
	/// </summary>
	///
	/// <remarks>
	/// Gets the native handle of the underlying Python object.
	/// </remarks>

	public IntPtr Handle {
	    get {
		return handle;
	    }
	}

	public virtual int Length {
	    get {
		int result = Runtime.PyObject_Size(handle);
		if (result < 0) {
		    Runtime.PyErr_Clear();
		    return 0;
		}
		return result;
	    }
	}


	public void Incref() {
	    Runtime.Incref(handle);
	}

	public void Decref() {
	    Runtime.Decref(handle);
	}

	public bool HasAttr(string name) {
	    return (Runtime.PyObject_HasAttrString(handle, name) != 0);
	}

	public bool HasAttr(PyObject name) {
	    return (Runtime.PyObject_HasAttr(handle, name.handle) != 0);
	}

	public PyObject GetAttr(string name) {
	    PyString pyName = new PyString(name);
	    IntPtr result = Runtime.PyObject_GetAttr(handle, pyName.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public PyObject GetAttr(string name, PyObject def) {
	    PyString pyName = new PyString(name);
	    IntPtr result = Runtime.PyObject_GetAttr(handle, pyName.handle);
	    if (result == IntPtr.Zero) {
		Runtime.PyErr_Clear();
		return def;
	    }
	    return new PyObject(result);
	}

	public PyObject GetAttr(PyObject name) {
	    IntPtr result = Runtime.PyObject_GetAttr(handle, name.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public PyObject GetAttr(PyObject name, PyObject def) {
	    IntPtr result = Runtime.PyObject_GetAttr(handle, name.handle);
	    if (result == IntPtr.Zero) {
		Runtime.PyErr_Clear();
		return def;
	    }
	    return new PyObject(result);
	}


	public void SetAttr(string name, PyObject value) {
	    int result = Runtime.PyObject_SetAttrString(
				 handle, name, value.handle
				 );
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void SetAttr(PyObject name, PyObject value) {
	    int result = Runtime.PyObject_SetAttr(
				 handle, name.handle, value.handle
				 );
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void DelAttr(string name) {
	    int result = Runtime.PyObject_SetAttrString(
				 handle, name, IntPtr.Zero
				 );
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public void DelAttr(PyObject name, PyObject value) {
	    int result = Runtime.PyObject_SetAttr(
				 handle, name.handle, IntPtr.Zero
				 );
	    if (result < 0) {
		throw new PythonException();
	    }
	}



	public virtual PyObject this[string key] {
	    get { return GetItem(key); }
	    set { SetItem(key, value); }
	}

	public virtual PyObject this[PyObject key] {
	    get { return GetItem(key); }
	    set { SetItem(key, value); }
	}

	public virtual PyObject this[int index] {
	    get { return GetItem(index); }
	    set { SetItem(index, value); }
	}

	public virtual PyObject GetItem(PyObject key) {
	    IntPtr result = Runtime.PyObject_GetItem(handle, key.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public virtual PyObject GetItem(string key) {
	    return GetItem(new PyString(key));
	}

	public virtual PyObject GetItem(int index) {
	    PyInteger key = new PyInteger(index);
	    return GetItem((PyObject)key);
	}


	public virtual void SetItem(PyObject key, PyObject value) {
	    int result = Runtime.PyObject_SetItem(
				 handle, key.handle, value.handle
				 );
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public virtual void SetItem(string key, PyObject value) {
	    SetItem(new PyString(key), value);
	}

	public virtual void SetItem(int index, PyObject value) {
	    // TODO
	    return;
	}


	public virtual void DelItem(PyObject key) {
	    int result = Runtime.PyObject_DelItem(handle, key.handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public virtual void DelItem(string key) {
	    DelItem(new PyString(key));
	}

	public virtual void DelItem(int index) {
	    // TODO
	    return;
	}


	// TODO: add format-based implementations?

	public PyObject Invoke(PyObject[] args, PyDict kw) {
	    PyTuple t = new PyTuple(args);
	    IntPtr result = Runtime.PyObject_Call(handle, t.handle, kw.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public PyObject Invoke(params PyObject[] args) {
	    PyTuple t = new PyTuple(args);
	    IntPtr result = Runtime.PyObject_Call(handle, t.handle, 
						  IntPtr.Zero
						  );
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public PyObject InvokeMethod(string name, PyObject[] args, PyDict kw) {
	    return GetAttr(name).Invoke(args, kw);
	}

	public PyObject InvokeMethod(string name, params PyObject[] args) {
	    return GetAttr(name).Invoke(args);
	}







	public bool IsInstance(PyObject typeOrClass) {
	    int result = Runtime.PyObject_IsInstance(
				 handle, typeOrClass.handle
				 );
	    if (result < 0) {
		Runtime.PyErr_Clear();
		return false;
	    }
	    return (result != 0);
	}

	public bool IsSubclass(PyObject typeOrClass) {
	    int result = Runtime.PyObject_IsSubclass(
				 handle, typeOrClass.handle
				 );
	    if (result < 0) {
		Runtime.PyErr_Clear();
		return false;
	    }
	    return (result != 0);
	}

	public bool IsCallable() {
	    return (Runtime.PyCallable_Check(handle) != 0);
	}

	public bool IsTrue() {
	    return (Runtime.PyObject_IsTrue(handle) != 0);
	}

	public string Repr() {
	    IntPtr strval = Runtime.PyObject_Repr(handle);
	    string result = Runtime.PyString_AsString(strval);
	    //	Runtime.Decref(strval);
	    return result;
	}

	public override string ToString() {
	    IntPtr strval = Runtime.PyObject_Str(handle);
	    string result = Runtime.PyString_AsString(strval);
	    Runtime.Decref(strval);
	    return result;
	}

	public override bool Equals(object o) {
	    if (!(o is PyObject)) {
		return false;
	    }
	    if (handle == ((PyObject) o).handle) {
		return true;
	    }
	    int result = Runtime.PyObject_Compare(
				 handle, ((PyObject) o).handle
				 );
	    if (Exceptions.ErrorOccurred()) {
		throw new PythonException();
	    }
	    return (result == 0);
	}

	public override int GetHashCode() {
	    // fix this!
	    return handle.GetHashCode();
	}

    }


}


=== Added File PythonNet/src/PySequence.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;

namespace Python.Runtime {


    public class PySequence : PyObject {

	public PySequence(IntPtr pointer) : base(pointer) {
	}

	public override int Length {
	    get {
		return Runtime.PySequence_Size(handle);
	    }
	}

	public override PyObject GetItem(int index) {
	    IntPtr item = Runtime.PySequence_GetItem(handle, index);
	    if (item == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(item);
	}

	public override void SetItem(int index, PyObject item) {
	    int result = Runtime.PySequence_SetItem(handle, index, item.Handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

	public override void DelItem(int index) {
	    int result = Runtime.PySequence_DelItem(handle, index);
	    if (result < 0) {
		throw new PythonException();
	    }
	}


	// add slice ops
	// add op overloads

	public int Index(PyObject item) {
	    return Runtime.PySequence_Index(handle, item.handle);
	}

	public int Count(PyObject value) {
	    int result = Runtime.PySequence_Count(handle, value.handle);
	    if (result < 0) {
		Runtime.PyErr_Clear();
		return 0;
	    }
	    return result;
	}

	public bool Contains(PyObject other) {
	    int result = Runtime.PySequence_Contains(handle, other.handle);
	    if (result < 0) {
		Runtime.PyErr_Clear();
		return false;
	    }
	    return (result != 0);
	}

	public PyObject Concat(PyObject other) {
	    IntPtr result = Runtime.PySequence_Concat(handle, other.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public PyObject Repeat(int count) {
	    IntPtr result = Runtime.PySequence_Repeat(handle, count);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyObject(result);
	}

	public static PyTuple AsTuple(PyObject value) {
	    IntPtr result = Runtime.PySequence_Tuple(value.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyTuple(result);
	}

	public static PyList AsList(PyObject value) {
	    IntPtr result = Runtime.PySequence_List(value.handle);
	    if (result == IntPtr.Zero) {
		throw new PythonException();
	    }
	    return new PyList(result);
	}


    }


}


=== Added File PythonNet/src/PyString.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 {


    public class PyString : PySequence {

	public PyString(IntPtr pointer) : base(pointer) {}

	public PyString(string value) : base(IntPtr.Zero) {
	    handle = Runtime.PyString_FromStringAndSize(value, value.Length);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}

	public override int Length {
	    get {
		return Runtime.PyString_Size(handle);
	    }
	}

	public override string ToString() {
	    return Runtime.PyString_AsString(handle);
	}

    }


}


=== Added File PythonNet/src/PyTuple.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 {




    public class PyTuple : PySequence {

	public PyTuple(IntPtr pointer) : base(pointer) {}

	public PyTuple() : base(IntPtr.Zero) {
	    handle = Runtime.PyTuple_New(0);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	}
	
	public static PyTuple Empty;

	public PyTuple(PyObject[] items) : base(IntPtr.Zero) {
	    int size = items.Length;
	    int result;

	    handle = Runtime.PyTuple_New(size);
	    if (handle == IntPtr.Zero) {
		throw new PythonException();
	    }
	    for (int i = 0; i < size; i++) {
		Runtime.Incref(items[i].handle);
		result = Runtime.PyTuple_SetItem(handle, i, items[i].handle);
		if (result < 0) {
		    throw new PythonException();
		}
	    }
	}




	public override void SetItem(int index, PyObject item) {
	    Runtime.Incref(item.handle);
	    int result = Runtime.PyTuple_SetItem(handle, index, item.Handle);
	    if (result < 0) {
		throw new PythonException();
	    }
	}

    }


}


=== Added File PythonNet/src/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 PyObject Type {
	    get {
		return null;
	    }
	}

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

	public PyObject Value {
	    get {
		return null;
	    }
	}

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

	public PyObject Traceback {
	    get {
		return null;
	    }
	}

	/// <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(PyObject ob) {
	    return Runtime.PyErr_ExceptionMatches(ob.Handle) != 0;
	}

    } 


}


=== Added File PythonNet/src/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.Collections;

namespace Python.Runtime {


    public class PythonInterpreter {

	public static bool initialized;

	//private static IntPtr mainThread;
	//private static Hashtable threads;

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


	public static void TestInit() {
	    /*

	      First time decref on a gc-aware object:
	        PyObject_GC_UnTrack(ob)


	     */
	    Runtime.Py_Initialize();
	    initialized = true;

	    // always causes segfault
	    IntPtr d = Runtime.PyDict_New();
	    Runtime.Decref(d);

	    IntPtr t = Runtime.PyTuple_New(0);
	    Runtime.Decref(t);

	    // this always works (non-gc aware)
	    IntPtr i = Runtime.PyInt_FromLong(550);
	    Runtime.Decref(i);

	    IntPtr l = Runtime.PyLong_FromLong(550);
	    Runtime.Decref(l);

    }



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


	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 Platform {
	    get { 
		return Runtime.Py_GetPlatform(); 
	    }
	}

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

	public static string Compiler {
	    get { 
		return Runtime.Py_GetCompiler(); 
	    }
	}

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


	// TODO: support InitThreads, etc.

	/*
	  public void InitThreads() {}

	  public static void RegisterThread() {
	  IntPtr threadState = threads.Get(Thread.CurrentThread);
	  if (threadState != null) {
	  return;
	  }
	  Runtime.PyEval_AcquireLock();
	
	  }

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

	*/


	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.cs === (1005/1105 lines abridged)
// 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);

[-=- -=- -=- 1005 lines omitted -=- -=- -=-]


	[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/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, 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/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 are connected to a managed implementation.
    //=======================================================================

    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 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 AssemblyBuilder ab;
	static ModuleBuilder mb;
	static ArrayList a;

	internal static IntPtr GetThunk2(MethodInfo method) {
	    // this doesn't work because SigHelper expects to work with
	    // a generated module. If we could find a way to get a sig
	    // and length from a methodinfo, we could really make this
	    // simple...
	    if (mb == null) {
		AssemblyName aname = new AssemblyName();
		aname.Name = "__";
		AssemblyBuilderAccess aa = AssemblyBuilderAccess.Run;
		
		ab = Thread.GetDomain().DefineDynamicAssembly(aname, aa);
		mb = ab.DefineDynamicModule("__");
	    }

	    SignatureHelper s = SignatureHelper.GetMethodSigHelper(
								   //mb, //
								   method.DeclaringType.Module,
				  CallingConvention.Cdecl,
				  method.ReturnType
				  );

	    ParameterInfo[] pi = method.GetParameters();
	    for (int n = 0; n < pi.Length; n++) {
		s.AddArgument(pi[n].ParameterType);
	    }
	    byte[] bsig = s.GetSignature();
	    int csig = bsig.Length;
	    
	    IntPtr psig = Marshal.AllocHGlobal(bsig.Length);
	    Marshal.Copy(bsig, 0, psig, csig);

	    IntPtr fp = Marshal.GetUnmanagedThunkForManagedMethodPtr(
				method.MethodHandle.GetFunctionPointer(), 
				psig, 
				csig
				);
	    //Marshal.FreeHGlobal(psig);

	    a.Add(fp);
	    a.Add(s);
	    return fp;

	}





	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);
		dList.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_") ||
			   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, 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/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;
	    Object result;

	    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/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 ./*~