/// <summary>
		/// Perform the actual configuration.
		/// </summary>
		/// <param name="config">The object to configure.</param>
		/// <param name="args">The args passed to the object.</param>
		/// <param name="options">The options to use when configuring the object, can be null.</param>
		/// <returns>True if configuration was successful, otherwise false.</returns>
		public static bool Configure(object config, string[] args, ConfiguratorOptions options = null)
		{
			if (options == null)
				options = ConfiguratorOptions.Default;
			var tree = new ConfigTree(config.GetType(), options);
			args = SeperateArgs(args, tree, options);

			List<ConfigItem> UnknownItems = new List<ConfigItem>();
			int i = 0;
			for (; i < args.Length; i += 2)
			{
				string s = options.CleanupArgumentName(args[i]);
				ConfigTree.ConfigTreeNode n;
				if (!tree.NodeMap.TryGetValue(s, out n))
				{
					UnknownItems.Add(new ConfigItem(s, args[i + 1]));
				}
				else
				{
					n.AssignValue(config, args[i + 1]);
				}
			}
			if (i != args.Length)
			{
#warning need to give proper error here.
				throw new Exception();
			}
			foreach (var v in tree.Nodes)
			{
				if (!v.Assigned)
					v.AssignDefault(config);
			}
			if (UnknownItems.Count > 0 && config is IManuallyConfigurable)
			{
				var v = ((IManuallyConfigurable)config).ManuallyConfigure(UnknownItems);
#warning Need to give a better error here.
				if (v.Count > 0)
					throw new Exception("We have args we don't know what to do with :(");
			}

			return true;
		}
		private static string[] SeperateArgs(string[] args, ConfigTree tree, ConfiguratorOptions opts)
		{
			List<string> ret = new List<string>(args.Length);

			for (int i = 0; i < args.Length; i++)
			{
				string s = args[i];
				int lowestIdx = -1;
				foreach (char c in opts.AssignmentChars)
				{
					int idx = s.IndexOf(c);
					if (idx != -1 && (lowestIdx == -1 || idx < lowestIdx))
						lowestIdx = idx;
				}
				if (lowestIdx != -1)
				{
					ret.Add(s.Substring(0, lowestIdx));
					ret.Add(s.Substring(lowestIdx + 1, s.Length - lowestIdx - 1));
				}
				else
				{
					string s2 = opts.CleanupArgumentName(s);
					bool t = s2.StartsWith("enable");
					bool f = s2.StartsWith("disable");
					if (!t && !f)
					{
						ret.Add(s);
					}
					else
					{
						if (t)
						{
							ret.Add(s2.Substring(6));
							ret.Add("true");
						}
						else
						{
							ret.Add(s2.Substring(7));
							ret.Add("false");
						}
					}
				}
			}

			return ret.ToArray();
		}
			public ConfigTree(Type objType, ConfiguratorOptions opts)
			{
				AddTypeChildren(objType);
				foreach (var n in Nodes)
				{
					NodeMap.Add(opts.CleanupArgumentName(n.Name), n);
					n.Names.ForEach(s => NodeMap.Add(opts.CleanupArgumentName(s), n));
				}
			}