public override IMessage Invoke(IMessage msg)
		{
			IMethodCallMessage callMessage = msg as IMethodCallMessage;

			object returnValue = null;

			MethodInfo method = callMessage.MethodBase as MethodInfo;					
			
			// We intercept all method calls on the interface and delegate the method
			// call to the COM reference.
			// Only exception is for "Dispose" which needs to be called on this class
			// in order to release the COM reference. COM reference does not have dispose
			if( method.Name == "Dispose" )
			{
				this.Release();
			}
			else
			{

				object invokeObject = this.COM;
				Type invokeType = this.COM.GetType();

				// Get Property called: Retrieve property value
				if( method.Name.StartsWith("get_") )
				{
					string propertyName = method.Name.Substring(4);
					returnValue = invokeType.InvokeMember( propertyName, BindingFlags.GetProperty, null,
						invokeObject, callMessage.InArgs );
				}
					// Set Property Called: Set the property value
				else if( method.Name.StartsWith("set_") )
				{
					string propertyName = method.Name.Substring(4);						
					returnValue = invokeType.InvokeMember( propertyName, BindingFlags.SetProperty, null,
						invokeObject, callMessage.InArgs );
				}
					// Regular method call
				else
				{
					returnValue = invokeType.InvokeMember( method.Name, BindingFlags.InvokeMethod, null,
						invokeObject, callMessage.Args );
				}

				// Now check if the method return value is also an interface. if it is an 
				// interface, then we are interested to intercept that too
				if( method.ReturnType.IsInterface && null != returnValue )
				{	
					// Return a intercepting wrapper for the com object
					DisposableCOMProxy proxy = new DisposableCOMProxy( returnValue, method.ReturnType );
					returnValue = proxy.GetTransparentProxy();
				}
				else if( method.ReturnType.IsEnum && null != returnValue )
				{
					// Convert to proper enum type
					returnValue = Enum.Parse(method.ReturnType, returnValue.ToString());
				}
			}

			// Construct a return message which contains the return value 
			ReturnMessage returnMessage = new ReturnMessage( returnValue, null, 
				0, callMessage.LogicalCallContext,
				callMessage );

			return returnMessage;
		}
		public static IDisposable Create( string progID, Type interfaceType )
		{	
			object theCOM = CreateCOM( progID );
			DisposableCOMProxy wrapper = new DisposableCOMProxy( theCOM, interfaceType );
			return wrapper.GetTransparentProxy() as IDisposable;
		}