Encapsulates working with shader archive files.
		/// <summary>
		/// Edits the specified game specific value.
		/// </summary>
		/// <remarks>
		/// This method writes the given value in the specified game specific value, if it
		/// is owned by the mod being upgraded. If the specified edit is not owned by the
		/// mod being upgraded, the edit is archived in the install log.
		/// 
		/// If the edit was not previously installed by the mod, then the normal install
		/// rules apply, including confirming overwrite if applicable.
		/// </remarks>
		/// <param name="p_strKey">The key of the edited Game Specific Value.</param>
		/// <param name="p_bteValue">The value to install.</param>
		/// <returns><c>true</c> if the value was set; <c>false</c> otherwise.</returns>
		public override bool EditGameSpecificValue(string p_strKey, byte[] p_bteValue)
		{
			IList<IMod> lstInstallers = InstallLog.GetGameSpecificValueEditInstallers(p_strKey);
			if (lstInstallers.Contains(Mod, ModComparer.Filename))
			{
				if (!ModComparer.Filename.Equals(lstInstallers[lstInstallers.Count - 1], Mod))
					InstallLog.ReplaceGameSpecificValueEdit(Mod, p_strKey, p_bteValue);
				else
				{
					ShaderEdit sedShader = new ShaderEdit(p_strKey);
					SDPArchives sdpManager = new SDPArchives(GameModeInfo, FileUtility);
					if (!TouchedFiles.Contains(sdpManager.GetPath(sedShader.Package)))
					{
						TouchedFiles.Add(sdpManager.GetPath(sedShader.Package));
						TransactionalFileManager.Snapshot(sdpManager.GetPath(sedShader.Package));
					}
					byte[] oldData;
					if (!sdpManager.EditShader(sedShader.Package, sedShader.ShaderName, p_bteValue, out oldData))
						throw new Exception("Failed to edit the shader");
				}
				OriginallyInstalledEdits.Remove(p_strKey);
				return true;
			}

			return base.EditGameSpecificValue(p_strKey, p_bteValue);
		}
		/// <summary>
		/// Undoes the edit made to the specified game specific value.
		/// </summary>
		/// <param name="p_strKey">The key of the edited Game Specific Value.</param>
		public void UnEditGameSpecificValue(string p_strKey)
		{
			ShaderEdit sedShader = new ShaderEdit(p_strKey);
			SDPArchives sdpManager = new SDPArchives(GameModeInfo, FileUtility);
			if (!TouchedFiles.Contains(sdpManager.GetPath(sedShader.Package)))
			{
				TouchedFiles.Add(sdpManager.GetPath(sedShader.Package));
				TransactionalFileManager.Snapshot(sdpManager.GetPath(sedShader.Package));
			}

			string strKey = InstallLog.GetModKey(Mod);
			string strCurrentOwnerKey = InstallLog.GetCurrentGameSpecificValueEditOwnerKey(p_strKey);
			//if we didn't edit the shader, then leave it alone
			if (!strKey.Equals(strCurrentOwnerKey))
				return;

			//if we did edit the shader, replace it with the shader we overwrote
			// if we didn't overwrite the shader, then just delete it
			byte[] btePreviousData = InstallLog.GetPreviousGameSpecificValue(p_strKey);
			if (btePreviousData != null)
			{
				/*TODO (likely never): I'm not sure if this is the strictly correct way to unedit a shader
				 * the original unedit code was:
				 * 
				 *	if (m_xelModInstallLogSdpEdits != null)
				 *	{
				 *		foreach (XmlNode node in m_xelModInstallLogSdpEdits.ChildNodes)
				 *		{
				 *			//TODO (likely never): Remove this workaround for the release version
				 *			if (node.Attributes.GetNamedItem("crc") == null)
				 *			{
				 *				InstallLog.UndoShaderEdit(int.Parse(node.Attributes.GetNamedItem("package").Value), node.Attributes.GetNamedItem("shader").Value, 0);
				 *			}
				 *			else
				 *			{
				 *				InstallLog.UndoShaderEdit(int.Parse(node.Attributes.GetNamedItem("package").Value), node.Attributes.GetNamedItem("shader").Value,
				 *					uint.Parse(node.Attributes.GetNamedItem("crc").Value));
				 *			}
				 *		}
				 *	}
				 *	
				 * where InstallLog.UndoShaderEdit was:
				 * 
				 *	public void UndoShaderEdit(int package, string shader, uint crc)
				 *	{
				 *		XmlNode node = sdpEditsNode.SelectSingleNode("sdp[@package='" + package + "' and @shader='" + shader + "']");
				 *		if (node == null) return;
				 *		byte[] b = new byte[node.InnerText.Length / 2];
				 *		for (int i = 0; i < b.Length; i++)
				 *		{
				 *			b[i] = byte.Parse("" + node.InnerText[i * 2] + node.InnerText[i * 2 + 1], System.Globalization.NumberStyles.AllowHexSpecifier);
				 *		}
				 *		if (SDPArchives.RestoreShader(package, shader, b, crc)) sdpEditsNode.RemoveChild(node);
				 *	}
				 *	
				 * after looking at SDPArchives it is not clear to me why a crc was being used.
				 * if ever it becomes evident that a crc is required, I will have to alter the log to store
				 *  a crc and pass it to the RestoreShader method.
				 */
				if (!sdpManager.RestoreShader(sedShader.Package, sedShader.ShaderName, btePreviousData, 0))
					throw new Exception("Failed to unedit the shader");
			}
			//TODO (likely never): how do we delete a shader? Right now, if there was no previous shader the current shader
			// remains
		}
		/// <summary>
		/// Edits the specified game specific value.
		/// </summary>
		/// <param name="p_strKey">The key of the edited Game Specific Value.</param>
		/// <param name="p_bteValue">The value to install.</param>
		/// <returns><c>true</c> if the value was set; <c>false</c> otherwise.</returns>
		public virtual bool EditGameSpecificValue(string p_strKey, byte[] p_bteValue)
		{
			if (m_booDontOverwriteAll)
				return false;

			ShaderEdit sedShader = new ShaderEdit(p_strKey);
			SDPArchives sdpManager = new SDPArchives(GameModeInfo, FileUtility);
			if (!TouchedFiles.Contains(sdpManager.GetPath(sedShader.Package)))
			{
				TouchedFiles.Add(sdpManager.GetPath(sedShader.Package));
				TransactionalFileManager.Snapshot(sdpManager.GetPath(sedShader.Package));
			}

			IMod modOldMod = InstallLog.GetCurrentGameSpecificValueEditOwner(p_strKey);
			if (!m_booOverwriteAll && (modOldMod != null))
			{
				string strMessage = String.Format("Shader '{0}' in package '{1}' has already been overwritten by '{2}'\n" +
										"Overwrite the changes?", sedShader.ShaderName, sedShader.Package, modOldMod.ModName);
				switch (m_dlgOverwriteConfirmationDelegate(strMessage, false, false))
				{
					case OverwriteResult.YesToAll:
						m_booOverwriteAll = true;
						break;
					case OverwriteResult.NoToAll:
						m_booDontOverwriteAll = true;
						break;
					case OverwriteResult.Yes:
						break;
					default:
						return false;
				}
			}

			byte[] oldData;
			if (!sdpManager.EditShader(sedShader.Package, sedShader.ShaderName, p_bteValue, out oldData))
				throw new Exception("Failed to edit the shader");

			//if we are overwriting an original shader, back it up
			if ((modOldMod == null) && (oldData != null))
				InstallLog.LogOriginalGameSpecificValue(p_strKey, oldData);

			InstallLog.AddGameSpecificValueEdit(Mod, p_strKey, p_bteValue);
			return true;
		}