public void AddRangeOfIndexedArgumentValues()
        {
            ConstructorArgumentValues values = new ConstructorArgumentValues();

            values.AddIndexedArgumentValue(1, DBNull.Value);
            values.AddIndexedArgumentValue(2, "Foo");
            values.AddIndexedArgumentValue(3, 3);
            new ConstructorArgumentValues(values);
            Assert.IsFalse(values.Empty, "Added three indexed values(as a range), but the collection is sayin' it's empty.");
            Assert.AreEqual(3, values.ArgumentCount, "Added three indexed values(as a range), but the collection ain't sayin' that it's got 3 elements in it.");
            Assert.AreEqual(3, values.IndexedArgumentValues.Count, "Added three indexed values(as a range), but the collection of indexed values ain't sayin' that it's got 3 elements in it.");
        }
        public void AddAllFromOther()
        {
            ConstructorArgumentValues other = new ConstructorArgumentValues();

            other.AddIndexedArgumentValue(1, DBNull.Value);
            other.AddIndexedArgumentValue(2, "Foo");
            other.AddIndexedArgumentValue(3, 3);

            ConstructorArgumentValues values = new ConstructorArgumentValues();

            values.AddAll(other);
            Assert.AreEqual(other.ArgumentCount, values.ArgumentCount,
                            "Must have been the same since one was filled up with the values in the other.");
        }
        public void AddIndexedArgumentValue()
        {
            ConstructorArgumentValues values = new ConstructorArgumentValues();

            values.AddIndexedArgumentValue(1, DBNull.Value);
            Assert.IsFalse(values.Empty, "Added one value, but the collection is sayin' it's empty.");
            Assert.AreEqual(1, values.ArgumentCount, "Added one value, but the collection ain't sayin' that it's got a single element in it.");
            Assert.AreEqual(1, values.IndexedArgumentValues.Count, "Added one indexed value, but the collection of indexed values ain't sayin' that it's got a single element in it.");
        }
 private ConstructorArgumentValues getConstructorArgumentValues(TypeRegistration registrationEntry)
 {
    ConstructorArgumentValues constructorArgs = new ConstructorArgumentValues();
    int index = 0;
    foreach (ParameterValue constructorParameter in registrationEntry.ConstructorParameters)
    {
       constructorArgs.AddIndexedArgumentValue(index++,getInjectionParameterValue(constructorParameter));
    }
    
    return constructorArgs;
 }
        public void GetIndexedArgumentValue()
        {
            ConstructorArgumentValues values = new ConstructorArgumentValues();

            Assert.IsNull(values.GetIndexedArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an empty instance.");
            values.AddIndexedArgumentValue(16, DBNull.Value, typeof(DBNull).FullName);
            Assert.IsNull(values.GetIndexedArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an instance that should have now't at the specified index.");
            ConstructorArgumentValues.ValueHolder value =
                values.GetIndexedArgumentValue(16, typeof(DBNull));
            Assert.IsNotNull(value, "Stored a value at a specified index, but got null when retrieving it.");
            Assert.AreSame(DBNull.Value, value.Value, "The value stored at the specified index was not the exact same instance as was added.");
            ConstructorArgumentValues.ValueHolder wrongValue =
                values.GetIndexedArgumentValue(16, typeof(string));
            Assert.IsNull(wrongValue, "Stored a value at a specified index, and got it (or rather something) back when retrieving it with the wrong Type specified.");
        }
        public void GetArgumentValue()
        {
            ConstructorArgumentValues values = new ConstructorArgumentValues();

            Assert.IsNull(values.GetArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an empty instance.");
            values.AddGenericArgumentValue(DBNull.Value, typeof(DBNull).FullName);
            values.AddNamedArgumentValue("foo", DBNull.Value);
            values.AddIndexedArgumentValue(16, DBNull.Value, typeof(DBNull).FullName);
            Assert.IsNull(values.GetArgumentValue(100, typeof(string)), "Mmm... managed to get a non null instance back from an instance that should have now't with the specified Type.");
            ConstructorArgumentValues.ValueHolder value =
                values.GetArgumentValue(-3, typeof(DBNull));
            Assert.IsNotNull(value, "Stored a value of a specified Type at a specified index, but got null when retrieving it using the wrong index but the correct Type.");
            Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added.");

            value = values.GetArgumentValue("foo", typeof(DBNull));
            Assert.IsNotNull(value, "Stored a value of a specified Type under a name, but got null when retrieving it using the wrong name but the correct Type.");
            Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added.");
        }
        public void GetArgumentValueIgnoresAlreadyUsedValues()
        {
            ISet used = new ListSet();

            ConstructorArgumentValues values = new ConstructorArgumentValues();

            values.AddGenericArgumentValue(1);
            values.AddNamedArgumentValue("2", 2);
            values.AddIndexedArgumentValue(3, 3);

            Type intType = typeof(int);

            ConstructorArgumentValues.ValueHolder one = values.GetArgumentValue(10, string.Empty, intType, used);
            Assert.AreEqual(1, one.Value);
            used.Add(one);
            ConstructorArgumentValues.ValueHolder two = values.GetArgumentValue(10, "2", intType, used);
            Assert.AreEqual(2, two.Value);
            used.Add(two);
            ConstructorArgumentValues.ValueHolder three = values.GetArgumentValue(3, string.Empty, intType, used);
            Assert.AreEqual(3, three.Value);
            used.Add(three);
            ConstructorArgumentValues.ValueHolder four = values.GetArgumentValue(10, string.Empty, intType, used);
            Assert.IsNull(four);
        }
        public void CreateObjectWithMixOfNamedAndIndexedAndAutowiredCtorArguments()
        {
            string expectedCompany = "Griffin's Foosball Arcade";
            MutablePropertyValues autoProps = new MutablePropertyValues();
            autoProps.Add(new PropertyValue("Company", expectedCompany));
            RootObjectDefinition autowired = new RootObjectDefinition(typeof(NestedTestObject), autoProps);

            string expectedName = "Bingo";
            int expectedAge = 1023;
            ConstructorArgumentValues values = new ConstructorArgumentValues();
            values.AddNamedArgumentValue("age", expectedAge);
            values.AddIndexedArgumentValue(0, expectedName);
            RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), values, new MutablePropertyValues());
            def.AutowireMode = AutoWiringMode.Constructor;
            DefaultListableObjectFactory fac = new DefaultListableObjectFactory();
            fac.RegisterObjectDefinition("foo", def);
            fac.RegisterObjectDefinition("doctor", autowired);

            ITestObject foo = fac["foo"] as ITestObject;
            Assert.IsNotNull(foo, "Couldn't pull manually registered instance out of the factory.");
            Assert.AreEqual(expectedName, foo.Name, "Dependency 'name' was not resolved an indexed ctor arg.");
            Assert.AreEqual(expectedAge, foo.Age, "Dependency 'age' was not resolved using a named ctor arg.");
            Assert.AreEqual(expectedCompany, foo.Doctor.Company, "Dependency 'doctor.Company' was not resolved using autowiring.");
        }
		public void GetIndexedArgumentValue()
		{
			ConstructorArgumentValues values = new ConstructorArgumentValues();
			Assert.IsNull(values.GetIndexedArgumentValue(0, typeof (object)), "Mmm... managed to get a non null instance back from an empty instance.");
			values.AddIndexedArgumentValue(16, DBNull.Value, typeof (DBNull).FullName);
			Assert.IsNull(values.GetIndexedArgumentValue(0, typeof (object)), "Mmm... managed to get a non null instance back from an instance that should have now't at the specified index.");
			ConstructorArgumentValues.ValueHolder value =
				values.GetIndexedArgumentValue(16, typeof (DBNull));
			Assert.IsNotNull(value, "Stored a value at a specified index, but got null when retrieving it.");
			Assert.AreSame(DBNull.Value, value.Value, "The value stored at the specified index was not the exact same instance as was added.");
			ConstructorArgumentValues.ValueHolder wrongValue =
				values.GetIndexedArgumentValue(16, typeof (string));
			Assert.IsNull(wrongValue, "Stored a value at a specified index, and got it (or rather something) back when retrieving it with the wrong Type specified.");
		}
		public void GetArgumentValue()
		{
			ConstructorArgumentValues values = new ConstructorArgumentValues();
			Assert.IsNull(values.GetArgumentValue(0, typeof (object)), "Mmm... managed to get a non null instance back from an empty instance.");
			values.AddGenericArgumentValue(DBNull.Value, typeof (DBNull).FullName);
			values.AddNamedArgumentValue("foo", DBNull.Value);
			values.AddIndexedArgumentValue(16, DBNull.Value, typeof (DBNull).FullName);
			Assert.IsNull(values.GetArgumentValue(100, typeof (string)), "Mmm... managed to get a non null instance back from an instance that should have now't with the specified Type.");
			ConstructorArgumentValues.ValueHolder value =
				values.GetArgumentValue(-3, typeof (DBNull));
			Assert.IsNotNull(value, "Stored a value of a specified Type at a specified index, but got null when retrieving it using the wrong index but the correct Type.");
			Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added.");
			
			value = values.GetArgumentValue("foo", typeof (DBNull));
			Assert.IsNotNull(value, "Stored a value of a specified Type under a name, but got null when retrieving it using the wrong name but the correct Type.");
			Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added.");
		}
        /// <summary>
        /// Resolves the <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/>
        /// of the supplied <paramref name="definition"/>.
        /// </summary>
        /// <param name="objectName">The name of the object that is being resolved by this factory.</param>
        /// <param name="definition">The rod.</param>
        /// <param name="wrapper">The wrapper.</param>
        /// <param name="cargs">The cargs.</param>
        /// <param name="resolvedValues">Where the resolved constructor arguments will be placed.</param>
        /// <returns>
        /// The minimum number of arguments that any constructor for the supplied
        /// <paramref name="definition"/> must have.
        /// </returns>
        /// <remarks>
        /// 	<p>
        /// 'Resolve' can be taken to mean that all of the <paramref name="definition"/>s
        /// constructor arguments is resolved into a concrete object that can be plugged
        /// into one of the <paramref name="definition"/>s constructors. Runtime object
        /// references to other objects in this (or a parent) factory are resolved,
        /// type conversion is performed, etc.
        /// </p>
        /// 	<p>
        /// These resolved values are plugged into the supplied
        /// <paramref name="resolvedValues"/> object, because we wouldn't want to touch
        /// the <paramref name="definition"/>s constructor arguments in case it (or any of
        /// its constructor arguments) is a prototype object definition.
        /// </p>
        /// 	<p>
        /// This method is also used for handling invocations of static factory methods.
        /// </p>
        /// </remarks>
        private int ResolveConstructorArguments(string objectName, RootObjectDefinition definition, ObjectWrapper wrapper,
                                                ConstructorArgumentValues cargs,
                                                ConstructorArgumentValues resolvedValues)
        {
//            ObjectDefinitionValueResolver valueResolver = new ObjectDefinitionValueResolver(objectFactory);
            int minNrOfArgs = cargs.ArgumentCount;

            foreach (KeyValuePair<int, ConstructorArgumentValues.ValueHolder> entry in cargs.IndexedArgumentValues)
            {
                int index = Convert.ToInt32(entry.Key);
                if (index < 0)
                {
                    throw new ObjectCreationException(definition.ResourceDescription, objectName,
                                                      "Invalid constructor agrument index: " + index);
                }
                if (index > minNrOfArgs)
                {
                    minNrOfArgs = index + 1;
                }
                ConstructorArgumentValues.ValueHolder valueHolder = entry.Value;
                string argName = "constructor argument with index " + index;
                object resolvedValue =
                    valueResolver.ResolveValueIfNecessary(objectName, definition, argName, valueHolder.Value);
                resolvedValues.AddIndexedArgumentValue(index, resolvedValue,
                                                       StringUtils.HasText(valueHolder.Type)
                                                           ? TypeResolutionUtils.ResolveType(valueHolder.Type).
                                                                 AssemblyQualifiedName
                                                           : null);
            }

            foreach (ConstructorArgumentValues.ValueHolder valueHolder in definition.ConstructorArgumentValues.GenericArgumentValues)
            {
                string argName = "constructor argument";
                object resolvedValue =
                    valueResolver.ResolveValueIfNecessary(objectName, definition, argName, valueHolder.Value);
                resolvedValues.AddGenericArgumentValue(resolvedValue,
                                                       StringUtils.HasText(valueHolder.Type)
                                                           ? TypeResolutionUtils.ResolveType(valueHolder.Type).
                                                                 AssemblyQualifiedName
                                                           : null);
            }
            foreach (KeyValuePair<string, object> namedArgumentEntry in definition.ConstructorArgumentValues.NamedArgumentValues)
            {
                string argumentName = namedArgumentEntry.Key;
                string syntheticArgumentName = "constructor argument with name " + argumentName;
                ConstructorArgumentValues.ValueHolder valueHolder =
                    (ConstructorArgumentValues.ValueHolder)namedArgumentEntry.Value;
                object resolvedValue =
                    valueResolver.ResolveValueIfNecessary(objectName, definition, syntheticArgumentName, valueHolder.Value);
                resolvedValues.AddNamedArgumentValue(argumentName, resolvedValue);
            }
            return minNrOfArgs;
        }
        public void CreateObjectWithMixOfIndexedAndTwoNamedSameTypeCtorArguments()
        {
            // this object will be passed in as a named constructor argument
            string expectedCompany = "Griffin's Foosball Arcade";
            MutablePropertyValues autoProps = new MutablePropertyValues();
            autoProps.Add(new PropertyValue("Company", expectedCompany));
            RootObjectDefinition autowired = new RootObjectDefinition(typeof(NestedTestObject), autoProps);

            // this object will be passed in as a named constructor argument
            string expectedLawyersCompany = "Pollack, Pounce, & Pulverise";
            MutablePropertyValues lawyerProps = new MutablePropertyValues();
            lawyerProps.Add(new PropertyValue("Company", expectedLawyersCompany));
            RootObjectDefinition lawyer = new RootObjectDefinition(typeof(NestedTestObject), lawyerProps);

            // this simple string object will be passed in as an indexed constructor argument
            string expectedName = "Bingo";

            // this simple integer object will be passed in as a named constructor argument
            int expectedAge = 1023;

            ConstructorArgumentValues values = new ConstructorArgumentValues();

            // lets mix the order up a little...
            values.AddNamedArgumentValue("age", expectedAge);
            values.AddIndexedArgumentValue(0, expectedName);
            values.AddNamedArgumentValue("doctor", new RuntimeObjectReference("a_doctor"));
            values.AddNamedArgumentValue("lawyer", new RuntimeObjectReference("a_lawyer"));

            RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), values, new MutablePropertyValues());

            DefaultListableObjectFactory fac = new DefaultListableObjectFactory();
            // the object we're attempting to resolve...
            fac.RegisterObjectDefinition("foo", def);
            // the object that will be looked up and passed as a named parameter to a ctor call...
            fac.RegisterObjectDefinition("a_doctor", autowired);
            // another object that will be looked up and passed as a named parameter to a ctor call...
            fac.RegisterObjectDefinition("a_lawyer", lawyer);

            ITestObject foo = fac["foo"] as ITestObject;
            Assert.IsNotNull(foo, "Couldn't pull manually registered instance out of the factory.");
            Assert.AreEqual(expectedName, foo.Name, "Dependency 'name' was not resolved an indexed ctor arg.");
            Assert.AreEqual(expectedAge, foo.Age, "Dependency 'age' was not resolved using a named ctor arg.");
            Assert.AreEqual(expectedCompany, foo.Doctor.Company, "Dependency 'doctor.Company' was not resolved using autowiring.");
            Assert.AreEqual(expectedLawyersCompany, foo.Lawyer.Company, "Dependency 'lawyer.Company' was not resolved using another named ctor arg.");
        }
        /// <summary>
        /// Parse a constructor-arg element.
        /// </summary>
        /// <param name="name">
        /// The name of the object (definition) associated with the ctor arg.
        /// </param>
        /// <param name="arguments">
        /// The list of constructor args associated with the object (definition).
        /// </param>
        /// <param name="element">
        /// The name of the element containing the ctor arg definition.
        /// </param>
        /// <param name="parserContext">
        /// The namespace-aware parser.
        /// </param>
        protected virtual void ParseConstructorArgElement(
            string name, ConstructorArgumentValues arguments, XmlElement element, ParserContext parserContext)
        {
            object val = ParsePropertyValue(element, name, parserContext);
            string indexAttr = GetAttributeValue(element, ObjectDefinitionConstants.IndexAttribute);
            string typeAttr = GetAttributeValue(element, ObjectDefinitionConstants.TypeAttribute);
            string nameAttr = GetAttributeValue(element, ObjectDefinitionConstants.ArgumentNameAttribute);

            // only one of the 'index' or 'name' attributes can be present
            if (StringUtils.HasText(indexAttr)
                && StringUtils.HasText(nameAttr))
            {
                throw new ObjectDefinitionStoreException(
                    parserContext.ReaderContext.Resource, name,
                    "Only one of the 'index' or 'name' attributes can be present per constructor argument.");
            }
            if (StringUtils.HasText(indexAttr))
            {
                try
                {
                    int index = int.Parse(indexAttr, CultureInfo.CurrentCulture);
                    if (index < 0)
                    {
                        throw new ObjectDefinitionStoreException(
                            parserContext.ReaderContext.Resource, name,
                            "'index' cannot be lower than 0");
                    }
                    if (StringUtils.HasText(typeAttr))
                    {
                        arguments.AddIndexedArgumentValue(index, val, typeAttr);
                    }
                    else
                    {
                        arguments.AddIndexedArgumentValue(index, val);
                    }
                }
                catch (FormatException)
                {
                    throw new ObjectDefinitionStoreException(
                        parserContext.ReaderContext.Resource, name,
                        "Attribute 'index' of tag 'constructor-arg' must be an integer value.");
                }
            }
            else if (StringUtils.HasText(nameAttr))
            {
                if (StringUtils.HasText(typeAttr))
                {
                    if (log.IsWarnEnabled)
                    {
                        log.Warn("The 'type' attribute is redundant when the 'name' attribute has been used on a constructor argument element.");
                    }
                }
                arguments.AddNamedArgumentValue(nameAttr, val);
            }
            else
            {
                if (StringUtils.HasText(typeAttr))
                {
                    arguments.AddGenericArgumentValue(val, typeAttr);
                }
                else
                {
                    arguments.AddGenericArgumentValue(val);
                }
            }
        }
        public void CreateObjectWithMixOfNamedAndIndexedCtorArguments()
        {
            string expectedName = "Bingo";
            int expectedAge = 1023;
            ConstructorArgumentValues values = new ConstructorArgumentValues();
            values.AddNamedArgumentValue("age", expectedAge);
            values.AddIndexedArgumentValue(0, expectedName);
            RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), values, new MutablePropertyValues());
            DefaultListableObjectFactory fac = new DefaultListableObjectFactory();
            fac.RegisterObjectDefinition("foo", def);

            ITestObject foo = fac["foo"] as ITestObject;
            Assert.IsNotNull(foo, "Couldn't pull manually registered instance out of the factory.");
            Assert.AreEqual(expectedName, foo.Name, "Dependency 'name' was not resolved an indexed ctor arg.");
            Assert.AreEqual(expectedAge, foo.Age, "Dependency 'age' was not resolved using a named ctor arg.");
        }
		public void AddIndexedArgumentValue()
		{
			ConstructorArgumentValues values = new ConstructorArgumentValues();
			values.AddIndexedArgumentValue(1, DBNull.Value);
			Assert.IsFalse(values.Empty, "Added one value, but the collection is sayin' it's empty.");
			Assert.AreEqual(1, values.ArgumentCount, "Added one value, but the collection ain't sayin' that it's got a single element in it.");
			Assert.AreEqual(1, values.IndexedArgumentValues.Count, "Added one indexed value, but the collection of indexed values ain't sayin' that it's got a single element in it.");
		}
        public void SunnyDay()
        {
            StaticApplicationContext ac = new StaticApplicationContext();


            MutablePropertyValues pvs = new MutablePropertyValues();

            pvs.Add("age", "${age}");
            RootObjectDefinition def
                = new RootObjectDefinition("${fqn}", new ConstructorArgumentValues(), pvs);

            ac.RegisterObjectDefinition("tb3", def);



            pvs = new MutablePropertyValues();
            pvs.Add("age", "${age}");
            pvs.Add("name", "name${var}${");
            pvs.Add("spouse", new RuntimeObjectReference("${ref}"));
            ac.RegisterSingleton("tb1", typeof(TestObject), pvs);

            ConstructorArgumentValues cas = new ConstructorArgumentValues();

            cas.AddIndexedArgumentValue(1, "${age}");
            cas.AddGenericArgumentValue("${var}name${age}");

            pvs = new MutablePropertyValues();
            ArrayList friends = new ManagedList();

            friends.Add("na${age}me");
            friends.Add(new RuntimeObjectReference("${ref}"));
            pvs.Add("friends", friends);

            ISet someSet = new ManagedSet();

            someSet.Add("na${age}me");
            someSet.Add(new RuntimeObjectReference("${ref}"));
            pvs.Add("someSet", someSet);

            IDictionary someDictionary = new ManagedDictionary();

            someDictionary["key1"] = new RuntimeObjectReference("${ref}");
            someDictionary["key2"] = "${age}name";
            MutablePropertyValues innerPvs = new MutablePropertyValues();

            someDictionary["key3"] = new RootObjectDefinition(typeof(TestObject), innerPvs);
            someDictionary["key4"] = new ChildObjectDefinition("tb1", innerPvs);
            pvs.Add("someMap", someDictionary);

            RootObjectDefinition definition = new RootObjectDefinition(typeof(TestObject), cas, pvs);

            ac.DefaultListableObjectFactory.RegisterObjectDefinition("tb2", definition);

            pvs = new MutablePropertyValues();
            pvs.Add("Properties", "<spring-config><add key=\"age\" value=\"98\"/><add key=\"var\" value=\"${m}var\"/><add key=\"ref\" value=\"tb2\"/><add key=\"m\" value=\"my\"/><add key=\"fqn\" value=\"Spring.Objects.TestObject, Spring.Core.Tests\"/></spring-config>");
            ac.RegisterSingleton("configurer", typeof(PropertyPlaceholderConfigurer), pvs);
            ac.Refresh();

            TestObject tb1 = (TestObject)ac.GetObject("tb1");
            TestObject tb2 = (TestObject)ac.GetObject("tb2");
            TestObject tb3 = (TestObject)ac.GetObject("tb3");

            Assert.AreEqual(98, tb1.Age);
            Assert.AreEqual(98, tb2.Age);
            Assert.AreEqual(98, tb3.Age);
            Assert.AreEqual("namemyvar${", tb1.Name);
            Assert.AreEqual("myvarname98", tb2.Name);
            Assert.AreEqual(tb2, tb1.Spouse);
            Assert.AreEqual(2, tb2.Friends.Count);
            IEnumerator ie = tb2.Friends.GetEnumerator();

            ie.MoveNext();
            Assert.AreEqual("na98me", ie.Current);
            ie.MoveNext();
            Assert.AreEqual(tb2, ie.Current);
            Assert.AreEqual(2, tb2.SomeSet.Count);
            Assert.IsTrue(tb2.SomeSet.Contains("na98me"));
            Assert.IsTrue(tb2.SomeSet.Contains(tb2));
            Assert.AreEqual(4, tb2.SomeMap.Count);
            Assert.AreEqual(tb2, tb2.SomeMap["key1"]);
            Assert.AreEqual("98name", tb2.SomeMap["key2"]);
            TestObject inner1 = (TestObject)tb2.SomeMap["key3"];
            TestObject inner2 = (TestObject)tb2.SomeMap["key4"];

            Assert.AreEqual(0, inner1.Age);
            Assert.AreEqual(null, inner1.Name);
            Assert.AreEqual(98, inner2.Age);
            Assert.AreEqual("namemyvar${", inner2.Name);
        }
        public void SunnyDay()
        {
            StaticApplicationContext ac = new StaticApplicationContext();

            MutablePropertyValues pvs = new MutablePropertyValues();
            pvs.Add("age", "${age}");
            RootObjectDefinition def
                = new RootObjectDefinition("${fqn}", new ConstructorArgumentValues(), pvs);
            ac.RegisterObjectDefinition("tb3", def);

            pvs = new MutablePropertyValues();
            pvs.Add("age", "${age}");
            pvs.Add("name", "name${var}${");
            pvs.Add("spouse", new RuntimeObjectReference("${ref}"));
            ac.RegisterSingleton("tb1", typeof (TestObject), pvs);

            ConstructorArgumentValues cas = new ConstructorArgumentValues();
            cas.AddIndexedArgumentValue(1, "${age}");
            cas.AddGenericArgumentValue("${var}name${age}");

            pvs = new MutablePropertyValues();
            ArrayList friends = new ManagedList();
            friends.Add("na${age}me");
            friends.Add(new RuntimeObjectReference("${ref}"));
            pvs.Add("friends", friends);

            ISet someSet = new ManagedSet();
            someSet.Add("na${age}me");
            someSet.Add(new RuntimeObjectReference("${ref}"));
            pvs.Add("someSet", someSet);

            IDictionary someDictionary = new ManagedDictionary();
            someDictionary["key1"] = new RuntimeObjectReference("${ref}");
            someDictionary["key2"] = "${age}name";
            MutablePropertyValues innerPvs = new MutablePropertyValues();
            someDictionary["key3"] = new RootObjectDefinition(typeof (TestObject), innerPvs);
            someDictionary["key4"] = new ChildObjectDefinition("tb1", innerPvs);
            pvs.Add("someMap", someDictionary);

            RootObjectDefinition definition = new RootObjectDefinition(typeof (TestObject), cas, pvs);
            ac.DefaultListableObjectFactory.RegisterObjectDefinition("tb2", definition);

            pvs = new MutablePropertyValues();
            pvs.Add("Properties", "<spring-config><add key=\"age\" value=\"98\"/><add key=\"var\" value=\"${m}var\"/><add key=\"ref\" value=\"tb2\"/><add key=\"m\" value=\"my\"/><add key=\"fqn\" value=\"Spring.Objects.TestObject, Spring.Core.Tests\"/></spring-config>");
            ac.RegisterSingleton("configurer", typeof (PropertyPlaceholderConfigurer), pvs);
            ac.Refresh();

            TestObject tb1 = (TestObject) ac.GetObject("tb1");
            TestObject tb2 = (TestObject) ac.GetObject("tb2");
            TestObject tb3 = (TestObject) ac.GetObject("tb3");
            Assert.AreEqual(98, tb1.Age);
            Assert.AreEqual(98, tb2.Age);
            Assert.AreEqual(98, tb3.Age);
            Assert.AreEqual("namemyvar${", tb1.Name);
            Assert.AreEqual("myvarname98", tb2.Name);
            Assert.AreEqual(tb2, tb1.Spouse);
            Assert.AreEqual(2, tb2.Friends.Count);
            IEnumerator ie = tb2.Friends.GetEnumerator();
            ie.MoveNext();
            Assert.AreEqual("na98me", ie.Current);
            ie.MoveNext();
            Assert.AreEqual(tb2, ie.Current);
            Assert.AreEqual(2, tb2.SomeSet.Count);
            Assert.IsTrue(tb2.SomeSet.Contains("na98me"));
            Assert.IsTrue(tb2.SomeSet.Contains(tb2));
            Assert.AreEqual(4, tb2.SomeMap.Count);
            Assert.AreEqual(tb2, tb2.SomeMap["key1"]);
            Assert.AreEqual("98name", tb2.SomeMap["key2"]);
            TestObject inner1 = (TestObject) tb2.SomeMap["key3"];
            TestObject inner2 = (TestObject) tb2.SomeMap["key4"];
            Assert.AreEqual(0, inner1.Age);
            Assert.AreEqual(null, inner1.Name);
            Assert.AreEqual(98, inner2.Age);
            Assert.AreEqual("namemyvar${", inner2.Name);
        }
		public void GetArgumentValueIgnoresAlreadyUsedValues()
		{
			ISet used = new ListSet();

			ConstructorArgumentValues values = new ConstructorArgumentValues();
			values.AddGenericArgumentValue(1);
			values.AddNamedArgumentValue("2", 2);
			values.AddIndexedArgumentValue(3, 3);

			Type intType = typeof (int);
			ConstructorArgumentValues.ValueHolder one = values.GetArgumentValue(10, string.Empty, intType, used);
			Assert.AreEqual(1, one.Value);
			used.Add(one);
			ConstructorArgumentValues.ValueHolder two = values.GetArgumentValue(10, "2", intType, used);
			Assert.AreEqual(2, two.Value);
			used.Add(two);
			ConstructorArgumentValues.ValueHolder three = values.GetArgumentValue(3, string.Empty, intType, used);
			Assert.AreEqual(3, three.Value);
			used.Add(three);
			ConstructorArgumentValues.ValueHolder four = values.GetArgumentValue(10, string.Empty, intType, used);
			Assert.IsNull(four);
		}
		public void AddRangeOfIndexedArgumentValues()
		{
			ConstructorArgumentValues values = new ConstructorArgumentValues();
			values.AddIndexedArgumentValue(1, DBNull.Value);
			values.AddIndexedArgumentValue(2, "Foo");
			values.AddIndexedArgumentValue(3, 3);
			new ConstructorArgumentValues(values);
			Assert.IsFalse(values.Empty, "Added three indexed values(as a range), but the collection is sayin' it's empty.");
			Assert.AreEqual(3, values.ArgumentCount, "Added three indexed values(as a range), but the collection ain't sayin' that it's got 3 elements in it.");
			Assert.AreEqual(3, values.IndexedArgumentValues.Count, "Added three indexed values(as a range), but the collection of indexed values ain't sayin' that it's got 3 elements in it.");
		}
		public void AddAllFromOther()
		{
			ConstructorArgumentValues other = new ConstructorArgumentValues();
			other.AddIndexedArgumentValue(1, DBNull.Value);
			other.AddIndexedArgumentValue(2, "Foo");
			other.AddIndexedArgumentValue(3, 3);

			ConstructorArgumentValues values = new ConstructorArgumentValues();
			values.AddAll(other);
			Assert.AreEqual(other.ArgumentCount, values.ArgumentCount,
				"Must have been the same since one was filled up with the values in the other.");
		}