From 54c6a920baa0ef02a9ea09e08cc1effcef3b0a3a Mon Sep 17 00:00:00 2001
From: Melanie Thielker
Date: Sat, 7 Feb 2009 12:25:39 +0000
Subject: Replace the console for all OpenSim apps with a new console featuring
 command line editing, context sensitive help (press ? at any time), command
 line history, a new plugin command system and new appender features thet let
 you type while the console is scrolling. Seamlessly integrates the ICommander
 interfaces.

---
 OpenSim/Framework/Console/ConsoleBase.cs           |  661 ++++++++++---
 OpenSim/Framework/Console/ConsoleCallbacksBase.cs  |   35 -
 OpenSim/Framework/Console/OpenSimAppender.cs       |   16 +
 OpenSim/Framework/IScene.cs                        |    3 +
 OpenSim/Framework/Servers/BaseOpenSimServer.cs     |  119 +--
 OpenSim/Grid/AssetServer/Main.cs                   |    6 +-
 OpenSim/Grid/GridServer/GridServerBase.cs          |   63 +-
 OpenSim/Grid/InventoryServer/Main.cs               |   21 +-
 OpenSim/Grid/MessagingServer/Main.cs               |   42 +-
 OpenSim/Grid/UserServer/Main.cs                    |   94 +-
 OpenSim/Region/Application/Application.cs          |   15 +-
 OpenSim/Region/Application/HGOpenSimNode.cs        |   27 +-
 OpenSim/Region/Application/OpenSim.cs              | 1033 ++++++++++----------
 OpenSim/Region/Application/OpenSimBase.cs          |   40 +
 .../Region/ClientStack/RegionApplicationBase.cs    |    2 +
 .../Framework/InterfaceCommander/Command.cs        |   12 +
 .../Modules/World/Permissions/PermissionsModule.cs |  148 +--
 OpenSim/Region/Framework/Interfaces/ICommand.cs    |    1 +
 OpenSim/Region/Framework/Scenes/Scene.cs           |   18 +-
 OpenSim/Region/Framework/Scenes/SceneBase.cs       |    8 +
 .../Shared/Api/Implementation/LSL_Api.cs           |    6 -
 OpenSim/TestSuite/BotManager.cs                    |   51 +-
 OpenSim/Tools/pCampBot/BotManager.cs               |   85 +-
 23 files changed, 1471 insertions(+), 1035 deletions(-)
 delete mode 100644 OpenSim/Framework/Console/ConsoleCallbacksBase.cs

diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs
index 30af23a..f990748 100644
--- a/OpenSim/Framework/Console/ConsoleBase.cs
+++ b/OpenSim/Framework/Console/ConsoleBase.cs
@@ -26,22 +26,250 @@
  */
 
 using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Net;
+using System.Text;
 using System.Reflection;
-using System.Text.RegularExpressions;
+using System.Diagnostics;
+using System.Collections.Generic;
 using log4net;
 
 namespace OpenSim.Framework.Console
 {
+    public delegate void CommandDelegate(string module, string[] cmd);
+
+    public class Commands
+    {
+        private class CommandInfo
+        {
+            public string module;
+            public string help_text;
+            public string long_help;
+            public CommandDelegate fn;
+        }
+
+        private Dictionary<string, Object> tree =
+                new Dictionary<string, Object>();
+
+        public List<string> GetHelp()
+        {
+            List<string> help = new List<string>();
+
+            help.AddRange(CollectHelp(tree));
+
+            help.Sort();
+
+            return help;
+        }
+
+        private List<string> CollectHelp(Dictionary<string, Object> dict)
+        {
+            List<string> result = new List<string>();
+
+            foreach (KeyValuePair<string, object> kvp in dict)
+            {
+                if (kvp.Value is Dictionary<string, Object>)
+                {
+                    result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
+                }
+                else
+                {
+                    if (((CommandInfo)kvp.Value).long_help != String.Empty)
+                        result.Add(((CommandInfo)kvp.Value).help_text+" - "+
+                                ((CommandInfo)kvp.Value).long_help);
+                }
+            }
+            return result;
+        }
+
+        public void AddCommand(string module, string command, string help, string longhelp, CommandDelegate fn)
+        {
+            string[] parts = Parser.Parse(command);
+
+            Dictionary<string, Object> current = tree;
+            foreach (string s in parts)
+            {
+                if (current.ContainsKey(s))
+                {
+                    if (current[s] is Dictionary<string, Object>)
+                    {
+                        current = (Dictionary<string, Object>)current[s];
+                    }
+                    else
+                        return;
+                }
+                else
+                {
+                    current[s] = new Dictionary<string, Object>();
+                    current = (Dictionary<string, Object>)current[s];
+                }
+            }
+
+            if (current.ContainsKey(String.Empty))
+                return;
+            CommandInfo info = new CommandInfo();
+            info.module = module;
+            info.help_text = help;
+            info.long_help = longhelp;
+            info.fn = fn;
+            current[String.Empty] = info;
+        }
+
+        public string[] FindNextOption(string[] cmd, bool term)
+        {
+            Dictionary<string, object> current = tree;
+
+            int remaining = cmd.Length;
+
+            foreach (string s in cmd)
+            {
+                remaining--;
+
+                List<string> found = new List<string>();
+
+                foreach (string opt in current.Keys)
+                {
+                    if (opt.StartsWith(s))
+                    {
+                        found.Add(opt);
+                    }
+                }
+
+                if (found.Count == 1 && (remaining != 0 || term))
+                {
+                    current = (Dictionary<string, object>)current[found[0]];
+                }
+                else if (found.Count > 0)
+                {
+                    return found.ToArray();
+                }
+                else
+                {
+                    break;
+//                    return new string[] {"<cr>"};
+                }
+            }
+
+            if (current.Count > 1)
+            {
+                List<string> choices = new List<string>();
+
+                bool addcr = false;
+                foreach (string s in current.Keys)
+                {
+                    if (s == String.Empty)
+                    {
+                        CommandInfo ci = (CommandInfo)current[String.Empty];
+                        if (ci.fn != null)
+                            addcr = true;
+                    }
+                    else
+                        choices.Add(s);
+                }
+                if (addcr)
+                    choices.Add("<cr>");
+                return choices.ToArray();
+            }
+
+            if (current.ContainsKey(String.Empty))
+                return new string[] { "Command help: "+((CommandInfo)current[String.Empty]).help_text};
+
+            return new string[] { new List<string>(current.Keys)[0] };
+        }
+
+        public string[] Resolve(string[] cmd)
+        {
+            string[] result = cmd;
+            int index = -1;
+
+            Dictionary<string, object> current = tree;
+
+            foreach (string s in cmd)
+            {
+                index++;
+
+                List<string> found = new List<string>();
+
+                foreach (string opt in current.Keys)
+                {
+                    if (opt.StartsWith(s))
+                    {
+                        found.Add(opt);
+                    }
+                }
+
+                if (found.Count == 1)
+                {
+                    result[index] = found[0];
+                    current = (Dictionary<string, object>)current[found[0]];
+                }
+                else if (found.Count > 0)
+                {
+                    return new string[0];
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            if (current.ContainsKey(String.Empty))
+            {
+                CommandInfo ci = (CommandInfo)current[String.Empty];
+                if (ci.fn == null)
+                    return new string[0];
+                ci.fn(ci.module, result);
+                return result;
+            }
+            return new string[0];
+        }
+    }
+
+    public class Parser
+    {
+        public static string[] Parse(string text)
+        {
+            List<string> result = new List<string>();
+
+            int index;
+
+            string[] unquoted = text.Split(new char[] {'"'});
+
+            for (index = 0 ; index < unquoted.Length ; index++)
+            {
+                if (index % 2 == 0)
+                {
+                    string[] words = unquoted[index].Split(new char[] {' '});
+                    foreach (string w in words)
+                    {
+                        if (w != String.Empty)
+                            result.Add(w);
+                    }
+                }
+                else
+                {
+                    result.Add(unquoted[index]);
+                }
+            }
+
+            return result.ToArray();
+        }
+    }
+
     public class ConsoleBase
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
         private readonly object m_syncRoot = new object();
 
-        public conscmd_callback m_cmdParser;
+        private int y = -1;
+        private int cp = 0;
+        private int h = 1;
+        private string prompt = "# ";
+        private StringBuilder cmdline = new StringBuilder();
+        public Commands Commands = new Commands();
+        private bool echo = true;
+        private List<string> history = new List<string>();
+
+        public object ConsoleScene = null;
 
         /// <summary>
         /// The default prompt text.
@@ -53,15 +281,19 @@ namespace OpenSim.Framework.Console
         }
         protected string m_defaultPrompt;
 
-        /// <summary>
-        /// Constructor.
-        /// </summary>
-        /// <param name="defaultPrompt"></param>
-        /// <param name="cmdparser"></param>
-        public ConsoleBase(string defaultPrompt, conscmd_callback cmdparser)
+        public ConsoleBase(string defaultPrompt)
         {
             DefaultPrompt = defaultPrompt;
-            m_cmdParser = cmdparser;
+
+            Commands.AddCommand("console", "help", "help", "Get command list", Help);
+        }
+
+        private void AddToHistory(string text)
+        {
+            while (history.Count >= 100)
+                history.RemoveAt(0);
+
+            history.Add(text);
         }
 
         /// <summary>
@@ -95,8 +327,7 @@ namespace OpenSim.Framework.Console
         /// <param name="args">WriteLine-style message arguments</param>
         public void Warn(string sender, string format, params object[] args)
         {
-            WritePrefixLine(DeriveColor(sender), sender);
-            WriteNewLine(ConsoleColor.Yellow, format, args);
+            WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Yellow, format, args);
         }
 
         /// <summary>
@@ -117,10 +348,8 @@ namespace OpenSim.Framework.Console
         /// <param name="args">WriteLine-style message arguments</param>
         public void Notice(string sender, string format, params object[] args)
         {
-            WritePrefixLine(DeriveColor(sender), sender);
-            WriteNewLine(ConsoleColor.White, format, args);
+            WriteNewLine(DeriveColor(sender), sender, ConsoleColor.White, format, args);
         }
-
         /// <summary>
         /// Sends an error to the current console output
         /// </summary>
@@ -139,8 +368,7 @@ namespace OpenSim.Framework.Console
         /// <param name="args">WriteLine-style message arguments</param>
         public void Error(string sender, string format, params object[] args)
         {
-            WritePrefixLine(DeriveColor(sender), sender);
-            Error(format, args);
+            WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Red, format, args);
         }
 
         /// <summary>
@@ -161,8 +389,7 @@ namespace OpenSim.Framework.Console
         /// <param name="args">WriteLine-style message arguments</param>
         public void Status(string sender, string format, params object[] args)
         {
-            WritePrefixLine(DeriveColor(sender), sender);
-            WriteNewLine(ConsoleColor.Blue, format, args);
+            WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Blue, format, args);
         }
 
         [Conditional("DEBUG")]
@@ -174,12 +401,60 @@ namespace OpenSim.Framework.Console
         [Conditional("DEBUG")]
         public void Debug(string sender, string format, params object[] args)
         {
-            WritePrefixLine(DeriveColor(sender), sender);
-            WriteNewLine(ConsoleColor.Gray, format, args);
+            WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Gray, format, args);
+        }
+
+        private void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
+        {
+            lock (cmdline)
+            {
+                if (y != -1)
+                {
+                    System.Console.CursorTop = y;
+                    System.Console.CursorLeft = 0;
+
+                    int count = cmdline.Length;
+
+                    System.Console.Write("  ");
+                    while (count-- > 0)
+                        System.Console.Write(" ");
+
+                    System.Console.CursorTop = y;
+                    System.Console.CursorLeft = 0;
+                }
+                WritePrefixLine(senderColor, sender);
+                WriteConsoleLine(color, format, args);
+                if (y != -1)
+                    y = System.Console.CursorTop;
+            }
         }
 
         private void WriteNewLine(ConsoleColor color, string format, params object[] args)
         {
+            lock (cmdline)
+            {
+                if (y != -1)
+                {
+                    System.Console.CursorTop = y;
+                    System.Console.CursorLeft = 0;
+
+                    int count = cmdline.Length;
+
+                    System.Console.Write("  ");
+                    while (count-- > 0)
+                        System.Console.Write(" ");
+
+                    System.Console.CursorTop = y;
+                    System.Console.CursorLeft = 0;
+                }
+                WriteConsoleLine(color, format, args);
+                if (y != -1)
+                    y = System.Console.CursorTop;
+            }
+        }
+
+        private void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
+        {
             try
             {
                 lock (m_syncRoot)
@@ -240,108 +515,150 @@ namespace OpenSim.Framework.Console
             }
         }
 
-        public string ReadLine()
+        private void Help(string module, string[] cmd)
         {
-            try
-            {
-                string line = System.Console.ReadLine();
+            List<string> help = Commands.GetHelp();
+
+            foreach (string s in help)
+                Output(s);
+        }
 
-                while (line == null)
+        private void Show()
+        {
+            lock (cmdline)
+            {
+                if (y == -1 || System.Console.BufferWidth == 0)
+                    return;
+
+                int xc = prompt.Length + cp;
+                int new_x = xc % System.Console.BufferWidth;
+                int new_y = y + xc / System.Console.BufferWidth;
+                int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
+                if (end_y / System.Console.BufferWidth >= h)
+                    h++;
+                if (end_y >= System.Console.BufferHeight) // wrap
                 {
-                    line = System.Console.ReadLine();
+                    y--;
+                    new_y--;
+                    System.Console.CursorLeft = 0;
+                    System.Console.CursorTop = System.Console.BufferHeight-1;
+                    System.Console.WriteLine(" ");
                 }
 
-                return line;
-            }
-            catch (Exception e)
-            {
-                m_log.Error("[Console]: System.Console.ReadLine exception " + e.ToString());
-                return String.Empty;
-            }
-        }
+                System.Console.CursorTop = y;
+                System.Console.CursorLeft = 0;
 
-        public int Read()
-        {
-            return System.Console.Read();
+                if (echo)
+                    System.Console.Write("{0}{1}", prompt, cmdline);
+                else
+                    System.Console.Write("{0}", prompt);
+
+                System.Console.CursorLeft = new_x;
+                System.Console.CursorTop = new_y;
+            }
         }
 
-        public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue)
+        public void LockOutput()
         {
-            IPAddress address;
-            string addressStr;
-
-            while (true)
+            System.Threading.Monitor.Enter(cmdline);
+            try
             {
-                addressStr = CmdPrompt(prompt, defaultvalue);
-                if (IPAddress.TryParse(addressStr, out address))
+                if (y != -1)
                 {
-                    break;
-                }
-                else
-                {
-                    m_log.Error("Illegal address. Please re-enter.");
+                    System.Console.CursorTop = y;
+                    System.Console.CursorLeft = 0;
+
+                    int count = cmdline.Length + prompt.Length;
+
+                    while (count-- > 0)
+                        System.Console.Write(" ");
+
+                    System.Console.CursorTop = y;
+                    System.Console.CursorLeft = 0;
+
                 }
             }
-
-            return address;
+            catch (Exception)
+            {
+            }
         }
 
-        public uint CmdPromptIPPort(string prompt, string defaultvalue)
+        public void UnlockOutput()
         {
-            uint port;
-            string portStr;
+            if (y != -1)
+            {
+                y = System.Console.CursorTop;
+                Show();
+            }
+            System.Threading.Monitor.Exit(cmdline);
+        }
 
-            while (true)
+        public void Output(string text)
+        {
+            lock (cmdline)
             {
-                portStr = CmdPrompt(prompt, defaultvalue);
-                if (uint.TryParse(portStr, out port))
+                if (y == -1)
                 {
-                    if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort)
-                    {
-                        break;
-                    }
+                    System.Console.WriteLine(text);
+
+                    return;
                 }
 
-                m_log.Error("Illegal address. Please re-enter.");
-            }
+                System.Console.CursorTop = y;
+                System.Console.CursorLeft = 0;
 
-            return port;
-        }
+                int count = cmdline.Length + prompt.Length;
 
-        // Displays a prompt and waits for the user to enter a string, then returns that string
-        // (Done with no echo and suitable for passwords - currently disabled)
-        public string PasswdPrompt(string prompt)
-        {
-            // FIXME: Needs to be better abstracted
-            System.Console.WriteLine(String.Format("{0}: ", prompt));
-            //ConsoleColor oldfg = System.Console.ForegroundColor;
-            //System.Console.ForegroundColor = System.Console.BackgroundColor;
-            string temp = System.Console.ReadLine();
-            //System.Console.ForegroundColor = oldfg;
-            return temp;
+                while (count-- > 0)
+                    System.Console.Write(" ");
+
+                System.Console.CursorTop = y;
+                System.Console.CursorLeft = 0;
+
+                System.Console.WriteLine(text);
+
+                y = System.Console.CursorTop;
+
+                Show();
+            }
         }
 
-        // Displays a command prompt and waits for the user to enter a string, then returns that string
-        public string CmdPrompt(string prompt)
+        private void ContextHelp()
         {
-            System.Console.WriteLine(String.Format("{0}: ", prompt));
-            return ReadLine();
+            string[] words = Parser.Parse(cmdline.ToString());
+
+            string[] opts = Commands.FindNextOption(words, cmdline.ToString().EndsWith(" "));
+
+            if (opts[0].StartsWith("Command help:"))
+                Output(opts[0]);
+            else
+                Output(String.Format("Options: {0}", String.Join(" ", opts)));
         }
 
-        // Displays a command prompt and returns a default value if the user simply presses enter
-        public string CmdPrompt(string prompt, string defaultresponse)
+        public void Prompt()
         {
-            string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse));
-            if (temp == String.Empty)
-            {
-                return defaultresponse;
-            }
-            else
+            string line = ReadLine(m_defaultPrompt, true, true);
+
+            if (line != String.Empty)
             {
-                return temp;
+                m_log.Info("Invalid command");
             }
         }
 
+        public string CmdPrompt(string p)
+        {
+            return ReadLine(String.Format("{0}: ", p), false, true);
+        }
+
+        public string CmdPrompt(string p, string def)
+        {
+            string ret = ReadLine(String.Format("{0} [{1}]: ", p, def), false, true);
+            if (ret == String.Empty)
+                ret = def;
+
+            return ret;
+        }
+
         // Displays a command prompt and returns a default value, user may only enter 1 of 2 options
         public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB)
         {
@@ -362,85 +679,137 @@ namespace OpenSim.Framework.Console
             return temp;
         }
 
-        // Runs a command with a number of parameters
-        public Object RunCmd(string Cmd, string[] cmdparams)
-        {
-            m_cmdParser.RunCmd(Cmd, cmdparams);
-            return null;
-        }
-
-        // Shows data about something
-        public void ShowCommands(string ShowWhat)
+        // Displays a prompt and waits for the user to enter a string, then returns that string
+        // (Done with no echo and suitable for passwords)
+        public string PasswdPrompt(string p)
         {
-            m_cmdParser.Show(new string[] { ShowWhat });
+            return ReadLine(p, false, false);
         }
 
-        public void Prompt()
+        public void RunCommand(string cmd)
         {
-            string tempstr = CmdPrompt(m_defaultPrompt);
-            RunCommand(tempstr);
+            string[] parts = Parser.Parse(cmd);
+            Commands.Resolve(parts);
         }
 
-        public void RunCommand(string cmdline)
+        public string ReadLine(string p, bool isCommand, bool e)
         {
-            Regex Extractor = new Regex(@"(['""][^""]+['""])\s*|([^\s]+)\s*", RegexOptions.Compiled);
-            char[] delims = {' ', '"'};
-            MatchCollection matches = Extractor.Matches(cmdline);
-            // Get matches
+            h = 1;
+            cp = 0;
+            prompt = p;
+            echo = e;
+            int historyLine = history.Count;
 
-            if (matches.Count == 0)
-                return;
+            System.Console.CursorLeft = 0; // Needed for mono
+            System.Console.Write(" "); // Needed for mono
 
-            string cmd = matches[0].Value.Trim(delims);
-            string[] cmdparams = new string[matches.Count - 1];
+            y = System.Console.CursorTop;
+            cmdline = new StringBuilder();
 
-            for (int i = 1; i < matches.Count; i++)
+            while(true)
             {
-                cmdparams[i-1] = matches[i].Value.Trim(delims);
-            }
+                Show();
 
-            try
-            {
-                RunCmd(cmd, cmdparams);
-            }
-            catch (Exception e)
-            {
-                m_log.ErrorFormat("[Console]: Command [{0}] failed with exception {1}", cmdline, e.ToString());
-                m_log.Error(e.StackTrace);
-            }
-        }
+                ConsoleKeyInfo key = System.Console.ReadKey(true);
+                char c = key.KeyChar;
 
-        public string LineInfo
-        {
-            get
-            {
-                string result = String.Empty;
+                if (!Char.IsControl(c))
+                {
+                    if (cp >= 318)
+                        continue;
 
-                string stacktrace = Environment.StackTrace;
-                List<string> lines = new List<string>(stacktrace.Split(new string[] {"at "}, StringSplitOptions.None));
+                    if (c == '?' && isCommand)
+                    {
+                        ContextHelp();
+                        continue;
+                    }
 
-                if (lines.Count > 4)
+                    cmdline.Insert(cp, c);
+                    cp++;
+                }
+                else
                 {
-                    lines.RemoveRange(0, 4);
+                    switch (key.Key)
+                    {
+                    case ConsoleKey.Backspace:
+                        if (cp == 0)
+                            break;
+                        cmdline.Remove(cp-1, 1);
+                        cp--;
 
-                    string tmpLine = lines[0];
+                        System.Console.CursorLeft = 0;
+                        System.Console.CursorTop = y;
 
-                    int inIndex = tmpLine.IndexOf(" in ");
+                        System.Console.Write("{0}{1} ", prompt, cmdline);
 
-                    if (inIndex > -1)
-                    {
-                        result = tmpLine.Substring(0, inIndex);
+                        break;
+                    case ConsoleKey.End:
+                        cp = cmdline.Length;
+                        break;
+                    case ConsoleKey.Home:
+                        cp = 0;
+                        break;
+                    case ConsoleKey.UpArrow:
+                        if (historyLine < 1)
+                            break;
+                        historyLine--;
+                        LockOutput();
+                        cmdline = new StringBuilder(history[historyLine]);
+                        cp = cmdline.Length;
+                        UnlockOutput();
+                        break;
+                    case ConsoleKey.DownArrow:
+                        if (historyLine >= history.Count)
+                            break;
+                        historyLine++;
+                        LockOutput();
+                        if (historyLine == history.Count)
+                            cmdline = new StringBuilder();
+                        else
+                            cmdline = new StringBuilder(history[historyLine]);
+                        cp = cmdline.Length;
+                        UnlockOutput();
+                        break;
+                    case ConsoleKey.LeftArrow:
+                        if (cp > 0)
+                            cp--;
+                        break;
+                    case ConsoleKey.RightArrow:
+                        if (cp < cmdline.Length)
+                            cp++;
+                        break;
+                    case ConsoleKey.Enter:
+                        System.Console.CursorLeft = 0;
+                        System.Console.CursorTop = y;
+
+                        System.Console.WriteLine("{0}{1}", prompt, cmdline);
 
-                        int lineIndex = tmpLine.IndexOf(":line ");
+                        y = -1;
 
-                        if (lineIndex > -1)
+                        if (isCommand)
                         {
-                            lineIndex += 6;
-                            result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5);
+                            string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
+
+                            if (cmd.Length != 0)
+                            {
+                                int i;
+
+                                for (i=0 ; i < cmd.Length ; i++)
+                                {
+                                    if (cmd[i].Contains(" "))
+                                        cmd[i] = "\"" + cmd[i] + "\"";
+                                }
+                                AddToHistory(String.Join(" ", cmd));
+                                return String.Empty;
+                            }
                         }
+
+                        AddToHistory(cmdline.ToString());
+                        return cmdline.ToString();
+                    default:
+                        break;
                     }
                 }
-                return result;
             }
         }
     }
diff --git a/OpenSim/Framework/Console/ConsoleCallbacksBase.cs b/OpenSim/Framework/Console/ConsoleCallbacksBase.cs
deleted file mode 100644
index d37c47a..0000000
--- a/OpenSim/Framework/Console/ConsoleCallbacksBase.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the OpenSim Project nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-namespace OpenSim.Framework.Console
-{
-    public interface conscmd_callback
-    {
-        void RunCmd(string cmd, string[] cmdparams);
-        void Show(string[] showParams);
-    }
-}
diff --git a/OpenSim/Framework/Console/OpenSimAppender.cs b/OpenSim/Framework/Console/OpenSimAppender.cs
index b07617f..6193bac 100644
--- a/OpenSim/Framework/Console/OpenSimAppender.cs
+++ b/OpenSim/Framework/Console/OpenSimAppender.cs
@@ -37,6 +37,14 @@ namespace OpenSim.Framework.Console
     /// </summary>
     public class OpenSimAppender : AnsiColorTerminalAppender
     {
+        private ConsoleBase m_console = null;
+
+        public ConsoleBase Console
+        {
+            get { return m_console; }
+            set { m_console = value; }
+        }
+
         private static readonly ConsoleColor[] Colors = {
             // the dark colors don't seem to be visible on some black background terminals like putty :(
             //ConsoleColor.DarkBlue,
@@ -55,6 +63,9 @@ namespace OpenSim.Framework.Console
 
         override protected void Append(LoggingEvent le)
         {
+            if (m_console != null)
+                m_console.LockOutput();
+
             try
             {
                 string loggingMessage = RenderLoggingEvent(le);
@@ -96,6 +107,11 @@ namespace OpenSim.Framework.Console
             {
                 System.Console.WriteLine("Couldn't write out log message: {0}", e.ToString());
             }
+            finally
+            {
+                if (m_console != null)
+                    m_console.UnlockOutput();
+            }
         }
 
         private void WriteColorText(ConsoleColor color, string sender)
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index ce74b46..493c626 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -27,6 +27,7 @@
 
 using System.Collections.Generic;
 using OpenMetaverse;
+using OpenSim.Framework.Console;
 
 namespace OpenSim.Framework
 {
@@ -88,5 +89,7 @@ namespace OpenSim.Framework
 
         T RequestModuleInterface<T>();
         T[] RequestModuleInterfaces<T>();
+
+        void AddCommand(string module, string command, string shorthelp, string longhelp, CommandDelegate callback);
     }
 }
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 473991a..cc75df4 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -98,7 +98,45 @@ namespace OpenSim.Framework.Servers
         /// <summary>
         /// Must be overriden by child classes for their own server specific startup behaviour.
         /// </summary>
-        protected abstract void StartupSpecific();
+        protected virtual void StartupSpecific()
+        {
+            if (m_console != null)
+            {
+                SetConsoleLogLevel(new string[] { "ALL" });
+
+                m_console.Commands.AddCommand("base", "quit",
+                        "quit",
+                        "Quit the application", HandleQuit);
+
+                m_console.Commands.AddCommand("base", "shutdown",
+                        "shutdown",
+                        "Quit the application", HandleQuit);
+
+                m_console.Commands.AddCommand("base", "set log level",
+                        "set log level <level>",
+                        "Set the console logging level", HandleLogLevel);
+
+                m_console.Commands.AddCommand("base", "show info",
+                        "show info",
+                        "Show general information", HandleShow);
+
+                m_console.Commands.AddCommand("base", "show stats",
+                        "show stats",
+                        "Show statistics", HandleShow);
+
+                m_console.Commands.AddCommand("base", "show threads",
+                        "show threads",
+                        "Show thread status", HandleShow);
+
+                m_console.Commands.AddCommand("base", "show uptime",
+                        "show uptime",
+                        "Show server uptime", HandleShow);
+
+                m_console.Commands.AddCommand("base", "show version",
+                        "show version",
+                        "Show server version", HandleShow);
+            }
+        }
         
         /// <summary>
         /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
@@ -212,6 +250,8 @@ namespace OpenSim.Framework.Servers
                 return;
             }
 
+            consoleAppender.Console = m_console;
+
             if (setParams.Length > 0)
             {
                 Level consoleLevel = repository.LevelMap[setParams[0]];
@@ -261,56 +301,18 @@ namespace OpenSim.Framework.Servers
             Environment.Exit(0);
         }
 
-        /// <summary>
-        /// Runs commands issued by the server console from the operator
-        /// </summary>
-        /// <param name="command">The first argument of the parameter (the command)</param>
-        /// <param name="cmdparams">Additional arguments passed to the command</param>
-        public virtual void RunCmd(string command, string[] cmdparams)
+        private void HandleQuit(string module, string[] args)
         {
-            switch (command)
-            {
-                case "help":
-                    ShowHelp(cmdparams);
-                    Notice("");
-                    break;
-
-                case "set":
-                    Set(cmdparams);
-                    break;
-
-                case "show":
-                    if (cmdparams.Length > 0)
-                    {
-                        Show(cmdparams);
-                    }
-                    break;
-
-                case "quit":
-                case "shutdown":
-                    Shutdown();
-                    break;
-            }
+            Shutdown();
         }
 
-        /// <summary>
-        /// Set an OpenSim parameter
-        /// </summary>
-        /// <param name="setArgs">
-        /// The arguments given to the set command.
-        /// </param>
-        public virtual void Set(string[] setArgs)
+        private void HandleLogLevel(string module, string[] cmd)
         {
-            // Temporary while we only have one command which takes at least two parameters
-            if (setArgs.Length < 2)
-                return;
-
-            if (setArgs[0] == "log" && setArgs[1] == "level")
+            if (cmd.Length > 3)
             {
-                string[] setParams = new string[setArgs.Length - 2];
-                Array.Copy(setArgs, 2, setParams, 0, setArgs.Length - 2);
+                string level = cmd[3];
 
-                SetConsoleLogLevel(setParams);
+                SetConsoleLogLevel(new string[] { level });
             }
         }
 
@@ -324,18 +326,6 @@ namespace OpenSim.Framework.Servers
             
             if (helpArgs.Length == 0)
             {
-                List<string> helpTopics = GetHelpTopics();
-                
-                if (helpTopics.Count > 0)
-                {                    
-                    Notice(
-                        "As well as the help information below, you can also type help <topic> to get more information on the following areas:");
-                    Notice(string.Format("    {0}", string.Join(", ", helpTopics.ToArray())));
-                    Notice("");
-                }                           
-                                
-                Notice("quit - equivalent to shutdown.");
-
                 Notice("set log level [level] - change the console logging level only.  For example, off or debug.");
                 Notice("show info - show server information (e.g. startup path).");
 
@@ -345,21 +335,20 @@ namespace OpenSim.Framework.Servers
                 Notice("show threads - list tracked threads");
                 Notice("show uptime - show server startup time and uptime.");
                 Notice("show version - show server version.");
-                Notice("shutdown - shutdown the server.");
                 Notice("");
 
                 return;
             }
         }
 
-        /// <summary>
-        /// Outputs to the console information about the region
-        /// </summary>
-        /// <param name="showParams">
-        /// What information to display (valid arguments are "uptime", "users", ...)
-        /// </param>
-        public virtual void Show(string[] showParams)
+        public virtual void HandleShow(string module, string[] cmd)
         {
+            List<string> args = new List<string>(cmd);
+
+            args.RemoveAt(0);
+
+            string[] showParams = args.ToArray();
+
             switch (showParams[0])
             {                       
                 case "info":
diff --git a/OpenSim/Grid/AssetServer/Main.cs b/OpenSim/Grid/AssetServer/Main.cs
index 060c473..c71e53f 100644
--- a/OpenSim/Grid/AssetServer/Main.cs
+++ b/OpenSim/Grid/AssetServer/Main.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Grid.AssetServer
     /// <summary>
     /// An asset server
     /// </summary>
-    public class OpenAsset_Main : BaseOpenSimServer, conscmd_callback
+    public class OpenAsset_Main : BaseOpenSimServer
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -76,7 +76,7 @@ namespace OpenSim.Grid.AssetServer
 
         public OpenAsset_Main()
         {
-            m_console = new ConsoleBase("Asset", this);
+            m_console = new ConsoleBase("Asset");
 
             MainConsole.Instance = m_console;
         }
@@ -99,6 +99,8 @@ namespace OpenSim.Grid.AssetServer
             AddHttpHandlers();
 
             m_httpServer.Start();
+
+            base.StartupSpecific();
         }
 
         protected void AddHttpHandlers()
diff --git a/OpenSim/Grid/GridServer/GridServerBase.cs b/OpenSim/Grid/GridServer/GridServerBase.cs
index 68edbd2..3fb07b5 100644
--- a/OpenSim/Grid/GridServer/GridServerBase.cs
+++ b/OpenSim/Grid/GridServer/GridServerBase.cs
@@ -39,7 +39,7 @@ namespace OpenSim.Grid.GridServer
 {
     /// <summary>
     /// </summary>
-    public class GridServerBase : BaseOpenSimServer, conscmd_callback
+    public class GridServerBase : BaseOpenSimServer
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -59,43 +59,34 @@ namespace OpenSim.Grid.GridServer
 
         public GridServerBase()
         {
-            m_console = new ConsoleBase("Grid", this);
+            m_console = new ConsoleBase("Grid");
             MainConsole.Instance = m_console;
         }
 
-        public override void RunCmd(string cmd, string[] cmdparams)
+        private void HandleRegistration(string module, string[] cmd)
         {
-            base.RunCmd(cmd, cmdparams);   
-            
-            switch (cmd)
+            switch (cmd[0])
             {
-                case "disable-reg":
-                    m_config.AllowRegionRegistration = false;
-                    m_log.Info("Region registration disabled");
-                    break;                
-                case "enable-reg":
-                    m_config.AllowRegionRegistration = true;
-                    m_log.Info("Region registration enabled");
-                    break;      
+            case "enable":
+                m_config.AllowRegionRegistration = true;
+                m_log.Info("Region registration enabled");
+                break;
+            case "disable":
+                m_config.AllowRegionRegistration = false;
+                m_log.Info("Region registration disabled");
+                break;
             }
         }
-        
-        public override void Show(string[] showParams)
-        {
-            base.Show(showParams);
 
-            switch (showParams[0])
+        private void HandleShowStatus(string module, string[] cmd)
+        {
+            if (m_config.AllowRegionRegistration)
             {
-                case "status":
-                    if (m_config.AllowRegionRegistration)
-                    {
-                        m_log.Info("Region registration enabled.");
-                    }
-                    else
-                    {              
-                        m_log.Info("Region registration disabled.");
-                    }
-                    break;
+                m_log.Info("Region registration enabled.");
+            }
+            else
+            {              
+                m_log.Info("Region registration disabled.");
             }
         }
   
@@ -120,6 +111,20 @@ namespace OpenSim.Grid.GridServer
 //            Timer simCheckTimer = new Timer(3600000 * 3); // 3 Hours between updates.
 //            simCheckTimer.Elapsed += new ElapsedEventHandler(CheckSims);
 //            simCheckTimer.Enabled = true;
+
+            base.StartupSpecific();
+
+            m_console.Commands.AddCommand("gridserver", "enable registration",
+                    "enable registration",
+                    "Enable new regions to register", HandleRegistration);
+
+            m_console.Commands.AddCommand("gridserver", "disable registration",
+                    "disable registration",
+                    "Disable registering new regions", HandleRegistration);
+
+            m_console.Commands.AddCommand("gridserver", "show status",
+                    "show status",
+                    "Show registration status", HandleShowStatus);
         }
 
         protected void AddHttpHandlers()
diff --git a/OpenSim/Grid/InventoryServer/Main.cs b/OpenSim/Grid/InventoryServer/Main.cs
index 81a6a03..4727f6e 100644
--- a/OpenSim/Grid/InventoryServer/Main.cs
+++ b/OpenSim/Grid/InventoryServer/Main.cs
@@ -38,7 +38,7 @@ using OpenSim.Framework.Servers;
 
 namespace OpenSim.Grid.InventoryServer
 {
-    public class OpenInventory_Main : BaseOpenSimServer, conscmd_callback
+    public class OpenInventory_Main : BaseOpenSimServer
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -58,7 +58,7 @@ namespace OpenSim.Grid.InventoryServer
 
         public OpenInventory_Main()
         {
-            m_console = new ConsoleBase("Inventory", this);
+            m_console = new ConsoleBase("Inventory");
             MainConsole.Instance = m_console;
         }
 
@@ -77,6 +77,12 @@ namespace OpenSim.Grid.InventoryServer
             m_httpServer.Start();
 
             m_log.Info("[" + LogName + "]: Started HTTP server");
+
+            base.StartupSpecific();
+
+            m_console.Commands.AddCommand("inventoryserver", "add user",
+                    "add user",
+                    "Add a random user inventory", HandleAddUser);
         }
 
         protected void AddHttpHandlers()
@@ -146,16 +152,9 @@ namespace OpenSim.Grid.InventoryServer
             }
         }
 
-        public override void RunCmd(string cmd, string[] cmdparams)
+        private void HandleAddUser(string module, string[] args)
         {
-            base.RunCmd(cmd, cmdparams);
-
-            switch (cmd)
-            {
-                case "add-user":
-                    m_inventoryService.CreateUsersInventory(UUID.Random().Guid);
-                    break;
-            }
+            m_inventoryService.CreateUsersInventory(UUID.Random().Guid);
         }
     }
 }
diff --git a/OpenSim/Grid/MessagingServer/Main.cs b/OpenSim/Grid/MessagingServer/Main.cs
index e83da7a..9b7e731 100644
--- a/OpenSim/Grid/MessagingServer/Main.cs
+++ b/OpenSim/Grid/MessagingServer/Main.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Grid.MessagingServer
 {
     /// <summary>
     /// </summary>
-    public class OpenMessage_Main : BaseOpenSimServer, conscmd_callback
+    public class OpenMessage_Main : BaseOpenSimServer
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -64,7 +64,7 @@ namespace OpenSim.Grid.MessagingServer
 
         public OpenMessage_Main()
         {
-            m_console = new ConsoleBase("Messaging", this);
+            m_console = new ConsoleBase("Messaging");
             MainConsole.Instance = m_console;
         }
 
@@ -124,6 +124,16 @@ namespace OpenSim.Grid.MessagingServer
             registerWithUserServer();
 
             m_log.Info("[SERVER]: Messageserver 0.5 - Startup complete");
+
+            base.StartupSpecific();
+
+            m_console.Commands.AddCommand("messageserver", "clear cache",
+                    "clear cache",
+                    "Clear presence cache", HandleClearCache);
+
+            m_console.Commands.AddCommand("messageserver", "register",
+                    "register",
+                    "Re-register with user server(s)", HandleRegister);
         }
 
         public void do_create(string what)
@@ -154,29 +164,17 @@ namespace OpenSim.Grid.MessagingServer
             }
         }
 
-        public override void RunCmd(string cmd, string[] cmdparams)
+        private void HandleClearCache(string module, string[] cmd)
         {
-            base.RunCmd(cmd, cmdparams);
-
-            switch (cmd)
-            {
-                case "clear-cache":
-                    int entries = msgsvc.ClearRegionCache();
-                    m_console.Notice("Region cache cleared! Cleared " + entries.ToString() + " entries");
-                    break;
-                case "register":
-                    deregisterFromUserServer();
-                    registerWithUserServer();
-                    break;
-            }
+            int entries = msgsvc.ClearRegionCache();
+            m_console.Notice("Region cache cleared! Cleared " +
+                    entries.ToString() + " entries");
         }
-        
-        protected override void ShowHelp(string[] helpArgs)
+
+        private void HandleRegister(string module, string[] cmd)
         {
-            base.ShowHelp(helpArgs);
-            
-            m_console.Notice("clear-cache - Clears region cache.  Should be done when regions change position.  The region cache gets stale after a while.");
-            m_console.Notice("register    - (Re-)registers with user-server. This might be necessary if the userserver crashed/restarted"); 
+            deregisterFromUserServer();
+            registerWithUserServer();
         }
 
         public override void ShutdownSpecific()
diff --git a/OpenSim/Grid/UserServer/Main.cs b/OpenSim/Grid/UserServer/Main.cs
index be26ab3..0b0bee1 100644
--- a/OpenSim/Grid/UserServer/Main.cs
+++ b/OpenSim/Grid/UserServer/Main.cs
@@ -46,7 +46,7 @@ namespace OpenSim.Grid.UserServer
     /// <summary>
     /// Grid user server main class
     /// </summary>
-    public class OpenUser_Main : BaseOpenSimServer, conscmd_callback
+    public class OpenUser_Main : BaseOpenSimServer
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -73,7 +73,7 @@ namespace OpenSim.Grid.UserServer
 
         public OpenUser_Main()
         {
-            m_console = new ConsoleBase("User", this);
+            m_console = new ConsoleBase("User");
             MainConsole.Instance = m_console;
         }
 
@@ -119,6 +119,37 @@ namespace OpenSim.Grid.UserServer
             m_httpServer = new BaseHttpServer(Cfg.HttpPort);
             AddHttpHandlers();
             m_httpServer.Start();
+            
+            base.StartupSpecific();
+
+            m_console.Commands.AddCommand("userserver", "create user",
+                    "create user [<first> [<last> [<x> <y> [email]]]]",
+                    "Create a new user account", RunCommand);
+
+            m_console.Commands.AddCommand("userserver", "reset user password",
+                    "reset user password [<first> [<last> [<new password>]]]",
+                    "Reset a user's password", RunCommand);
+
+            m_console.Commands.AddCommand("userserver", "login level",
+                    "login level <level>",
+                    "Set the minimum user level to log in", HandleLoginCommand);
+
+            m_console.Commands.AddCommand("userserver", "login reset",
+                    "login reset",
+                    "Reset the login level to allow all users",
+                    HandleLoginCommand);
+
+            m_console.Commands.AddCommand("userserver", "login text",
+                    "login text <text>",
+                    "Set the text users will see on login", HandleLoginCommand);
+
+            m_console.Commands.AddCommand("userserver", "test-inventory",
+                    "test-inventory",
+                    "Perform a test inventory transaction", RunCommand);
+
+            m_console.Commands.AddCommand("userserver", "logoff-user",
+                    "logoff-user <first> <last> <message>",
+                    "Log off a named user", RunCommand);
         }
 
         /// <summary>
@@ -301,39 +332,54 @@ namespace OpenSim.Grid.UserServer
             m_userManager.ResetUserPassword(firstName, lastName, newPassword);
         }         
 
-        public override void RunCmd(string cmd, string[] cmdparams)
+        private void HandleLoginCommand(string module, string[] cmd)
         {
-            base.RunCmd(cmd, cmdparams);
-            switch (cmd)
+            string subcommand = cmd[1];
+            
+            switch (subcommand)
             {
-                case "create":
-                    do_create(cmdparams);
-                    break;
-                
-                case "reset":
-                    Reset(cmdparams);
-                    break;
-
-
-                case "login-level":
-                       // Set the minimal level to allow login 
-                       // Usefull to allow grid update without worrying about users.
-                       // or fixing critical issue
-                    if (cmdparams.Length == 1)
+                case "level":
+                    // Set the minimal level to allow login 
+                    // Useful to allow grid update without worrying about users.
+                    // or fixing critical issues
+                    //
+                    if (cmd.Length > 2)
                     {
-                        int level = Convert.ToInt32(cmdparams[0]);
+                        int level = Convert.ToInt32(cmd[2]);
                         m_loginService.setloginlevel(level);
                     }
                     break;
-                case "login-reset":
+                case "reset":
                      m_loginService.setloginlevel(0);
                     break;
-                case "login-text":
-                    if (cmdparams.Length == 1)
+                case "text":
+                    if (cmd.Length > 2)
                     {
-                        m_loginService.setwelcometext(cmdparams[0]);
+                        m_loginService.setwelcometext(cmd[2]);
                     }
                     break;
+            }
+        }
+
+        public void RunCommand(string module, string[] cmd)
+        {
+            List<string> args = new List<string>(cmd);
+            string command = cmd[0];
+
+            args.RemoveAt(0);
+
+            string[] cmdparams = args.ToArray();
+
+            switch (command)
+            {
+                case "create":
+                    do_create(cmdparams);
+                    break;
+                
+                case "reset":
+                    Reset(cmdparams);
+                    break;
+
 
                 case "test-inventory":
                     //  RestObjectPosterResponse<List<InventoryFolderBase>> requester = new RestObjectPosterResponse<List<InventoryFolderBase>>();
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index a8e1499..7a427dc 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -34,6 +34,7 @@ using log4net.Config;
 using Nini.Config;
 using OpenSim.Framework;
 using OpenSim.Framework.Console;
+using OpenSim.Region.Framework.Scenes;
 
 namespace OpenSim
 {
@@ -46,6 +47,8 @@ namespace OpenSim
         public static bool m_saveCrashDumps = false;
         public static string m_crashDir = "crashes";
 
+        protected static OpenSimBase m_sim = null;
+
         //could move our main function into OpenSimMain and kill this class
         public static void Main(string[] args)
         {
@@ -93,18 +96,18 @@ namespace OpenSim
 
             if (background)
             {
-                OpenSimBase sim = new OpenSimBackground(configSource);
-                sim.Startup();
+                m_sim = new OpenSimBackground(configSource);
+                m_sim.Startup();
             }
             else
             {
-                OpenSimBase sim = null;
+                m_sim = null;
                 if (hgrid)
-                    sim = new HGOpenSimNode(configSource);
+                    m_sim = new HGOpenSimNode(configSource);
                 else
-                    sim = new OpenSim(configSource);
+                    m_sim = new OpenSim(configSource);
 
-                sim.Startup();
+                m_sim.Startup();
 
                 while (true)
                 {
diff --git a/OpenSim/Region/Application/HGOpenSimNode.cs b/OpenSim/Region/Application/HGOpenSimNode.cs
index 4941fb4..2de9ddf 100644
--- a/OpenSim/Region/Application/HGOpenSimNode.cs
+++ b/OpenSim/Region/Application/HGOpenSimNode.cs
@@ -77,6 +77,9 @@ namespace OpenSim
             m_log.Info("====================================================================");
 
             base.StartupSpecific();
+
+            MainConsole.Instance.Commands.AddCommand("hypergrid", "link-mapping", "link-mapping [<x> <y>] <cr>", "Set local coordinate to map HG regions to", RunCommand);
+            MainConsole.Instance.Commands.AddCommand("hypergrid", "link-region", "link-region <Xloc> <Yloc> <HostName> <HttpPort> <LocalName> <cr>", "Link a hypergrid region", RunCommand);
         }
 
         protected override void InitialiseStandaloneServices(LibraryRootFolder libraryRootFolder)
@@ -143,11 +146,18 @@ namespace OpenSim
                     m_configSettings.See_into_region_from_neighbor, m_config.Source, m_version);
         }
 
-        public override void RunCmd(string command, string[] cmdparams)
+        public void RunCommand(string module, string[] cp)
         {
+            List<string> cmdparams = new List<string>(cp);
+            if (cmdparams.Count < 1)
+                return;
+
+            string command = cmdparams[0];
+            cmdparams.RemoveAt(0);
+
             if (command.Equals("link-mapping"))
             {
-                if (cmdparams.Length == 2)
+                if (cmdparams.Count == 2)
                 {
                     try
                     {
@@ -166,11 +176,11 @@ namespace OpenSim
             else if (command.Equals("link-region"))
             {
                 // link-region <Xloc> <Yloc> <HostName> <HttpPort> <LocalName>
-                if (cmdparams.Length < 4)
+                if (cmdparams.Count < 4)
                 {
-                    if ((cmdparams.Length == 1) || (cmdparams.Length ==2))
+                    if ((cmdparams.Count == 1) || (cmdparams.Count ==2))
                     {
-                        LoadXmlLinkFile(cmdparams);
+                        LoadXmlLinkFile(cmdparams.ToArray());
                     }
                     else
                     {
@@ -201,19 +211,16 @@ namespace OpenSim
 
                 if (TryCreateLink(xloc, yloc, externalPort, externalHostName, out regInfo))
                 {
-                    if (cmdparams.Length >= 5)
+                    if (cmdparams.Count >= 5)
                     {
                         regInfo.RegionName = "";
-                        for (int i = 4; i < cmdparams.Length; i++)
+                        for (int i = 4; i < cmdparams.Count; i++)
                             regInfo.RegionName += cmdparams[i] + " ";
                     }
                 }
 
                 return;
             }
-
-            base.RunCmd(command, cmdparams);
-
         }
 
         private void LoadXmlLinkFile(string[] cmdparams)
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index af42a3d..37066c2 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -49,7 +49,7 @@ namespace OpenSim
     /// <summary>
     /// Interactive OpenSim region server
     /// </summary>
-    public class OpenSim : OpenSimBase, conscmd_callback
+    public class OpenSim : OpenSimBase
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -59,11 +59,6 @@ namespace OpenSim
         private string m_timedScript = "disabled";
         private Timer m_scriptTimer;
 
-        /// <summary>
-        /// List of Console Plugin Commands
-        /// </summary>
-        private static List<ConsolePluginCommand> m_PluginCommandInfos = new List<ConsolePluginCommand>();
-
         public OpenSim(IConfigSource configSource) : base(configSource)
         {
         }
@@ -97,9 +92,189 @@ namespace OpenSim
             //GCSettings.LatencyMode = GCLatencyMode.Batch;
             //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString());
 
-            m_console = new ConsoleBase("Region", this);
+            m_console = new ConsoleBase("Region");
             MainConsole.Instance = m_console;
 
+            m_console.Commands.AddCommand("region", "clear assets",
+                    "clear assets",
+                    "Clear the asset cache", HandleClearAssets);
+
+            m_console.Commands.AddCommand("region", "force update",
+                    "force update",
+                    "Force the update of all objects on clients",
+                    HandleForceUpdate);
+
+            m_console.Commands.AddCommand("region", "debug packet",
+                    "debug packet <level>",
+                    "Turn on packet debugging", Debug);
+
+            m_console.Commands.AddCommand("region", "debug scene",
+                    "debug scene <cripting> <collisions> <physics>",
+                    "Turn on scene debugging", Debug);
+
+            m_console.Commands.AddCommand("region", "change region",
+                    "change region <region name>",
+                    "Change current console region", ChangeSelectedRegion);
+
+            m_console.Commands.AddCommand("region", "save xml",
+                    "save xml",
+                    "Save a region's data in XML format", SaveXml);
+
+            m_console.Commands.AddCommand("region", "save xml2",
+                    "save xml2",
+                    "Save a region's data in XML2 format", SaveXml2);
+
+            m_console.Commands.AddCommand("region", "load xml",
+                    "load xml [-newIDs [<x> <y> <z>]]",
+                    "Load a region's data from XML format", LoadXml);
+
+            m_console.Commands.AddCommand("region", "load xml2",
+                    "load xml2",
+                    "Load a region's data from XML2 format", LoadXml2);
+
+            m_console.Commands.AddCommand("region", "save prims xml2",
+                    "save prims xml2 [<prim name> <file name>]",
+                    "Save named prim to XML2", SavePrimsXml2);
+
+            m_console.Commands.AddCommand("region", "load oar",
+                    "load oar <oar name>",
+                    "Load a region's data from OAR archive", LoadOar);
+
+            m_console.Commands.AddCommand("region", "save oar",
+                    "save oar <oar name>",
+                    "Save a region's data to an OAR archive", SaveOar);
+
+            m_console.Commands.AddCommand("region", "save inventory",
+                    "save inventory <first> <last> <path> <file>",
+                    "Save user inventory data", SaveInv);
+
+            m_console.Commands.AddCommand("region", "load inventory",
+                    "load inventory <first> <last> <path> <file>",
+                    "Load user inventory data", LoadInv);
+
+            m_console.Commands.AddCommand("region", "edit scale",
+                    "edit scale <name> <x> <y> <z>",
+                    "Change the scale of a named prim", HandleEditScale);
+
+            m_console.Commands.AddCommand("region", "kick user",
+                    "kick user <first> <last>",
+                    "Kick a user off the simulator", HandleEditScale);
+
+            m_console.Commands.AddCommand("region", "show assets",
+                    "show assets",
+                    "Show asset data", HandleShow);
+
+            m_console.Commands.AddCommand("region", "show users",
+                    "show users [full]",
+                    "Show user data", HandleShow);
+
+            m_console.Commands.AddCommand("region", "show users full",
+                    "show users full",
+                    String.Empty, HandleShow);
+
+            m_console.Commands.AddCommand("region", "show modules",
+                    "show modules",
+                    "Show module data", HandleShow);
+
+            m_console.Commands.AddCommand("region", "show regions",
+                    "show regions",
+                    "Show region data", HandleShow);
+
+            m_console.Commands.AddCommand("region", "show queues",
+                    "show queues",
+                    "Show queue data", HandleShow);
+
+            m_console.Commands.AddCommand("region", "alert",
+                    "alert <first> <last> <message>",
+                    "Send an alert to a user", RunCommand);
+
+            m_console.Commands.AddCommand("region", "alert general",
+                    "alert general <message>",
+                    "Send an alert everyone", RunCommand);
+
+            m_console.Commands.AddCommand("region", "backup",
+                    "backup",
+                    "Persist objects to the database now", RunCommand);
+
+            m_console.Commands.AddCommand("region", "create region",
+                    "create region",
+                    "Create a new region", HandleCreateRegion);
+
+            m_console.Commands.AddCommand("region", "login enable",
+                    "login enable",
+                    "Enable logins to the simulator", HandleLoginEnable);
+
+            m_console.Commands.AddCommand("region", "login disable",
+                    "login disable",
+                    "Disable logins to the simulator", HandleLoginDisable);
+
+            m_console.Commands.AddCommand("region", "login status",
+                    "login status",
+                    "Display status of logins", HandleLoginStatus);
+
+            m_console.Commands.AddCommand("region", "restart",
+                    "restart",
+                    "Restart all sims in this instance", RunCommand);
+
+            m_console.Commands.AddCommand("region", "config set",
+                    "config set <section> <field> <value>",
+                    "Set a config option", HandleConfig);
+
+            m_console.Commands.AddCommand("region", "config get",
+                    "config get <section> <field>",
+                    "Read a config option", HandleConfig);
+
+            m_console.Commands.AddCommand("region", "config save",
+                    "config save",
+                    "Save current configuration", HandleConfig);
+
+            m_console.Commands.AddCommand("region", "command-script",
+                    "command-script <script>",
+                    "Run a command script from file", RunCommand);
+
+            m_console.Commands.AddCommand("region", "export-map",
+                    "export-map <file>",
+                    "Save an image of the world map", RunCommand);
+
+            m_console.Commands.AddCommand("region", "remove-region",
+                    "remove-region <name>",
+                    "Remove a region from this simulator", RunCommand);
+
+            m_console.Commands.AddCommand("region", "delete-region",
+                    "delete-region <name>",
+                    "Delete a region from disk", RunCommand);
+
+            m_console.Commands.AddCommand("region", "predecode-j2k",
+                    "predecode-j2k [<num threads>]>",
+                    "Precache assets,decode j2k layerdata", RunCommand);
+
+            m_console.Commands.AddCommand("region", "modules list",
+                    "modules list",
+                    "List modules", HandleModules);
+
+            m_console.Commands.AddCommand("region", "modules load",
+                    "modules load <name>",
+                    "Load a module", HandleModules);
+
+            m_console.Commands.AddCommand("region", "modules unload",
+                    "modules unload <name>",
+                    "Unload a module", HandleModules);
+
+            m_console.Commands.AddCommand("region", "Add-InventoryHost",
+                    "Add-InventoryHost <host>",
+                    String.Empty, RunCommand);
+
+            if (ConfigurationSettings.Standalone)
+            {
+                m_console.Commands.AddCommand("region", "create user",
+                        "create user [<first> [<last> [<pass> [<x> <y> [<email>]]]]]",
+                        "Create a new user", HandleCreateUser);
+
+                m_console.Commands.AddCommand("region", "reset user password",
+                        "reset user password [<first> [<last> [<password>]]]",
+                        "Reset a user password", HandleResetUserPassword);
+            }
+
             base.StartupSpecific();
 
             //Run Startup Commands
@@ -122,11 +297,9 @@ namespace OpenSim
             }
 
             PrintFileToConsole("startuplogo.txt");
-            RegisterCmd("echoTest", RunEchoTest, "this echos your command args to see how they are parsed");
-            RegisterCmd("kickuser", KickUserCommand, "kickuser [first] [last] - attempts to log off a user from any region we are serving");
 
             // For now, start at the 'root' level by default
-            ChangeSelectedRegion(new string[] {"root"});
+            ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
         }
 
         public override void ShutdownSpecific()
@@ -148,17 +321,9 @@ namespace OpenSim
 
         #region Console Commands
 
-        private void RunEchoTest(string[] cmdparams)
+        private void KickUserCommand(string module, string[] cmdparams)
         {
-            for (int i = 0; i < cmdparams.Length; i++)
-            {
-                m_log.Info("[EchoTest]:  <arg" + i + ">"+cmdparams[i]+"</arg" + i + ">");
-            }
-        }
-
-        private void KickUserCommand(string[] cmdparams)
-        {
-            if (cmdparams.Length < 2)
+            if (cmdparams.Length < 4)
                 return;
 
             IList agents = m_sceneManager.GetCurrentSceneAvatars();
@@ -167,7 +332,7 @@ namespace OpenSim
             {
                 RegionInfo regionInfo = m_sceneManager.GetRegionInfo(presence.RegionHandle);
 
-                if (presence.Firstname.ToLower().Contains(cmdparams[0].ToLower()) && presence.Lastname.ToLower().Contains(cmdparams[1].ToLower()))
+                if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && presence.Lastname.ToLower().Contains(cmdparams[3].ToLower()))
                 {
                     m_console.Notice(
                         String.Format(
@@ -219,302 +384,261 @@ namespace OpenSim
             }
         }
 
-        /// <summary>
-        /// Runs commands issued by the server console from the operator
-        /// </summary>
-        /// <param name="command">The first argument of the parameter (the command)</param>
-        /// <param name="cmdparams">Additional arguments passed to the command</param>
-        public override void RunCmd(string command, string[] cmdparams)
+        private void HandleClearAssets(string module, string[] args)
         {
-            base.RunCmd(command, cmdparams);
-            RunPluginCommands(command , cmdparams);
-
-            switch (command)
-            {
-                case "clear-assets":
-                    m_assetCache.Clear();
-                    break;
-
-                case "force-update":
-                    m_console.Notice("Updating all clients");
-                    m_sceneManager.ForceCurrentSceneClientUpdate();
-                    break;
-
-                case "edit-scale":
-                    if (cmdparams.Length == 4)
-                    {
-                        m_sceneManager.HandleEditCommandOnCurrentScene(cmdparams);
-                    }
-                    break;
-
-                case "debug":
-                    Debug(cmdparams);
-                    break;
-
-                case "save-xml":
-                    SaveXml(cmdparams);
-                    break;
-
-                case "load-xml":
-                    LoadXml(cmdparams);
-                    break;
-
-                case "save-xml2":
-                    SaveXml2(cmdparams);
-                    break;
+            m_assetCache.Clear();
+        }
 
-                case "load-xml2":
-                    LoadXml2(cmdparams);
-                    break;
+        private void HandleForceUpdate(string module, string[] args)
+        {
+            m_console.Notice("Updating all clients");
+            m_sceneManager.ForceCurrentSceneClientUpdate();
+        }
 
-                case "save-prims-xml2":
-                    if (cmdparams.Length > 1)
-                    {
-                        m_sceneManager.SaveNamedPrimsToXml2(cmdparams[0], cmdparams[1]);
-                    }
-                    else
-                    {
-                        m_sceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
-                    }
-                    break;
+        private void HandleEditScale(string module, string[] args)
+        {
+            if (args.Length == 5)
+            {
+                m_sceneManager.HandleEditCommandOnCurrentScene(args);
+            }
+            else
+            {
+                m_console.Notice("Argument error: edit scale <prim name> <x> <y> <z>");
+            }
+        }
 
-                case "load-oar":
-                    LoadOar(cmdparams);
-                    break;
+        private void HandleCreateRegion(string module, string[] cmd)
+        {
+            if (cmd.Length < 4)
+            {
+                m_console.Error("Usage: create region <region name> <region_file.xml>");
+                return;
+            }
 
-                case "save-oar":
-                    SaveOar(cmdparams);
-                    break;
+            string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim();
+            string regionFile = String.Format("{0}/{1}", regionsDir, cmd[3]);
+            // Allow absolute and relative specifiers
+            if (cmd[3].StartsWith("/") || cmd[3].StartsWith("\\") || cmd[3].StartsWith(".."))
+                regionFile = cmd[3];
 
-                case "save-inv":
-                    SaveInv(cmdparams);
-                    break;
+            CreateRegion(new RegionInfo(cmd[2], regionFile, false, ConfigSource.Source), true);
+        }
 
-                case "load-inv":
-                    LoadInv(cmdparams);
-                    break;
+        private void HandleLoginEnable(string module, string[] cmd)
+        {
+            ProcessLogin(true);
+        }
 
-                case "plugin":
-                    m_sceneManager.SendCommandToPluginModules(cmdparams);
-                    break;
+        private void HandleLoginDisable(string module, string[] cmd)
+        {
+            ProcessLogin(false);
+        }
 
-                case "command-script":
-                    if (cmdparams.Length > 0)
-                    {
-                        RunCommandScript(cmdparams[0]);
-                    }
-                    break;
+        private void HandleLoginStatus(string module, string[] cmd)
+        {
+            if (m_commsManager.GridService.RegionLoginsEnabled == false)
 
-                case "backup":
-                    m_sceneManager.BackupCurrentScene();
-                    break;
+                m_log.Info("[ Login ]  Login are disabled ");
+            else
+                m_log.Info("[ Login ]  Login are enabled");
+        }
 
-                case "alert":
-                    m_sceneManager.HandleAlertCommandOnCurrentScene(cmdparams);
-                    break;
+        private void HandleConfig(string module, string[] cmd)
+        {
+            List<string> args = new List<string>(cmd);
+            args.RemoveAt(0);
+            string[] cmdparams = args.ToArray();
+            string n = "CONFIG";
 
-                case "create":
-                    Create(cmdparams);
-                    break;
+            if (cmdparams.Length > 0)
+            {
+                switch (cmdparams[0].ToLower())
+                {
+                    case "set":
+                        if (cmdparams.Length < 4)
+                        {
+                            m_console.Error(n, "SYNTAX: " + n + " SET SECTION KEY VALUE");
+                            m_console.Error(n, "EXAMPLE: " + n + " SET ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
+                        }
+                        else
+                        {
+                           // IConfig c = DefaultConfig().Configs[cmdparams[1]];
+                           // if (c == null)
+                           //     c = DefaultConfig().AddConfig(cmdparams[1]);
+                            IConfig c;
+                            IConfigSource source = new IniConfigSource();
+                            c = source.AddConfig(cmdparams[1]);
+                            if (c != null)
+                            {
+                                string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
+                                c.Set(cmdparams[2], _value);
+                                m_config.Source.Merge(source);
 
-                case "login-enable":
-                    ProcessLogin(true);
-                    break;
-                case "login-disable":
-                    ProcessLogin(false);
-                    break;
-                case "login-status":
-                    if (m_commsManager.GridService.RegionLoginsEnabled == false)
+                                m_console.Error(n, n + " " + n + " " + cmdparams[1] + " " + cmdparams[2] + " " +
+                                                _value);
+                            }
+                        }
+                        break;
+                    case "get":
+                        if (cmdparams.Length < 3)
+                        {
+                            m_console.Error(n, "SYNTAX: " + n + " GET SECTION KEY");
+                            m_console.Error(n, "EXAMPLE: " + n + " GET ScriptEngine.DotNetEngine NumberOfScriptThreads");
+                        }
+                        else
+                        {
+                            IConfig c = m_config.Source.Configs[cmdparams[1]]; // DefaultConfig().Configs[cmdparams[1]];
+                            if (c == null)
+                            {
+                                m_console.Notice(n, "Section \"" + cmdparams[1] + "\" does not exist.");
+                                break;
+                            }
+                            else
+                            {
+                                m_console.Notice(n + " GET " + cmdparams[1] + " " + cmdparams[2] + ": " +
+                                                 c.GetString(cmdparams[2]));
+                            }
+                        }
 
-                        m_log.Info("[ Login ]  Login are disabled ");
-                    else
-                        m_log.Info("[ Login ]  Login are enabled");
-                    break;
-                case "create-region":
-                    if (cmdparams.Length < 2)
-                    {
-                        m_console.Error("Usage: create-region <region name> <region_file.xml>");
                         break;
-                    }
+                    case "save":
+                        m_console.Notice("Saving configuration file: " + Application.iniFilePath);
+                        m_config.Save(Application.iniFilePath);
+                        break;
+                }
+            }
+        }
 
-                    string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim();
-                    string regionFile = String.Format("{0}/{1}", regionsDir, cmdparams[1]);
-                    // Allow absolute and relative specifiers
-                    if (cmdparams[1].StartsWith("/") || cmdparams[1].StartsWith("\\") || cmdparams[1].StartsWith(".."))
-                        regionFile = cmdparams[1];
+        private void HandleModules(string module, string[] cmd)
+        {
+            List<string> args = new List<string>(cmd);
+            args.RemoveAt(0);
+            string[] cmdparams = args.ToArray();
 
-                    CreateRegion(new RegionInfo(cmdparams[0], regionFile, false, ConfigSource.Source), true);
-                    break;
+            if (cmdparams.Length > 0)
+            {
+                switch (cmdparams[0].ToLower())
+                {
+                    case "list":
+                        foreach (IRegionModule irm in m_moduleLoader.GetLoadedSharedModules)
+                        {
+                            m_console.Notice("Shared region module: " + irm.Name);
+                        }
+                        break;
+                    case "unload":
+                        if (cmdparams.Length > 1)
+                        {
+                            foreach (IRegionModule rm in new ArrayList(m_moduleLoader.GetLoadedSharedModules))
+                            {
+                                if (rm.Name.ToLower() == cmdparams[1].ToLower())
+                                {
+                                    m_console.Notice("Unloading module: " + rm.Name);
+                                    m_moduleLoader.UnloadModule(rm);
+                                }
+                            }
+                        }
+                        break;
+                    case "load":
+                        if (cmdparams.Length > 1)
+                        {
+                            foreach (Scene s in new ArrayList(m_sceneManager.Scenes))
+                            {
 
-                case "remove-region":
-                    string regRemoveName = CombineParams(cmdparams, 0);
+                                m_console.Notice("Loading module: " + cmdparams[1]);
+                                m_moduleLoader.LoadRegionModules(cmdparams[1], s);
+                            }
+                        }
+                        break;
+                }
+            }
+        }
 
-                    Scene removeScene;
-                    if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
-                        RemoveRegion(removeScene, false);
-                    else
-                        m_console.Error("no region with that name");
-                    break;
 
-                case "delete-region":
-                    string regDeleteName = CombineParams(cmdparams, 0);
+        /// <summary>
+        /// Runs commands issued by the server console from the operator
+        /// </summary>
+        /// <param name="command">The first argument of the parameter (the command)</param>
+        /// <param name="cmdparams">Additional arguments passed to the command</param>
+        public void RunCommand(string module, string[] cmdparams)
+        {
+            List<string> args = new List<string>(cmdparams);
+            if (args.Count < 1)
+                return;
 
-                    Scene killScene;
-                    if (m_sceneManager.TryGetScene(regDeleteName, out killScene))
-                        RemoveRegion(killScene, true);
-                    else
-                        m_console.Error("no region with that name");
-                    break;
+            string command = args[0];
+            args.RemoveAt(0);
 
-                case "restart":
-                    m_sceneManager.RestartCurrentScene();
-                    break;
+            cmdparams = args.ToArray();
 
-                case "change-region":
-                    ChangeSelectedRegion(cmdparams);
-                    break;
+            switch (command)
+            {
+            case "command-script":
+                if (cmdparams.Length > 0)
+                {
+                    RunCommandScript(cmdparams[0]);
+                }
+                break;
 
-                case "export-map":
-                    if (cmdparams.Length > 0)
-                    {
-                        m_sceneManager.CurrentOrFirstScene.ExportWorldMap(cmdparams[0]);
-                    }
-                    else
-                    {
-                        m_sceneManager.CurrentOrFirstScene.ExportWorldMap("exportmap.jpg");
-                    }
-                    break;
+            case "backup":
+                m_sceneManager.BackupCurrentScene();
+                break;
 
-                case "config":
-                    string n = command.ToUpper();
-                    if (cmdparams.Length > 0)
-                    {
-                        switch (cmdparams[0].ToLower())
-                        {
-                            case "set":
-                                if (cmdparams.Length < 4)
-                                {
-                                    m_console.Error(n, "SYNTAX: " + n + " SET SECTION KEY VALUE");
-                                    m_console.Error(n, "EXAMPLE: " + n + " SET ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
-                                }
-                                else
-                                {
-                                   // IConfig c = DefaultConfig().Configs[cmdparams[1]];
-                                   // if (c == null)
-                                   //     c = DefaultConfig().AddConfig(cmdparams[1]);
-                                    IConfig c;
-                                    IConfigSource source = new IniConfigSource();
-                                    c = source.AddConfig(cmdparams[1]);
-                                    if (c != null)
-                                    {
-                                        string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
-                                        c.Set(cmdparams[2], _value);
-                                        m_config.Source.Merge(source);
-
-                                        m_console.Error(n, n + " " + n + " " + cmdparams[1] + " " + cmdparams[2] + " " +
-                                                        _value);
-                                    }
-                                }
-                                break;
-                            case "get":
-                                if (cmdparams.Length < 3)
-                                {
-                                    m_console.Error(n, "SYNTAX: " + n + " GET SECTION KEY");
-                                    m_console.Error(n, "EXAMPLE: " + n + " GET ScriptEngine.DotNetEngine NumberOfScriptThreads");
-                                }
-                                else
-                                {
-                                    IConfig c = m_config.Source.Configs[cmdparams[1]]; // DefaultConfig().Configs[cmdparams[1]];
-                                    if (c == null)
-                                    {
-                                        m_console.Notice(n, "Section \"" + cmdparams[1] + "\" does not exist.");
-                                        break;
-                                    }
-                                    else
-                                    {
-                                        m_console.Notice(n + " GET " + cmdparams[1] + " " + cmdparams[2] + ": " +
-                                                         c.GetString(cmdparams[2]));
-                                    }
-                                }
+            case "alert":
+                m_sceneManager.HandleAlertCommandOnCurrentScene(cmdparams);
+                break;
 
-                                break;
-                            case "save":
-                                m_console.Notice("Saving configuration file: " + Application.iniFilePath);
-                                m_config.Save(Application.iniFilePath);
-                                break;
-                        }
-                    }
-                    break;
+            case "remove-region":
+                string regRemoveName = CombineParams(cmdparams, 0);
 
-                case "modules":
-                    if (cmdparams.Length > 0)
-                    {
-                        switch (cmdparams[0].ToLower())
-                        {
-                            case "list":
-                                foreach (IRegionModule irm in m_moduleLoader.GetLoadedSharedModules)
-                                {
-                                    m_console.Notice("Shared region module: " + irm.Name);
-                                }
-                                break;
-                            case "unload":
-                                if (cmdparams.Length > 1)
-                                {
-                                    foreach (IRegionModule rm in new ArrayList(m_moduleLoader.GetLoadedSharedModules))
-                                    {
-                                        if (rm.Name.ToLower() == cmdparams[1].ToLower())
-                                        {
-                                            m_console.Notice("Unloading module: " + rm.Name);
-                                            m_moduleLoader.UnloadModule(rm);
-                                        }
-                                    }
-                                }
-                                break;
-                            case "load":
-                                if (cmdparams.Length > 1)
-                                {
-                                    foreach (Scene s in new ArrayList(m_sceneManager.Scenes))
-                                    {
+                Scene removeScene;
+                if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
+                    RemoveRegion(removeScene, false);
+                else
+                    m_console.Error("no region with that name");
+                break;
 
-                                        m_console.Notice("Loading module: " + cmdparams[1]);
-                                        m_moduleLoader.LoadRegionModules(cmdparams[1], s);
-                                    }
-                                }
-                                break;
-                        }
-                    }
+            case "delete-region":
+                string regDeleteName = CombineParams(cmdparams, 0);
 
-                    break;
+                Scene killScene;
+                if (m_sceneManager.TryGetScene(regDeleteName, out killScene))
+                    RemoveRegion(killScene, true);
+                else
+                    m_console.Error("no region with that name");
+                break;
 
-                case "Add-InventoryHost":
-                    if (cmdparams.Length > 0)
-                    {
-                        m_commsManager.AddInventoryService(cmdparams[0]);
-                    }
-                    break;
+            case "restart":
+                m_sceneManager.RestartCurrentScene();
+                break;
 
-                case "reset":
-                    Reset(cmdparams);
-                    break;
-                
-                case "predecode-j2k":
-                    if (cmdparams.Length > 0)
-                    {
-                        m_sceneManager.CacheJ2kDecode(Convert.ToInt32(cmdparams[0]));
-                    }
-                    else
-                    {
-                        m_sceneManager.CacheJ2kDecode(1);
-                    }
-                    break;
+            case "export-map":
+                if (cmdparams.Length > 0)
+                {
+                    m_sceneManager.CurrentOrFirstScene.ExportWorldMap(cmdparams[0]);
+                }
+                else
+                {
+                    m_sceneManager.CurrentOrFirstScene.ExportWorldMap("exportmap.jpg");
+                }
+                break;
 
-                default:
-                    string[] tmpPluginArgs = new string[cmdparams.Length + 1];
-                    cmdparams.CopyTo(tmpPluginArgs, 1);
-                    tmpPluginArgs[0] = command;
+            case "Add-InventoryHost":
+                if (cmdparams.Length > 0)
+                {
+                    m_commsManager.AddInventoryService(cmdparams[0]);
+                }
+                break;
 
-                    m_sceneManager.SendCommandToPluginModules(tmpPluginArgs);
-                    break;
+            case "predecode-j2k":
+                if (cmdparams.Length > 0)
+                {
+                    m_sceneManager.CacheJ2kDecode(Convert.ToInt32(cmdparams[0]));
+                }
+                else
+                {
+                    m_sceneManager.CacheJ2kDecode(1);
+                }
+                break;
             }
         }
 
@@ -522,46 +646,39 @@ namespace OpenSim
         /// Change the currently selected region.  The selected region is that operated upon by single region commands.
         /// </summary>
         /// <param name="cmdParams"></param>
-        protected void ChangeSelectedRegion(string[] cmdparams)
+        protected void ChangeSelectedRegion(string module, string[] cmdparams)
         {
-            if (cmdparams.Length > 0)
+            if (cmdparams.Length > 2)
             {
-                string newRegionName = CombineParams(cmdparams, 0);
+                string newRegionName = CombineParams(cmdparams, 2);
 
                 if (!m_sceneManager.TrySetCurrentScene(newRegionName))
                     m_console.Error("Couldn't select region " + newRegionName);
             }
             else
             {
-                m_console.Error("Usage: change-region <region name>");
+                m_console.Error("Usage: change region <region name>");
             }
 
             string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
             m_console.Notice(String.Format("Currently selected region is {0}", regionName));
             m_console.DefaultPrompt = String.Format("Region ({0}) ", regionName);
+            m_console.ConsoleScene = m_sceneManager.CurrentScene;
         }
 
         /// <summary>
         /// Execute switch for some of the create commands
         /// </summary>
         /// <param name="args"></param>
-        protected void Create(string[] args)
+        private void HandleCreateUser(string module, string[] cmd)
         {
-            if (args.Length == 0)
-                return;
-
-            switch (args[0])
+            if (ConfigurationSettings.Standalone)
             {
-                case "user":
-                    if (ConfigurationSettings.Standalone)
-                    {
-                        CreateUser(args);
-                    }
-                    else
-                    {
-                        m_console.Notice("Create user is not available in grid mode, use the user server.");
-                    }
-                    break;
+                CreateUser(cmd);
+            }
+            else
+            {
+                m_console.Notice("Create user is not available in grid mode, use the user server.");
             }
         }
 
@@ -569,30 +686,15 @@ namespace OpenSim
         /// Execute switch for some of the reset commands
         /// </summary>
         /// <param name="args"></param>
-        protected void Reset(string[] args)
+        protected void HandleResetUserPassword(string module, string[] cmd)
         {
-            if (args.Length == 0)
-                return;
-
-            switch (args[0])
+            if (ConfigurationSettings.Standalone)
             {
-                case "user":
-
-                    switch (args[1])
-                    {
-                        case "password":
-                            if (ConfigurationSettings.Standalone)
-                            {
-                                ResetUserPassword(args);
-                            }
-                            else
-                            {
-                                m_console.Notice("Reset user password is not available in grid mode, use the user-server.");
-                            }
-                            break;
-                    }
-
-                    break;
+                ResetUserPassword(cmd);
+            }
+            else
+            {
+                m_console.Notice("Reset user password is not available in grid mode, use the user-server.");
             }
         }
 
@@ -600,18 +702,18 @@ namespace OpenSim
         /// Turn on some debugging values for OpenSim.
         /// </summary>
         /// <param name="args"></param>
-        protected void Debug(string[] args)
+        protected void Debug(string module, string[] args)
         {
-            if (args.Length == 0)
+            if (args.Length == 1)
                 return;
 
-            switch (args[0])
+            switch (args[1])
             {
                 case "packet":
-                    if (args.Length > 1)
+                    if (args.Length > 2)
                     {
                         int newDebug;
-                        if (int.TryParse(args[1], out newDebug))
+                        if (int.TryParse(args[2], out newDebug))
                         {
                             m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug);
                         }
@@ -625,17 +727,17 @@ namespace OpenSim
                     break;
 
                 case "scene":
-                    if (args.Length == 4)
+                    if (args.Length == 5)
                     {
                         if (m_sceneManager.CurrentScene == null)
                         {
-                            m_console.Error("CONSOLE", "Please use 'change-region <regioname>' first");
+                            m_console.Notice("Please use 'change region <regioname>' first");
                         }
                         else
                         {
-                            bool scriptingOn = !Convert.ToBoolean(args[1]);
-                            bool collisionsOn = !Convert.ToBoolean(args[2]);
-                            bool physicsOn = !Convert.ToBoolean(args[3]);
+                            bool scriptingOn = !Convert.ToBoolean(args[2]);
+                            bool collisionsOn = !Convert.ToBoolean(args[3]);
+                            bool physicsOn = !Convert.ToBoolean(args[4]);
                             m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn);
 
                             m_console.Notice(
@@ -658,87 +760,12 @@ namespace OpenSim
             }
         }
 
-        protected override void ShowHelp(string[] helpArgs)
-        {
-            base.ShowHelp(helpArgs);
-
-            if (helpArgs.Length == 0)
-            {            
-                m_console.Notice("alert - send alert to a designated user or all users.");
-                m_console.Notice("  alert [First] [Last] [Message] - send an alert to a user. Case sensitive.");
-                m_console.Notice("  alert general [Message] - send an alert to all users.");
-                m_console.Notice("backup - persist simulator objects to the database ahead of the normal schedule.");
-                m_console.Notice("clear-assets - clear the asset cache");
-                m_console.Notice("create-region <name> <regionfile.xml> - create a new region");
-                m_console.Notice("change-region <name> - select the region that single region commands operate upon.");
-                m_console.Notice("command-script [filename] - Execute command in a file.");
-                m_console.Notice("debug - debugging commands");
-                m_console.Notice("  debug packet 0..255 - print incoming/outgoing packets (0=off)");
-                m_console.Notice("  debug scene [scripting] [collision] [physics] - Enable/Disable debug stuff, each can be True/False");
-                m_console.Notice("edit-scale [prim name] [x] [y] [z] - resize given prim");
-                m_console.Notice("export-map [filename] - save image of world map");
-                m_console.Notice("force-update - force an update of prims in the scene");
-                m_console.Notice("restart - disconnects all clients and restarts the sims in the instance.");
-                m_console.Notice("remove-region [name] - remove a region");
-                m_console.Notice("delete-region [name] - delete a region and its associated region file");
-                m_console.Notice("load-xml [filename] - load prims from XML (DEPRECATED)");
-                m_console.Notice("save-xml [filename] - save prims to XML (DEPRECATED)");
-                m_console.Notice("save-xml2 [filename] - save prims to XML using version 2 format");
-                m_console.Notice("load-xml2 [filename] - load prims from XML using version 2 format");
-                m_console.Notice("load-oar [filename] - load an OpenSimulator region archive.  This replaces everything in the current region.");
-                m_console.Notice("save-oar [filename] - Save the current region to an OpenSimulator region archive.");
-                m_console.Notice("script - manually trigger scripts? or script commands?");
-                m_console.Notice("show assets - show state of asset cache.");
-                m_console.Notice("show modules - shows info about loaded modules.");
-                m_console.Notice("show queues - show packet queues length for all clients.");
-                m_console.Notice("show regions - show running region information.");
-                m_console.Notice("show users - show info about connected users (only root agents).");
-                m_console.Notice("show users full - show info about connected users (root and child agents).");
-                m_console.Notice("config set section field value - set a config value");
-                m_console.Notice("config get section field - get a config value");
-                m_console.Notice("config save - save OpenSim.ini");
-                m_console.Notice("login-enable  - Allows login at sim level");
-                m_console.Notice("login-disable - Disable login at sim level");
-                m_console.Notice("login-status  - Show the actual login status");
-                m_console.Notice("predecode-j2k - Precache assets,decode j2k layerdata, First parameter is threads to use");
-                ShowPluginCommandsHelp(CombineParams(helpArgs, 0), m_console);                
-
-                if (ConfigurationSettings.Standalone)
-                {
-                    m_console.Notice("");
-                    m_console.Notice("create user - adds a new user.");
-                    m_console.Notice("reset user password - reset a user's password.");
-                }                                                
-            }
-            else
-            {
-                // Messily we want to join all the help params back here
-                //string helpSubject = string.Join(" ", helpArgs);
-                
-                // FIXME: Very cheap hack to get transition help working.  Will disappear very shortly.
-                if (helpArgs.Length == 1)
-                {
-                    ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(helpArgs[0]);
-                    if (moduleCommander != null)
-                    {
-                        m_console.Notice(moduleCommander.Help);
-                    }
-                }
-                else
-                {
-                    ICommand command = SceneManager.CurrentOrFirstScene.GetCommand(helpArgs[1]);
-                    if (command != null)
-                    {
-                        m_console.Notice(command.Help);
-                    }
-                }
-            }                            
-        }
-
         // see BaseOpenSimServer
-        public override void Show(string[] showParams)
+        private void HandleShow(string mod, string[] cmd)
         {
-            base.Show(showParams);
+            List<string> args = new List<string>(cmd);
+            args.RemoveAt(0);
+            string[] showParams = args.ToArray();
 
             switch (showParams[0])
             {
@@ -864,29 +891,29 @@ namespace OpenSim
             uint regX = 1000;
             uint regY = 1000;
 
-            if (cmdparams.Length < 2)
+            if (cmdparams.Length < 3)
                 firstName = MainConsole.Instance.CmdPrompt("First name", "Default");
-            else firstName = cmdparams[1];
+            else firstName = cmdparams[2];
 
-            if ( cmdparams.Length < 3 )
+            if ( cmdparams.Length < 4 )
                 lastName = MainConsole.Instance.CmdPrompt("Last name", "User");
-            else lastName = cmdparams[2];
+            else lastName = cmdparams[3];
 
-            if (cmdparams.Length < 4)
+            if (cmdparams.Length < 5)
                 password = MainConsole.Instance.PasswdPrompt("Password");
-            else password = cmdparams[3];
+            else password = cmdparams[4];
 
-            if ( cmdparams.Length < 5 )
+            if ( cmdparams.Length < 6 )
                 regX = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region X", regX.ToString()));
-            else regX = Convert.ToUInt32(cmdparams[4]);
+            else regX = Convert.ToUInt32(cmdparams[5]);
 
-            if ( cmdparams.Length < 6 )
+            if ( cmdparams.Length < 7 )
                 regY = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region Y", regY.ToString()));
-            else regY = Convert.ToUInt32(cmdparams[5]);
+            else regY = Convert.ToUInt32(cmdparams[6]);
 
-            if (cmdparams.Length < 7)
+            if (cmdparams.Length < 8)
                 email = MainConsole.Instance.CmdPrompt("Email", "");
-            else email = cmdparams[6];
+            else email = cmdparams[7];
 
             if (null == m_commsManager.UserService.GetUserProfile(firstName, lastName))
             {
@@ -908,28 +935,40 @@ namespace OpenSim
             string lastName;
             string newPassword;
 
-            if (cmdparams.Length < 3)
+            if (cmdparams.Length < 4)
                 firstName = MainConsole.Instance.CmdPrompt("First name");
-            else firstName = cmdparams[2];
+            else firstName = cmdparams[3];
 
-            if ( cmdparams.Length < 4 )
+            if ( cmdparams.Length < 5 )
                 lastName = MainConsole.Instance.CmdPrompt("Last name");
-            else lastName = cmdparams[3];
+            else lastName = cmdparams[4];
 
-            if ( cmdparams.Length < 5 )
+            if ( cmdparams.Length < 6 )
                 newPassword = MainConsole.Instance.PasswdPrompt("New password");
-            else newPassword = cmdparams[4];
+            else newPassword = cmdparams[5];
 
             m_commsManager.UserAdminService.ResetUserPassword(firstName, lastName, newPassword);
         }
 
-        protected void SaveXml(string[] cmdparams)
+        protected void SavePrimsXml2(string module, string[] cmdparams)
+        {
+            if (cmdparams.Length > 5)
+            {
+                m_sceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
+            }
+            else
+            {
+                m_sceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
+            }
+        }
+
+        protected void SaveXml(string module, string[] cmdparams)
         {
             m_log.Error("[CONSOLE]: PLEASE NOTE, save-xml is DEPRECATED and may be REMOVED soon.  If you are using this and there is some reason you can't use save-xml2, please file a mantis detailing the reason.");
 
             if (cmdparams.Length > 0)
             {
-                m_sceneManager.SaveCurrentSceneToXml(cmdparams[0]);
+                m_sceneManager.SaveCurrentSceneToXml(cmdparams[2]);
             }
             else
             {
@@ -937,30 +976,30 @@ namespace OpenSim
             }
         }
 
-        protected void LoadXml(string[] cmdparams)
+        protected void LoadXml(string module, string[] cmdparams)
         {
             m_log.Error("[CONSOLE]: PLEASE NOTE, load-xml is DEPRECATED and may be REMOVED soon.  If you are using this and there is some reason you can't use load-xml2, please file a mantis detailing the reason.");
 
             Vector3 loadOffset = new Vector3(0, 0, 0);
-            if (cmdparams.Length > 0)
+            if (cmdparams.Length > 2)
             {
                 bool generateNewIDS = false;
-                if (cmdparams.Length > 1)
+                if (cmdparams.Length > 3)
                 {
-                    if (cmdparams[1] == "-newUID")
+                    if (cmdparams[3] == "-newUID")
                     {
                         generateNewIDS = true;
                     }
-                    if (cmdparams.Length > 2)
+                    if (cmdparams.Length > 4)
                     {
-                        loadOffset.X = (float) Convert.ToDecimal(cmdparams[2]);
-                        if (cmdparams.Length > 3)
+                        loadOffset.X = (float) Convert.ToDecimal(cmdparams[4]);
+                        if (cmdparams.Length > 5)
                         {
-                            loadOffset.Y = (float) Convert.ToDecimal(cmdparams[3]);
+                            loadOffset.Y = (float) Convert.ToDecimal(cmdparams[5]);
                         }
-                        if (cmdparams.Length > 4)
+                        if (cmdparams.Length > 6)
                         {
-                            loadOffset.Z = (float) Convert.ToDecimal(cmdparams[4]);
+                            loadOffset.Z = (float) Convert.ToDecimal(cmdparams[6]);
                         }
                         m_console.Error("loadOffsets <X,Y,Z> = <" + loadOffset.X + "," + loadOffset.Y + "," +
                                         loadOffset.Z + ">");
@@ -981,11 +1020,11 @@ namespace OpenSim
             }
         }
 
-        protected void SaveXml2(string[] cmdparams)
+        protected void SaveXml2(string module, string[] cmdparams)
         {
-            if (cmdparams.Length > 0)
+            if (cmdparams.Length > 2)
             {
-                m_sceneManager.SaveCurrentSceneToXml2(cmdparams[0]);
+                m_sceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
             }
             else
             {
@@ -993,11 +1032,11 @@ namespace OpenSim
             }
         }
 
-        protected void LoadXml2(string[] cmdparams)
+        protected void LoadXml2(string module, string[] cmdparams)
         {
-            if (cmdparams.Length > 0)
+            if (cmdparams.Length > 2)
             {
-                m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[0]);
+                m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
             }
             else
             {
@@ -1007,7 +1046,7 @@ namespace OpenSim
                 }
                 catch
                 {
-                    m_console.Error("Default xml not found. Usage: load-xml2 <filename>");
+                    m_console.Error("Default xml not found. Usage: load xml2 <filename>");
                 }
             }
         }
@@ -1016,11 +1055,11 @@ namespace OpenSim
         /// Load a whole region from an opensim archive.
         /// </summary>
         /// <param name="cmdparams"></param>
-        protected void LoadOar(string[] cmdparams)
+        protected void LoadOar(string module, string[] cmdparams)
         {
-            if (cmdparams.Length > 0)
+            if (cmdparams.Length > 2)
             {
-                m_sceneManager.LoadArchiveToCurrentScene(cmdparams[0]);
+                m_sceneManager.LoadArchiveToCurrentScene(cmdparams[2]);
             }
             else
             {
@@ -1039,11 +1078,11 @@ namespace OpenSim
         /// Save a region to a file, including all the assets needed to restore it.
         /// </summary>
         /// <param name="cmdparams"></param>
-        protected void SaveOar(string[] cmdparams)
+        protected void SaveOar(string module, string[] cmdparams)
         {
-            if (cmdparams.Length > 0)
+            if (cmdparams.Length > 2)
             {
-                m_sceneManager.SaveCurrentSceneToArchive(cmdparams[0]);
+                m_sceneManager.SaveCurrentSceneToArchive(cmdparams[2]);
             }
             else
             {
@@ -1055,19 +1094,19 @@ namespace OpenSim
         /// Load inventory from an inventory file archive
         /// </summary>
         /// <param name="cmdparams"></param>
-        protected void LoadInv(string[] cmdparams)
+        protected void LoadInv(string module, string[] cmdparams)
         {
             m_log.Error("[CONSOLE]: This command has not yet been implemented!");
-            if (cmdparams.Length < 3)
+            if (cmdparams.Length < 5)
             {
                 m_log.Error("[CONSOLE]: usage is load-inv <first name> <last name> <inventory path> [<load file path>]");
                 return;
             }
 
-            string firstName = cmdparams[0];
-            string lastName = cmdparams[1];
-            string invPath = cmdparams[2];
-            string loadPath = (cmdparams.Length > 3 ? cmdparams[3] : DEFAULT_INV_BACKUP_FILENAME);
+            string firstName = cmdparams[2];
+            string lastName = cmdparams[3];
+            string invPath = cmdparams[4];
+            string loadPath = (cmdparams.Length > 5 ? cmdparams[5] : DEFAULT_INV_BACKUP_FILENAME);
 
             new InventoryArchiveReadRequest(
                 m_sceneManager.CurrentOrFirstScene, m_commsManager).execute(
@@ -1078,19 +1117,19 @@ namespace OpenSim
         /// Save inventory to a file archive
         /// </summary>
         /// <param name="cmdparams"></param>
-        protected void SaveInv(string[] cmdparams)
+        protected void SaveInv(string module, string[] cmdparams)
         {
             m_log.Error("[CONSOLE]: This command has not yet been implemented!");
-            if (cmdparams.Length < 3)
+            if (cmdparams.Length < 5)
             {
                 m_log.Error("[CONSOLE]: usage is save-inv <first name> <last name> <inventory path> [<save file path>]");
                 return;
             }
 
-            string firstName = cmdparams[0];
-            string lastName = cmdparams[1];
-            string invPath = cmdparams[2];
-            string savePath = (cmdparams.Length > 3 ? cmdparams[3] : DEFAULT_INV_BACKUP_FILENAME);
+            string firstName = cmdparams[2];
+            string lastName = cmdparams[3];
+            string invPath = cmdparams[4];
+            string savePath = (cmdparams.Length > 5 ? cmdparams[5] : DEFAULT_INV_BACKUP_FILENAME);
 
             new InventoryArchiveWriteRequest(
                 m_sceneManager.CurrentOrFirstScene,m_commsManager).execute(
@@ -1108,62 +1147,6 @@ namespace OpenSim
             return result;
         }
 
-        /// <summary>
-        /// Runs the best matching plugin command
-        /// </summary>
-        /// <param name="cmd"></param>
-        /// <param name="withParams"></param>
-        /// <returns>true if a match was found, false otherwise</returns>
-        public bool RunPluginCommands(string cmd, string[] withParams)
-        {
-            ConsolePluginCommand bestMatch = null;
-            int bestLength = 0;
-            String cmdWithParams = cmd + " " + String.Join(" ",withParams);
-            
-            foreach (ConsolePluginCommand cmdinfo in m_PluginCommandInfos)
-            {
-                int matchLen = cmdinfo.matchLength(cmdWithParams);
-                if (matchLen > bestLength)
-                {
-                    bestMatch = cmdinfo;
-                    bestLength = matchLen;
-                }
-            }
-            
-            if (bestMatch == null) return false;
-            bestMatch.Run(cmd,withParams);//.Substring(bestLength));
-            return true;
-        }
-
-        /// <summary>
-        /// Show the matching plugins command help
-        /// </summary>
-        public void ShowPluginCommandsHelp(string cmdWithParams, ConsoleBase console)
-        {
-            foreach (ConsolePluginCommand cmdinfo in m_PluginCommandInfos)
-            {
-                if (cmdinfo.IsHelpfull(cmdWithParams))
-                {
-                    cmdinfo.ShowHelp(console);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Registers a new console plugin command
-        /// </summary>
-        public static void RegisterCmd(string cmd, ConsoleCommand deligate, string help)
-        {
-            RegisterConsolePluginCommand(new ConsolePluginCommand(cmd, deligate, help));
-        }
-
-        /// <summary>
-        /// Registers a new console plugin command
-        /// </summary>
-        public static void RegisterConsolePluginCommand(ConsolePluginCommand pluginCommand)
-        {
-            m_PluginCommandInfos.Add(pluginCommand);
-        }
         #endregion
     }
 }
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index a7ff0e2..4d56147 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -198,6 +198,46 @@ namespace OpenSim
                                     
             // Only enable logins to the regions once we have completely finished starting up (apart from scripts)
             m_commsManager.GridService.RegionLoginsEnabled = true;
+
+            List<string> topics = GetHelpTopics();
+
+            foreach (string topic in topics)
+            {
+                m_console.Commands.AddCommand("plugin", "help "+topic,
+                        "help "+topic,
+                        "Get help on plugin command '"+topic+"'",
+                        HandleCommanderHelp);
+
+                m_console.Commands.AddCommand("plugin", topic,
+                        topic,
+                        "Execute subcommand for plugin '"+topic+"'",
+                        null);
+
+                ICommander commander =
+                        SceneManager.CurrentOrFirstScene.GetCommanders()[topic];
+
+                if (commander == null)
+                    continue;
+
+                foreach (string command in commander.Commands.Keys)
+                {
+                    m_console.Commands.AddCommand(topic, topic+" "+command,
+                            topic+" "+commander.Commands[command].ShortHelp(),
+                            String.Empty, HandleCommanderCommand);
+                }
+            }
+        }
+
+        private void HandleCommanderCommand(string module, string[] cmd)
+        {
+            m_sceneManager.SendCommandToPluginModules(cmd);
+        }
+
+        private void HandleCommanderHelp(string module, string[] cmd)
+        {
+            ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]);
+            if (moduleCommander != null)
+                m_console.Notice(moduleCommander.Help);
         }
 
         /// <summary>
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index 0921dbd..dcc17a7 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -108,6 +108,8 @@ namespace OpenSim.Region.ClientStack
 
             m_log.Info("[REGION]: Starting HTTP server");
             m_httpServer.Start();
+
+            base.StartupSpecific();
         }
 
         /// <summary>
diff --git a/OpenSim/Region/Environment/Modules/Framework/InterfaceCommander/Command.cs b/OpenSim/Region/Environment/Modules/Framework/InterfaceCommander/Command.cs
index 0ad95ae..b6114e8 100644
--- a/OpenSim/Region/Environment/Modules/Framework/InterfaceCommander/Command.cs
+++ b/OpenSim/Region/Environment/Modules/Framework/InterfaceCommander/Command.cs
@@ -88,6 +88,18 @@ namespace OpenSim.Region.Environment.Modules.Framework.InterfaceCommander
             }
         }
 
+        public string ShortHelp()
+        {
+            string help = m_name;
+
+            foreach (CommandArgument arg in m_args)
+            {
+                help += " <" + arg.Name + ">";
+            }
+
+            return help;
+        }
+
         public void ShowConsoleHelp()
         {
             Console.WriteLine("== " + Name + " ==");
diff --git a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
index 060a4f4..e48ef13 100644
--- a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
@@ -32,21 +32,20 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Reflection;
 using log4net;
+using OpenSim;
 using OpenSim.Framework;
 using OpenSim.Region.Framework.Interfaces;
 using OpenSim.Region.Framework.Scenes;
 using OpenSim.Region.Environment.Modules.Framework;
-using OpenSim.Region.Environment.Modules.Framework.InterfaceCommander;
 using OpenSim.Framework.Communications.Cache;
 
 namespace OpenSim.Region.Environment.Modules.World.Permissions
 {
-    public class PermissionsModule : IRegionModule, ICommandableModule
+    public class PermissionsModule : IRegionModule
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
                 
         protected Scene m_scene;
-        private readonly Commander m_commander = new Commander("permissions");                
 
         #region Constants
         // These are here for testing.  They will be taken out
@@ -94,60 +93,6 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions
 
         #endregion
 
-        #region ICommandableModule Members
-
-        public ICommander CommandInterface
-        {
-            get { throw new System.NotImplementedException(); }
-        }
-
-        private void InterfaceDebugPermissions(Object[] args)
-        {
-            if ((bool)args[0] == true)
-            {
-                m_debugPermissions = true;
-                m_log.Info("[PERMISSIONS]: Permissions Debugging Enabled.");
-            }
-            else
-            {
-                m_debugPermissions = false;
-                m_log.Info("[PERMISSIONS]:  Permissions Debugging Disabled.");
-            }
-        }
-
-        private void InterfaceBypassPermissions(Object[] args)
-        {
-            if ((bool)args[0] == true)
-            {
-                m_log.Info("[PERMISSIONS]: Permissions Bypass Enabled.");
-                m_bypassPermissionsValue = (bool)args[1];
-            }
-            else
-            {
-                m_bypassPermissions = false;
-                m_log.Info("[PERMISSIONS]:  Permissions Bypass Disabled. Normal Operation.");
-            }
-        }
-
-        /// <summary>
-        /// Processes commandline input. Do not call directly.
-        /// </summary>
-        /// <param name="args">Commandline arguments</param>
-        private void EventManager_OnPluginConsole(string[] args)
-        {
-            if (args[0] == "permissions")
-            {
-                string[] tmpArgs = new string[args.Length - 2];
-                int i;
-                for (i = 2; i < args.Length; i++)
-                    tmpArgs[i - 2] = args[i];
-
-                m_commander.ProcessConsoleCommand(args[1], tmpArgs);
-            }
-        }
-
-        #endregion
-
         #region IRegionModule Members
 
         public void Initialise(Scene scene, IConfigSource config)
@@ -226,20 +171,89 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions
             
             m_scene.Permissions.AddCanTeleportHandler(CanTeleport); //NOT YET IMPLEMENTED
 
-            //Register Debug Commands
-            Command bypassCommand = new Command("bypass", CommandIntentions.COMMAND_HAZARDOUS, InterfaceBypassPermissions, "Force the permissions a specific way to test permissions");
-            bypassCommand.AddArgument("enable_bypass_perms", "true to enable bypassing all perms", "Boolean");
-            bypassCommand.AddArgument("bypass_perms_value", "true/false: true will ignore all perms; false will restrict everything", "Boolean");
+            m_scene.AddCommand("permissions", "bypass permissions",
+                    "bypass permissions <true / false>",
+                    "Bypass permission checks",
+                    HandleBypassPermissions);
+
+            m_scene.AddCommand("permissions", "force permissions",
+                    "force permissions <true / false>",
+                    "Force permissions on or off",
+                    HandleForcePermissions);
+
+            m_scene.AddCommand("permissions", "debug permissions",
+                    "debug permissions <true / false>",
+                    "Enable permissions debugging",
+                    HandleDebugPermissions);
+        }
+
+        public void HandleBypassPermissions(string module, string[] args)
+        {
+            if (m_scene.ConsoleScene() != null &&
+                m_scene.ConsoleScene() != m_scene)
+            {
+                return;
+            }
+
+            if (args.Length > 2)
+            {
+                bool val;
+
+                if (!bool.TryParse(args[2], out val))
+                    return;
+
+                m_bypassPermissions = val;
+
+                m_log.InfoFormat("[PERMISSIONS] Set permissions bypass to {0} for {1}", m_bypassPermissions, m_scene.RegionInfo.RegionName);
+            }
+        }
+
+        public void HandleForcePermissions(string module, string[] args)
+        {
+            if (m_scene.ConsoleScene() != null &&
+                m_scene.ConsoleScene() != m_scene)
+            {
+                return;
+            }
+
+            if (!m_bypassPermissions)
+            {
+                m_log.Error("[PERMISSIONS] Permissions can't be forced unless they are bypassed first");
+                return;
+            }
 
-            m_commander.RegisterCommand("bypass", bypassCommand);
+            if (args.Length > 2)
+            {
+                bool val;
 
-            Command debugCommand = new Command("debug", CommandIntentions.COMMAND_STATISTICAL, InterfaceDebugPermissions, "Force the permissions a specific way to test permissions");
-            debugCommand.AddArgument("enable_debug_perms", "true to enable debugging to console all perms", "Boolean");
+                if (!bool.TryParse(args[2], out val))
+                    return;
 
-            m_commander.RegisterCommand("debug", debugCommand);
-            m_scene.RegisterModuleCommander(m_commander);
+                m_bypassPermissionsValue = val;
 
-            m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole);
+                m_log.InfoFormat("[PERMISSIONS] Forced permissions to {0} in {1}", m_bypassPermissionsValue, m_scene.RegionInfo.RegionName);
+            }
+        }
+
+        public void HandleDebugPermissions(string module, string[] args)
+        {
+            if (m_scene.ConsoleScene() != null &&
+                m_scene.ConsoleScene() != m_scene)
+            {
+                return;
+            }
+
+            if (args.Length > 2)
+            {
+                bool val;
+
+                if (!bool.TryParse(args[2], out val))
+                    return;
+
+                m_debugPermissions = val;
+
+                m_log.InfoFormat("[PERMISSIONS] Set permissions debugging to {0} in {1}", m_debugPermissions, m_scene.RegionInfo.RegionName);
+            }
         }
 
         public void PostInitialise()
diff --git a/OpenSim/Region/Framework/Interfaces/ICommand.cs b/OpenSim/Region/Framework/Interfaces/ICommand.cs
index 1551b58..15e55c4 100644
--- a/OpenSim/Region/Framework/Interfaces/ICommand.cs
+++ b/OpenSim/Region/Framework/Interfaces/ICommand.cs
@@ -46,5 +46,6 @@ namespace OpenSim.Region.Framework.Interfaces
 
         void Run(object[] args);
         void ShowConsoleHelp();
+        string ShortHelp();
     }
 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f07391d..55fc02a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -37,6 +37,7 @@ using OpenMetaverse;
 using OpenMetaverse.Imaging;
 using OpenMetaverse.Packets;
 using OpenSim.Framework;
+using OpenSim.Framework.Console;
 using OpenSim.Framework.Communications;
 using OpenSim.Framework.Communications.Cache;
 using OpenSim.Framework.Servers;
@@ -3384,7 +3385,7 @@ namespace OpenSim.Region.Framework.Scenes
         /// <param name="cmdparams"></param>
         public void HandleEditCommand(string[] cmdparams)
         {
-            Console.WriteLine("Searching for Primitive: '" + cmdparams[0] + "'");
+            Console.WriteLine("Searching for Primitive: '" + cmdparams[2] + "'");
 
             List<EntityBase> EntityList = GetEntities();
 
@@ -3395,11 +3396,11 @@ namespace OpenSim.Region.Framework.Scenes
                     SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID);
                     if (part != null)
                     {
-                        if (part.Name == cmdparams[0])
+                        if (part.Name == cmdparams[2])
                         {
                             part.Resize(
-                                new Vector3(Convert.ToSingle(cmdparams[1]), Convert.ToSingle(cmdparams[2]),
-                                              Convert.ToSingle(cmdparams[3])));
+                                new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]),
+                                              Convert.ToSingle(cmdparams[5])));
 
                             Console.WriteLine("Edited scale of Primitive: " + part.Name);
                         }
@@ -4235,5 +4236,14 @@ namespace OpenSim.Region.Framework.Scenes
                 }
             }
         }
+
+        public Scene ConsoleScene()
+        {
+            if (MainConsole.Instance == null)
+                return null;
+            if (MainConsole.Instance.ConsoleScene is Scene)
+                return (Scene)MainConsole.Instance.ConsoleScene;
+            return null;
+        }
     }
 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index e58d3ce..cee9037 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -32,6 +32,7 @@ using System.Threading;
 using OpenMetaverse;
 using log4net;
 using OpenSim.Framework;
+using OpenSim.Framework.Console;
 using OpenSim.Framework.Communications.Cache;
 using OpenSim.Region.Framework.Interfaces;
 
@@ -458,5 +459,12 @@ namespace OpenSim.Region.Framework.Scenes
                     break;
             }
         }        
+
+        public void AddCommand(string module, string command, string shorthelp, string longhelp, CommandDelegate callback)
+        {
+            if (MainConsole.Instance == null)
+                return;
+            MainConsole.Instance.Commands.AddCommand(module, command, shorthelp, longhelp, callback);
+        }
     }
 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 1484638..0825bf8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -128,12 +128,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             get { return m_ScriptEngine.World; }
         }
 
-        // Extension commands use this:
-        public ICommander GetCommander(string name)
-        {
-            return World.GetCommander(name);
-        }
-
         public void state(string newState)
         {
             m_ScriptEngine.SetState(m_itemID, newState);
diff --git a/OpenSim/TestSuite/BotManager.cs b/OpenSim/TestSuite/BotManager.cs
index 8eb2027..0838214 100644
--- a/OpenSim/TestSuite/BotManager.cs
+++ b/OpenSim/TestSuite/BotManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.TestSuite
     /// <summary>
     /// Thread/Bot manager for the application
     /// </summary>
-    public class BotManager : conscmd_callback
+    public class BotManager
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -58,8 +58,6 @@ namespace OpenSim.TestSuite
         public BotManager()
         {
             m_log.Info("In bot manager");
-            // m_console = CreateConsole();
-            // MainConsole.Instance = m_console;
             m_lBot = new List<PhysicsBot>();
         }
 
@@ -169,52 +167,5 @@ namespace OpenSim.TestSuite
                 pb.shutdown();
             }
         }
-
-        /// <summary>
-        /// Standard CreateConsole routine
-        /// </summary>
-        /// <returns></returns>
-        protected ConsoleBase CreateConsole()
-        {
-            return new ConsoleBase("Region", this);
-        }
-
-        /// <summary>
-        /// Command runnint tool..  Currently use it to add bots, shutdown and (dangerous)Forcequit
-        /// </summary>
-        /// <param name="command"></param>
-        /// <param name="cmdparams"></param>
-        public void RunCmd(string command, string[] cmdparams)
-        {
-            switch (command)
-            {
-                case "shutdown":
-                    m_console.Warn("BOTMANAGER", "Shutting down bots");
-                    doBotShutdown();
-                    break;
-                case "quit":
-                    m_console.Warn("DANGER", "This should only be used to quit the program if you've already used the shutdown command and the program hasn't quit");
-                    Environment.Exit(0);
-                    break;
-                case "addbots":
-                    int newbots;
-                    Int32.TryParse(cmdparams[0], out newbots);
-
-                    if (newbots > 0)
-                        addbots(newbots);
-                    break;
-                case "help":
-                    m_console.Notice("HELP", "\nshutdown - graceful shutdown\naddbots <n> - adds n bots to the test\nquit - forcequits, dangerous if you have not already run shutdown");
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Required method to implement the conscmd_callback interface
-        /// </summary>
-        /// <param name="showParams">What to show</param>
-        public void Show(string[] showParams)
-        {
-        }
     }
 }
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs
index 100f2d4..3b08adc 100644
--- a/OpenSim/Tools/pCampBot/BotManager.cs
+++ b/OpenSim/Tools/pCampBot/BotManager.cs
@@ -31,6 +31,9 @@ using System.Reflection;
 using System.Threading;
 using OpenMetaverse;
 using log4net;
+using log4net.Appender;
+using log4net.Core;
+using log4net.Repository;
 using Nini.Config;
 using OpenSim.Framework;
 using OpenSim.Framework.Console;
@@ -40,7 +43,7 @@ namespace pCampBot
     /// <summary>
     /// Thread/Bot manager for the application
     /// </summary>
-    public class BotManager : conscmd_callback
+    public class BotManager
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -59,6 +62,36 @@ namespace pCampBot
         {
             m_console = CreateConsole();
             MainConsole.Instance = m_console;
+
+            // Make log4net see the console
+            //
+            ILoggerRepository repository = LogManager.GetRepository();
+            IAppender[] appenders = repository.GetAppenders();
+            OpenSimAppender consoleAppender = null;
+
+            foreach (IAppender appender in appenders)
+            {
+                if (appender.Name == "Console")
+                {
+                    consoleAppender = (OpenSimAppender)appender;
+                    consoleAppender.Console = m_console;
+                    break;
+                }
+            }
+
+            m_console.Commands.AddCommand("bot", "shutdown",
+                    "shutdown",
+                    "Gracefully shut down bots", HandleShutdown);
+
+            m_console.Commands.AddCommand("bot", "quit",
+                    "quit",
+                    "Force quit (DANGEROUS, try shutdown first)",
+                    HandleShutdown);
+
+            m_console.Commands.AddCommand("bot", "add bots",
+                    "add bots <number>",
+                    "Add more bots", HandleAddBots);
+
             m_lBot = new List<PhysicsBot>();
         }
 
@@ -175,45 +208,31 @@ namespace pCampBot
         /// <returns></returns>
         protected ConsoleBase CreateConsole()
         {
-            return new ConsoleBase("Region", this);
+            return new ConsoleBase("Region");
         }
 
-        /// <summary>
-        /// Command runnint tool..  Currently use it to add bots, shutdown and (dangerous)Forcequit
-        /// </summary>
-        /// <param name="command"></param>
-        /// <param name="cmdparams"></param>
-        public void RunCmd(string command, string[] cmdparams)
+        private void HandleShutdown(string module, string[] cmd)
         {
-            switch (command)
-            {
-                case "shutdown":
-                    m_console.Warn("BOTMANAGER", "Shutting down bots");
-                    doBotShutdown();
-                    break;
-                case "quit":
-                    m_console.Warn("DANGER", "This should only be used to quit the program if you've already used the shutdown command and the program hasn't quit");
-                    Environment.Exit(0);
-                    break;
-                case "addbots":
-                    int newbots;
-                    Int32.TryParse(cmdparams[0], out newbots);
+            m_console.Warn("BOTMANAGER", "Shutting down bots");
+            doBotShutdown();
+        }
 
-                    if (newbots > 0)
-                        addbots(newbots);
-                    break;
-                case "help":
-                    m_console.Notice("HELP", "\nshutdown - graceful shutdown\naddbots <n> - adds n bots to the test\nquit - forcequits, dangerous if you have not already run shutdown");
-                    break;
-            }
+        private void HandleQuit(string module, string[] cmd)
+        {
+            m_console.Warn("DANGER", "This should only be used to quit the program if you've already used the shutdown command and the program hasn't quit");
+            Environment.Exit(0);
         }
 
-        /// <summary>
-        /// Required method to implement the conscmd_callback interface
-        /// </summary>
-        /// <param name="showParams">What to show</param>
-        public void Show(string[] showParams)
+        private void HandleAddBots(string module, string[] cmd)
         {
+            int newbots = 0;
+            
+            if (cmd.Length > 2)
+            {
+                Int32.TryParse(cmd[2], out newbots);
+            }
+            if (newbots > 0)
+                addbots(newbots);
         }
     }
 }
-- 
cgit v1.1