/// <summary>
        ///     The on perpare.
        /// </summary>
        /// <param name="context">
        ///     The context.
        /// </param>
        public override void OnPerpare(IBuildContext context)
        {
            if (!context.CanUseBuildUp()) return;

            context.ErrorTracer.Phase = "Reciving Interception Informations for " + context.Metadata;

            var contextPolicy = new ObjectContextPolicy
            {
                ContextName =
                    context.Metadata.Metadata.TryGetAndCast<string>(
                        AopConstants.ContextMetadataName)
            };

            foreach (MemberInfo memberInfo in context.ExportType.GetMembers(AopConstants.DefaultBindingFlags))
            {
                Contract.Assume(memberInfo != null);

                ObjectContextPropertyAttribute[] attrs =
                    memberInfo.GetAllCustomAttributes<ObjectContextPropertyAttribute>();
                foreach (ObjectContextPropertyAttribute objectContextPropertyAttribute in attrs) contextPolicy.ContextPropertys.Add(Tuple.Create(objectContextPropertyAttribute, memberInfo));
            }

            context.Policys.Add(contextPolicy);

            var attr = context.Metadata.Metadata.TryGetAndCast<InterceptAttribute>(AopConstants.InterceptMetadataName);

            object meta;
            if (context.Metadata.Metadata.TryGetValue("IgnoreIntercepion", out meta))
            {
                try
                {
                    if((bool)meta)
                        return;
                }
                catch (InvalidCastException)
                {
                }
            }

            if (attr == null) return;

            var policy = new InterceptionPolicy {InterceptAttribute = attr};
            IInterceptor temp = attr.Create();
            if (temp != null) policy.MemberInterceptor.Add(new KeyValuePair<MemberInterceptionAttribute, IInterceptor>(null, temp));

            foreach (MemberInterceptionAttribute attribute in
                context.ExportType.GetAllCustomAttributes<MemberInterceptionAttribute>())
            {
                policy.MemberInterceptor.Add(
                    new KeyValuePair<MemberInterceptionAttribute, IInterceptor>(
                        attribute,
                        attribute.Create(context.ExportType)));
            }

            foreach (MemberInfo member in context.ExportType.GetMembers(AopConstants.DefaultBindingFlags))
            {
                Contract.Assume(member != null);

                MemberInterceptionAttribute[] intattrs = member.GetAllCustomAttributes<MemberInterceptionAttribute>();
                foreach (MemberInterceptionAttribute interceptionAttribute in intattrs)
                {
                    Contract.Assert(interceptionAttribute != null);

                    IInterceptor temp2 = interceptionAttribute.Create(member);
                    policy.MemberInterceptor.Add(
                        new KeyValuePair<MemberInterceptionAttribute, IInterceptor>(
                            interceptionAttribute, temp2));
                }
            }

            context.Policys.Add(policy);
        }
        /// <summary>
        ///     The on build.
        /// </summary>
        /// <param name="context">
        ///     The context.
        /// </param>
        public override void OnBuild(IBuildContext context)
        {
            if (!context.CanUseBuildUp()) return;

            context.ErrorTracer.Phase = "Setting up ObjectContext for " + context.Metadata;

            var contextPolicy = context.Policys.Get<ObjectContextPolicy>();

            Contract.Assume(contextPolicy != null);

            ObjectContext objectContext;

            string name = contextPolicy.ContextName;
            if (name != null) objectContext = ContextManager.GetContext(name, context.Target);
            else
            {
                var holder = context.Target as IContextHolder;
                name = Guid.NewGuid().ToString();

                if (holder != null)
                {
                    if (holder.Context == null) holder.Context = ContextManager.GetContext(name, context.Target);

                    objectContext = holder.Context;
                }
                else
                {
                    object obj = context.Target;
                    Contract.Assume(obj != null);

                    objectContext = ContextManager.GetContext(name, obj);
                }
            }

            foreach (var contextProperty in contextPolicy.ContextPropertys) contextProperty.Item1.Register(objectContext, contextProperty.Item2, context.Target);

            var policy = context.Policys.Get<InterceptionPolicy>();

            if (policy == null || context.Target == null) return;

            var options = new ProxyGenerationOptions {Selector = new InternalInterceptorSelector()};

            try
            {
                if (ProxyUtil.IsProxy(context.Target)) return;

                context.ErrorTracer.Phase = "Creating Proxy with Target for " + context.Metadata;

                lock (_generator)
                {
                    context.Target = _generator.CreateClassProxyWithTarget(
                        context.ExportType,
                        context.Target,
                        options,
                        policy.MemberInterceptor.Select(
                            mem =>
                            mem.Value)
                              .ToArray());
                }
            }
            finally
            {
                foreach (MemberInterceptionAttribute result in
                    policy.MemberInterceptor.Select(mem => mem.Key).Where(attr => attr != null)) result.Initialize(context.Target, objectContext, name);
            }
        }
        /// <summary>
        ///     The on perpare.
        /// </summary>
        /// <param name="context">
        ///     The context.
        /// </param>
        public override void OnPerpare(IBuildContext context)
        {
            if (!context.CanUseBuildUp()) return;

            context.ErrorTracer.Phase = "Loading Injections for " + context.Metadata;

            MemberInfo[] members = context.ExportType.GetMembers(AopConstants.DefaultBindingFlags);

            List<IImportInterceptor> importInterceptors = null;
            var intpol = context.Policys.Get<ExternalImportInterceptorPolicy>();
            if (intpol != null) importInterceptors = intpol.Interceptors;

            foreach (
                var temp in
                    _interceptorFactories.Select(
                        importInterceptorFactory => importInterceptorFactory.CreateInterceptor(context.Metadata))
                                         .Where(temp => temp != null))
            {
                if (importInterceptors == null) importInterceptors = new List<IImportInterceptor> {temp};
                else importInterceptors.Add(temp);
            }

            foreach (ImportMetadata importMetadata in context.Metadata.Export.ImportMetadata)
            {
                var policy = new InjectMemberPolicy {Metadata = importMetadata, Interceptors = importInterceptors};

                MemberInfo info = members.FirstOrDefault(inf => inf.Name == importMetadata.MemberName);
                if (info == null) continue;

                switch (info.MemberType)
                {
                    case MemberTypes.Event:
                        policy.Injector = new EventMemberInjector(importMetadata, _eventManager, info);
                        break;
                    case MemberTypes.Field:
                        policy.Injector = new FieldInjector(_factory, (FieldInfo) info, context.ResolverExtensions);
                        break;
                    case MemberTypes.Property:
                        policy.Injector = new PropertyInjector(_factory, (PropertyInfo) info, context.ResolverExtensions);
                        break;
                    case MemberTypes.Method:
                        policy.Injector = new MethodInjector((MethodInfo) info, _factory, _eventManager, context.ResolverExtensions);
                        break;
                }

                context.Policys.Add(policy);
            }
        }