//        /// <summary>
//        /// Create an object instance for the given object definition.
//        /// </summary>
//        /// <param name="name">The name of the object.</param>
//        /// <param name="definition">
//        /// The object definition for the object that is to be instantiated.
//        /// </param>
//        /// <param name="arguments">
//        /// The arguments to use if creating a prototype using explicit arguments to
//        /// a static factory method. It is invalid to use a non-<see langword="null"/> arguments value
//        /// in any other case.
//        /// </param>
//        /// <returns>
//        /// A new instance of the object.
//        /// </returns>
//        /// <exception cref="Spring.Objects.ObjectsException">
//        /// In case of errors.
//        /// </exception>
//        /// <remarks>
//        /// <p>
//        /// Delegates to the
//        /// <see cref="Spring.Objects.Factory.Support.AbstractAutowireCapableObjectFactory.CreateObject (string,RootObjectDefinition,object[],bool)"/>
//        /// method version with the <c>allowEagerCaching</c> parameter set to <b>true</b>.
//        /// </p>
//        /// <p>
//        /// The object definition will already have been merged with the parent
//        /// definition in case of a child definition.
//        /// </p>
//        /// <p>
//        /// All the other methods in this class invoke this method, although objects
//        /// may be cached after being instantiated by this method. All object
//        /// instantiation within this class is performed by this method.
//        /// </p>
//        /// </remarks>
//        protected internal override object CreateObject(string name, RootObjectDefinition definition, object[] arguments)
//        {
//            return CreateObject(name, definition, arguments, true, false);
//        }

        /// <summary>
        /// Create an object instance for the given object definition.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <param name="definition">
        /// The object definition for the object that is to be instantiated.
        /// </param>
        /// <param name="arguments">
        /// The arguments to use if creating a prototype using explicit arguments to
        /// a static factory method. It is invalid to use a non-<see langword="null"/> arguments value
        /// in any other case.
        /// </param>
        /// <param name="allowEagerCaching">
        /// Whether eager caching of singletons is allowed... typically true for
        /// singlton objects, but never true for inner object definitions.
        /// </param>
        /// <param name="suppressConfigure">
        /// Suppress injecting dependencies yet.
        /// </param>
        /// <returns>
        /// A new instance of the object.
        /// </returns>
        /// <exception cref="Spring.Objects.ObjectsException">
        /// In case of errors.
        /// </exception>
        /// <remarks>
        /// <p>
        /// The object definition will already have been merged with the parent
        /// definition in case of a child definition.
        /// </p>
        /// <p>
        /// All the other methods in this class invoke this method, although objects
        /// may be cached after being instantiated by this method. All object
        /// instantiation within this class is performed by this method.
        /// </p>
        /// </remarks>
        protected internal override object InstantiateObject(string name, RootObjectDefinition definition, object[] arguments, bool allowEagerCaching, bool suppressConfigure)
        {
            // guarantee the initialization of objects that the current one depends on..
            if (definition.DependsOn != null && definition.DependsOn.Length > 0)
            {
                foreach (string dependant in definition.DependsOn)
                {
                    GetObject(dependant);
                }
            }

            #region Instrumentation

            if (log.IsDebugEnabled)
            {
                log.Debug(string.Format(CultureInfo.InvariantCulture, "Creating instance of Object '{0}' with merged definition [{1}].", name, definition));
            }

            #endregion

            // Make sure object type is actually resolved at this point.
            ResolveObjectType(definition, name);

            try
            {
                definition.PrepareMethodOverrides();
            }
            catch (ObjectDefinitionValidationException ex)
            {
                throw new ObjectDefinitionStoreException(definition.ResourceDescription, name,
                                                         "Validation of method overrides failed.  " + ex.Message, ex);
            }

            // return IObjectDefinition instance itself for an abstract object-definition
            if (definition.IsTemplate)
            {
                return definition;
            }



            object instance = null;


            IObjectWrapper instanceWrapper = null;
            bool eagerlyCached = false;
            try
            {
                // Give IInstantiationAwareObjectPostProcessors a chance to return a proxy instead of the target instance....
                if (definition.HasObjectType)
                {
                    instance = ApplyObjectPostProcessorsBeforeInstantiation(definition.ObjectType, name);
                    if (instance != null)
                    {
                        return instance;
                    }
                }


                instanceWrapper = CreateObjectInstance(name, definition, arguments);
                instance = instanceWrapper.WrappedInstance;

                // eagerly cache singletons to be able to resolve circular references
                // even when triggered by lifecycle interfaces like IObjectFactoryAware.
                if (allowEagerCaching && definition.IsSingleton)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Eagerly caching object '" + name + "' to allow for resolving potential circular references");
                    }
                    AddEagerlyCachedSingleton(name, definition, instance);
                    eagerlyCached = true;
                }

                if (!suppressConfigure)
                {
                    instance = ConfigureObject(name, definition, instanceWrapper);
                }
            }
            catch (ObjectCreationException)
            {
                if (eagerlyCached)
                {
                    RemoveEagerlyCachedSingleton(name, definition);
                }
                throw;
            }
            catch (Exception ex)
            {
                if (eagerlyCached)
                {
                    RemoveEagerlyCachedSingleton(name, definition);
                }
                throw new ObjectCreationException(definition.ResourceDescription, name, "Initialization of object failed : " + ex.Message, ex);
            }
            return instance;
        }