/SearchHandler.cs
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace bytex64.WebThing {
    public class SearchHandler {
        WebThing wt;
        Dictionary<string,ISearchPlugin> Handlers;
        ISearchPlugin DefaultSearchHandler;
        
        public SearchHandler(WebThing wt) {
            Handlers = new Dictionary<string,ISearchPlugin>();
            this.wt = wt;

            foreach (SearchHandlerPair p in Config.SearchHandlers) {
                AddHandler(p.Shortcut, p.Plugin);
            }
            if (Config.DefaultSearchHandler != null) {
                SetDefaultHandler(Config.DefaultSearchHandler);
            }
        }

        private bool IsValidSearchHandler(WebThingPlugin p) {
            Type ptype = p.GetType();
            if (ptype.GetInterface("ISearchPlugin") != null)
                return true;
            return false;
        }

        public void AddHandler(string key, string plugin) {
            if (Handlers.ContainsKey(key)) {
                Console.WriteLine("Cannot add search handler {0}: shortcut {1} already registered", plugin, key);
                return;
            }
            if (!wt.Plugins.Plugins.ContainsKey(plugin)) {
                Console.WriteLine("Cannot add search handler {0}: Plugin for {0} not loaded", plugin);
                return;
            }

            WebThingPlugin p = wt.Plugins.Plugins[plugin];

            if (IsValidSearchHandler(p)) {
                Handlers[key] = (ISearchPlugin) p;
                Console.WriteLine("Added handler {0} for key {1}", plugin, key);
            } else {
                Console.WriteLine("Cannot add search handler {0}: {0} Does not implement ISearchPlugin", plugin);
            }
        }

        public void SetDefaultHandler(string plugin) {
            if (wt.Plugins.Plugins.ContainsKey(plugin)) {
                WebThingPlugin p = wt.Plugins.Plugins[plugin];
                if (IsValidSearchHandler(p)) {
                    DefaultSearchHandler = (ISearchPlugin) p;
                } else {
                    Console.WriteLine("Could not set default search handler: {0} does not implement ISearchPlugin", plugin);
                }
            } else {
                Console.WriteLine("Could not set default search handler: {0} is not loaded", plugin);
            }
        }

        // Call a search handler based on the leading word
        public string Transform(string search) {
            Regex get_handler_re = new Regex(@"^([\w-]+)\s+");
            Match m = get_handler_re.Match(search);
            if (m.Success) {
                string key = m.Groups[1].Value;
                string query = get_handler_re.Replace(search, "");
                if (Handlers.ContainsKey(key)) {
                    return Handlers[key].SearchTransform(query);
                } else {
                    if (DefaultSearchHandler != null) {
                        return DefaultSearchHandler.SearchTransform(search);
                    } else {
                        Console.WriteLine("Could not search with {0} and no default search handler defined", key);
                        return null;
                    }
                }
            } else {
                if (DefaultSearchHandler != null) {
                    return DefaultSearchHandler.SearchTransform(search);
                } else {
                    Console.WriteLine("Could not get search key and no default search handler defined");
                    return null;
                }
            }
        }
    }
}