/// <summary>
		/// Assigns a new name to a configuration. 
		/// </summary>
		/// <param name="old">The old name of the target configuration.</param>
		/// <param name="newname">The new name of the target configuration.</param>
		/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
		public virtual int RenameCfgsOfCfgName(string old, string newname)
		{
			// First create the condition that represent the configuration we want to rename
			string condition = String.Format(CultureInfo.InvariantCulture, configString, old).Trim();

			foreach (var config in this.project.BuildProject.Xml.PropertyGroups)
			{
				// Only care about conditional property groups
				if (config.Condition == null || config.Condition.Length == 0)
					continue;

				var configCanonicalName = ConfigCanonicalName.OfCondition(config.Condition);
				// Skip if it isn't the group we want
				if (!configCanonicalName.MatchesConfigName(old))
					continue;

				var newCanonicalName = new ConfigCanonicalName(newname, configCanonicalName.Platform);
				// Change the name 
				config.Condition = newCanonicalName.ToMSBuildCondition();
				var propertyCollection = config.Properties;
				var outputPathProperty = propertyCollection.Where(p => p.Name == ProjectFileConstants.OutputPath).FirstOrDefault();
				if (outputPathProperty != null)
				{
					string outputBasePath = this.ProjectMgr.OutputBaseRelativePath;
					if (outputBasePath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
						outputBasePath = Path.GetDirectoryName(outputBasePath);
					var expectedOutputPathValue = Path.Combine(outputBasePath, old);
					if (String.Equals(expectedOutputPathValue, outputPathProperty.Value, StringComparison.OrdinalIgnoreCase))
					{
						var newOutputPathValue = Path.Combine(outputBasePath, newname);
						config.SetProperty(ProjectFileConstants.OutputPath, newOutputPathValue);
					}
				}
				// Update the name in our config list   
				if (configurationsList.ContainsKey(configCanonicalName))
				{
					ProjectConfig configuration = configurationsList[configCanonicalName];
					configurationsList.Remove(configCanonicalName);
					configurationsList.Add(newCanonicalName, configuration);
					// notify the configuration of its new name
					configuration.ConfigName = newname;
				}

			}
			NotifyOnCfgNameRenamed(old, newname);

			return VSConstants.S_OK;
		}
		/// <summary>
		/// Copies an existing platform name or creates a new one. 
		/// </summary>
		/// <param name="platformName">The name of the new platform.</param>
		/// <param name="clonePlatformName">The name of the platform to copy, or a null reference, indicating that AddCfgsOfPlatformName should create a new platform.</param>
		/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
		public virtual int AddCfgsOfPlatformName(string platformName, string clonePlatformName)
		{
			// We need to QE/QS the project file
			if (!this.ProjectMgr.QueryEditProjectFile(false))
			{
				throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
			}

			// Get all configs
			List<ProjectPropertyGroupElement> configGroup = new List<ProjectPropertyGroupElement>(this.project.BuildProject.Xml.PropertyGroups);
			// configName -> property group
			var configToClone = new Dictionary<string, ProjectPropertyGroupElement>(StringComparer.Ordinal);


			if (clonePlatformName != null)
			{
				// Find the configuration to clone
				foreach (var currentConfig in configGroup)
				{
					// Only care about conditional property groups
					if (currentConfig.Condition == null || currentConfig.Condition.Length == 0)
						continue;
					var configCanonicalName = ConfigCanonicalName.OfCondition(currentConfig.Condition);

					// Skip if it isn't the group we want
					if (!configCanonicalName.MatchesPlatform(clonePlatformName))
						continue;

					if (!configToClone.ContainsKey(configCanonicalName.ConfigName))
						configToClone.Add(configCanonicalName.ConfigName, currentConfig);
				}
			}


			var configNames = GetPropertiesConditionedOn(ProjectFileConstants.Configuration);
			if (configNames.Length == 0) return VSConstants.E_FAIL;

			foreach (var configName in configNames)
			{
				// If we have any property groups to clone, and we do not have sourec for this config, skip
				if (configToClone.Count > 0 && !configToClone.ContainsKey(configName)) continue;
				var newCanonicalName = new ConfigCanonicalName(configName, platformName);

				ProjectPropertyGroupElement newConfig = null;
				if (configToClone.ContainsKey(configName))
				{
					// Clone the configuration settings
					newConfig = this.project.ClonePropertyGroup(configToClone[configName]);
					foreach (ProjectPropertyElement property in newConfig.Properties)
					{
						if (property.Name.Equals(ProjectFileConstants.PlatformTarget, StringComparison.OrdinalIgnoreCase))
						{
							property.Parent.RemoveChild(property);
						}
					}

				}
				else
				{
					// no source to clone from, lets just create a new empty config
					PopulateEmptyConfig(ref newConfig);
					this.AddOutputPath(newConfig, configName);
				}

				newConfig.AddProperty(ProjectFileConstants.PlatformTarget, newCanonicalName.PlatformTarget);

				// Set the condition that will define the new configuration
				string newCondition = newCanonicalName.ToMSBuildCondition();
				newConfig.Condition = newCondition;
			}
			NotifyOnPlatformNameAdded(platformName);
			return VSConstants.S_OK;

		}