diff --git a/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java b/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java
index 850efcade..e75b43bf2 100644
--- a/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java
+++ b/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java
@@ -21,10 +21,17 @@ package com.maddyhome.idea.vim.ex.handler;
 
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Editor;
-import com.maddyhome.idea.vim.KeyHandler;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.diagnostic.Logger;
 import com.maddyhome.idea.vim.ex.CommandHandler;
 import com.maddyhome.idea.vim.ex.ExCommand;
 import com.maddyhome.idea.vim.ex.ExException;
+import com.maddyhome.idea.vim.ex.InvalidArgumentException;
+import com.maddyhome.idea.vim.ex.CommandName;
+import com.maddyhome.idea.vim.group.CommandGroups;
+import com.maddyhome.idea.vim.group.SearchGroup;
+import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
 
 /**
  *
@@ -33,13 +40,87 @@ public class SubstituteHandler extends CommandHandler
 {
     public SubstituteHandler()
     {
-        super("s", "ubstitute", 0);
+        super(new CommandName[] {
+            new CommandName("s", "ubstitute"),
+            new CommandName("&", ""),
+            new CommandName("~", "")
+        }, WRITABLE);
     }
 
     public boolean execute(Editor editor, DataContext context, ExCommand cmd) throws ExException
     {
-        KeyHandler.executeAction("Replace", context);
+        String arg = cmd.getArgument();
+        logger.debug("arg="+arg);
+        String pattern = "";
+        String replace = "~";
+        String args = "";
+        String count = "";
+        // Are there any aruments at all?
+        if (arg.length() > 0)
+        {
+            // Are there flags and possible count?
+            if (Character.isLetter(arg.charAt(0)) || arg.charAt(0) == '&')
+            {
+                StringTokenizer tokenizer = new StringTokenizer(arg, " ");
+                args = tokenizer.nextToken();
+                if (tokenizer.hasMoreTokens())
+                {
+                    count = tokenizer.nextToken();
+                }
+            }
+            // Is there just a count?
+            else if (Character.isDigit(arg.charAt(0)))
+            {
+                count = arg;
+            }
+            // We have a pattern and maybe flags and a count
+            else
+            {
+                if (arg.length() < 3)
+                {
+                    throw new InvalidArgumentException();
+                }
+                StringTokenizer tokenizer = new StringTokenizer(arg.substring(1), Character.toString(arg.charAt(0)));
+                if (tokenizer.countTokens() < 2)
+                {
+                    throw new InvalidArgumentException();
+                }
 
-        return true;
+                pattern = tokenizer.nextToken();
+                replace = tokenizer.nextToken();
+                try
+                {
+                    args = tokenizer.nextToken(" " + arg.charAt(0));
+                    count = tokenizer.nextToken(" ");
+                }
+                catch (NoSuchElementException e)
+                {
+                }
+
+                if (args.length() > 0 && Character.isDigit(args.charAt(0)))
+                {
+                    args = "";
+                    count = args;
+                }
+            }
+        }
+
+        logger.debug("pattern="+pattern);
+        logger.debug("replace="+replace);
+        logger.debug("args="+args);
+        logger.debug("count="+count);
+
+        cmd.setArgument(count);
+        TextRange range = cmd.getTextRange(editor, context, count.length() > 0);
+
+        int sflags = SearchGroup.argsToFlags(args);
+        if (cmd.getCommand().equals("~"))
+        {
+            sflags |= SearchGroup.REUSE;
+        }
+
+        return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, pattern, replace, sflags);
     }
+
+    private static Logger logger = Logger.getInstance(SubstituteHandler.class.getName());
 }