/// <summary>
        /// Adds a new change.
        /// </summary>
        /// <param name="page">The page name.</param>
        /// <param name="title">The page title.</param>
        /// <param name="messageSubject">The message subject (or <c>null</c>).</param>
        /// <param name="dateTime">The date/time.</param>
        /// <param name="user">The user.</param>
        /// <param name="change">The change.</param>
        /// <param name="descr">The description (optional).</param>
        /// <returns><c>true</c> if the change is saved, <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">If <b>page</b>, <b>title</b> or <b>user</b> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <b>page</b>, <b>title</b> or <b>user</b> are empty.</exception>
        public bool AddRecentChange(string page, string title, string messageSubject, DateTime dateTime, string user,
            ScrewTurn.Wiki.PluginFramework.Change change, string descr)
        {
            if(page == null) throw new ArgumentNullException("page");
            if(page.Length == 0) throw new ArgumentException("Page cannot be empty", "page");
            if(title == null) throw new ArgumentNullException("title");
            if(title.Length == 0) throw new ArgumentException("Title cannot be empty", "title");
            if(user == null) throw new ArgumentNullException("user");
            if(user.Length == 0) throw new ArgumentException("User cannot be empty", "user");

            if(messageSubject == null) messageSubject = "";
            if(descr == null) descr = "";

            lock(this) {
                StringBuilder sb = new StringBuilder(100);
                sb.Append(Tools.EscapeString(page));
                sb.Append("|");
                sb.Append(Tools.EscapeString(title));
                sb.Append("|");
                sb.Append(Tools.EscapeString(messageSubject));
                sb.Append("|");
                sb.Append(dateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
                sb.Append("|");
                sb.Append(Tools.EscapeString(user));
                sb.Append("|");
                sb.Append(GetChangeString(change));
                sb.Append("|");
                sb.Append(Tools.EscapeString(descr));
                sb.Append("\r\n");
                File.AppendAllText(GetFullPath(RecentChangesFile), sb.ToString());

                // Delete old changes, if needed
                int max = int.Parse(host.GetSettingValue(SettingName.MaxRecentChanges));
                if(GetRecentChanges().Length > max) CutRecentChanges((int)(max * 0.90));

                return true;
            }
        }
 /// <summary>
 /// Gets the change string for a change.
 /// </summary>
 /// <param name="change">The change.</param>
 /// <returns>The change string.</returns>
 private static string GetChangeString(ScrewTurn.Wiki.PluginFramework.Change change)
 {
     switch(change) {
         case ScrewTurn.Wiki.PluginFramework.Change.PageUpdated:
             return "U";
         case ScrewTurn.Wiki.PluginFramework.Change.PageDeleted:
             return "D";
         case ScrewTurn.Wiki.PluginFramework.Change.PageRolledBack:
             return "R";
         case ScrewTurn.Wiki.PluginFramework.Change.PageRenamed:
             return "N";
         case ScrewTurn.Wiki.PluginFramework.Change.MessagePosted:
             return "MP";
         case ScrewTurn.Wiki.PluginFramework.Change.MessageEdited:
             return "ME";
         case ScrewTurn.Wiki.PluginFramework.Change.MessageDeleted:
             return "MD";
         default:
             throw new NotSupportedException();
     }
 }
		/// <summary>
		/// Adds a new change.
		/// </summary>
		/// <param name="page">The page name.</param>
		/// <param name="title">The page title.</param>
		/// <param name="messageSubject">The message subject (or <c>null</c>).</param>
		/// <param name="dateTime">The date/time.</param>
		/// <param name="user">The user.</param>
		/// <param name="change">The change.</param>
		/// <param name="descr">The description (optional).</param>
		/// <returns><c>true</c> if the change is saved, <c>false</c> otherwise.</returns>
		/// <exception cref="ArgumentNullException">If <b>page</b>, <b>title</b> or <b>user</b> are <c>null</c>.</exception>
		/// <exception cref="ArgumentException">If <b>page</b>, <b>title</b> or <b>user</b> are empty.</exception>
		public bool AddRecentChange(string page, string title, string messageSubject, DateTime dateTime, string user, ScrewTurn.Wiki.PluginFramework.Change change, string descr) {
			if(page == null) throw new ArgumentNullException("page");
			if(page.Length == 0) throw new ArgumentException("Page cannot be empty", "page");
			if(title == null) throw new ArgumentNullException("title");
			if(title.Length == 0) throw new ArgumentException("Title cannot be empty", "title");
			if(user == null) throw new ArgumentNullException("user");
			if(user.Length == 0) throw new ArgumentException("User cannot be empty", "user");

			ICommandBuilder builder = GetCommandBuilder();

			string query = QueryBuilder.NewQuery(builder).InsertInto("RecentChange", new string[] { "Page", "Title", "MessageSubject", "DateTime", "User", "Change", "Description" },
				new string[] { "Page", "Title", "MessageSubject", "DateTime", "User", "Change", "Description" });

			List<Parameter> parameters = new List<Parameter>(7);
			parameters.Add(new Parameter(ParameterType.String, "Page", page));
			parameters.Add(new Parameter(ParameterType.String, "Title", title));
			if(!string.IsNullOrEmpty(messageSubject)) parameters.Add(new Parameter(ParameterType.String, "MessageSubject", messageSubject));
			else parameters.Add(new Parameter(ParameterType.String, "MessageSubject", DBNull.Value));
			parameters.Add(new Parameter(ParameterType.DateTime, "DateTime", dateTime));
			parameters.Add(new Parameter(ParameterType.String, "User", user));
			parameters.Add(new Parameter(ParameterType.Char, "Change", RecentChangeToChar(change)));
			if(!string.IsNullOrEmpty(descr)) parameters.Add(new Parameter(ParameterType.String, "Description", descr));
			else parameters.Add(new Parameter(ParameterType.String, "Description", DBNull.Value));

			DbCommand command = builder.GetCommand(connString, query, parameters);

			int rows = ExecuteNonQuery(command);

			CutRecentChangesIfNecessary();

			return rows == 1;
		}
		/// <summary>
		/// Converts a <see cref="T:ScrewTurn.Wiki.PluginFramework.Change" /> to its character representation.
		/// </summary>
		/// <param name="change">The <see cref="T:ScrewTurn.Wiki.PluginFramework.Change" />.</param>
		/// <returns>The character representation.</returns>
		private static char RecentChangeToChar(ScrewTurn.Wiki.PluginFramework.Change change) {
			switch(change) {
				case ScrewTurn.Wiki.PluginFramework.Change.MessageDeleted:
					return 'M';
				case ScrewTurn.Wiki.PluginFramework.Change.MessageEdited:
					return 'E';
				case ScrewTurn.Wiki.PluginFramework.Change.MessagePosted:
					return 'P';
				case ScrewTurn.Wiki.PluginFramework.Change.PageDeleted:
					return 'D';
				case ScrewTurn.Wiki.PluginFramework.Change.PageRenamed:
					return 'N';
				case ScrewTurn.Wiki.PluginFramework.Change.PageRolledBack:
					return 'R';
				case ScrewTurn.Wiki.PluginFramework.Change.PageUpdated:
					return 'U';
				default:
					throw new NotSupportedException();
			}
		}
 public bool AddRecentChange(string page, string title, string messageSubject, DateTime dateTime, string user, ScrewTurn.Wiki.PluginFramework.Change change, string descr)
 {
     throw new NotImplementedException();
 }
 public ScrewTurn.Wiki.SearchEngine.SearchResultCollection PerformSearch(string query, bool fullText, bool filesAndAttachments, ScrewTurn.Wiki.SearchEngine.SearchOptions options)
 {
     throw new NotImplementedException();
 }