public object Intercept(InvocationInfo info)
		{
			string methodName = info.TargetMethod.Name;
			if ("get_DataHandler".Equals(methodName))
			{
				return this;
			}
			else if (methodName.StartsWith("set_"))
			{
				string propertyName = methodName.Substring(4);
				data[propertyName] = info.Arguments[0];
			}
			else if (methodName.StartsWith("get_"))
			{
				string propertyName = methodName.Substring(4);
				return data[propertyName];
			}
			else if ("ToString".Equals(methodName))
			{
				return entityName + "#" + data["Id"];
			}
			else if ("GetHashCode".Equals(methodName))
			{
				return GetHashCode();
			}
			return null;
		}
		public object Intercept(InvocationInfo info)
		{
			object returnValue;
			try
			{
				returnValue = base.Invoke(info.TargetMethod, info.Arguments, info.Target);

				// Avoid invoking the actual implementation, if possible
				if (returnValue != InvokeImplementation)
				{
					return returnValue;
				}

				var targetMethod = info.TargetMethod;
				if (targetMethod.IsGenericMethodDefinition && info.TypeArguments != null && info.TypeArguments.Length > 0)
				{
					targetMethod = targetMethod.MakeGenericMethod(info.TypeArguments);
				}
				returnValue = targetMethod.Invoke(GetImplementation(), info.Arguments);
			}
			catch (TargetInvocationException ex)
			{
				exceptionInternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] {});
				throw ex.InnerException;
			}

			return returnValue;
		}
        public new virtual object Intercept(InvocationInfo info)
        {
            if (_proxy == null)
            {
                _proxy = info.Target;
            }

            object returnValue = null;

            if (info.TargetMethod.Name == "add_PropertyChanged")
            {
                var propertyChangedEventHandler = info.Arguments[0] as PropertyChangedEventHandler;
                _changed += propertyChangedEventHandler;
            }
            else if (info.TargetMethod.Name == "remove_PropertyChanged")
            {
                var propertyChangedEventHandler = info.Arguments[0] as PropertyChangedEventHandler;
                _changed -= propertyChangedEventHandler;
            }
            else
            {
                returnValue = base.Intercept(info);
            }

            if (!_entityHandlesPropertyChanged && info.TargetMethod.Name.StartsWith("set_"))
            {
                var propertyName = info.TargetMethod.Name.Substring("set_".Length);
                _changed(info.Target, new PropertyChangedEventArgs(propertyName));
            }

            return returnValue;
        }
		public object Intercept(InvocationInfo info)
		{
			var methodName = info.TargetMethod.Name;
			if (FieldInterceptor != null)
			{
				if (ReflectHelper.IsPropertyGet(info.TargetMethod))
				{
					if("get_FieldInterceptor".Equals(methodName))
					{
						return FieldInterceptor;
					}

					object propValue = info.InvokeMethodOnTarget();

					var result = FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), propValue);

					if (result != AbstractFieldInterceptor.InvokeImplementation)
					{
						return result;
					}
				}
				else if (ReflectHelper.IsPropertySet(info.TargetMethod))
				{
					if ("set_FieldInterceptor".Equals(methodName))
					{
						FieldInterceptor = (IFieldInterceptor)info.Arguments[0];
						return null;
					}
					FieldInterceptor.MarkDirty();
					FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), info.Arguments[0]);
				}
			}
			else
			{
				if ("set_FieldInterceptor".Equals(methodName))
				{
					FieldInterceptor = (IFieldInterceptor)info.Arguments[0];
					return null;
				}
			}

			object returnValue;
			try
			{
				returnValue = info.InvokeMethodOnTarget();
			}
			catch (TargetInvocationException ex)
			{
				throw ReflectHelper.UnwrapTargetInvocationException(ex);
			}
			return returnValue;
		}
		public object Intercept(InvocationInfo info)
		{
			var methodName = info.TargetMethod.Name;
			if (FieldInterceptor != null)
			{
				if (ReflectHelper.IsPropertyGet(info.TargetMethod))
				{
					if("get_FieldInterceptor".Equals(methodName))
					{
						return FieldInterceptor;
					}
					object propValue = info.TargetMethod.Invoke(TargetInstance, info.Arguments);

					var result = FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), propValue);

					if (result != AbstractFieldInterceptor.InvokeImplementation)
					{
						return result;
					}
				}
				else if (ReflectHelper.IsPropertySet(info.TargetMethod))
				{
					if ("set_FieldInterceptor".Equals(methodName))
					{
						FieldInterceptor = (IFieldInterceptor)info.Arguments[0];
						return null;
					}
					FieldInterceptor.MarkDirty();
					FieldInterceptor.Intercept(info.Target, ReflectHelper.GetPropertyName(info.TargetMethod), info.Arguments[0]);
				}
			}
			else
			{
				if ("set_FieldInterceptor".Equals(methodName))
				{
					FieldInterceptor = (IFieldInterceptor)info.Arguments[0];
					return null;
				}
			}

			var targetMethod = info.TargetMethod;
			if (targetMethod.IsGenericMethodDefinition && info.TypeArguments != null && info.TypeArguments.Length > 0)
			{
				targetMethod = targetMethod.MakeGenericMethod(info.TypeArguments);
			}
			return targetMethod.Invoke(TargetInstance, info.Arguments);
		}
		public object Intercept(InvocationInfo info)
		{
			object returnValue;
			try
			{
				returnValue = base.Invoke(info.TargetMethod, info.Arguments, info.Target);

				// Avoid invoking the actual implementation, if possible
				if (returnValue != InvokeImplementation)
				{
					return returnValue;
				}

				returnValue = info.TargetMethod.Invoke(GetImplementation(), info.Arguments);
			}
			catch (TargetInvocationException ex)
			{
				throw ReflectHelper.UnwrapTargetInvocationException(ex);
			}

			return returnValue;
		}
		public object Intercept(InvocationInfo info)
		{
			object returnValue;
			try
			{
				returnValue = base.Invoke(info.TargetMethod, info.Arguments, info.Target);

				// Avoid invoking the actual implementation, if possible
				if (returnValue != InvokeImplementation)
				{
					return returnValue;
				}

				returnValue = info.TargetMethod.Invoke(GetImplementation(), info.Arguments);
			}
			catch (TargetInvocationException ex)
			{
				exceptionInternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] {});
				throw ex.InnerException;
			}

			return returnValue;
		}
			public object Intercept(InvocationInfo info)
			{
				interceptedMethods.Add(info.TargetMethod.Name);
				return true;
			}
		public object Intercept(InvocationInfo info)
		{
			return info.TargetMethod.Invoke(targetInstance, info.Arguments);
		}