Index: urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPhaseA.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPhaseA.java	(revision 454)
+++ urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPhaseA.java	(revision )
@@ -41,7 +41,7 @@
     public void register(final UpdaterContext context) {
 
         context.registerName("url-rewriter-updater-1-04-phaseA");
-        context.registerStartTag("url-rewriter-updater-1-04");
+        context.registerStartTag("url-rewriter-updater-1-04-pre-processed");
         context.registerEndTag("url-rewriter-updater-1-04-phaseA");
 
 
Index: urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPreProcessorMultipleRulesSplitter.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPreProcessorMultipleRulesSplitter.java	(revision )
+++ urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPreProcessorMultipleRulesSplitter.java	(revision )
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2013 Hippo B.V. (http://www.onehippo.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onehippo.forge.rewriting.updater;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.hippoecm.repository.ext.UpdaterContext;
+import org.hippoecm.repository.ext.UpdaterItemVisitor;
+import org.hippoecm.repository.ext.UpdaterModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This updater registers an intermediate cnd containing all the new document types. This is a trivial cnd change. Then
+ * the updater moves all existing content of type urlrewriter:ruleset to urlrewriter:advancedrule.
+ *
+ * @version $Id: UrlRewriter_1_04_UpdaterPhaseA.java 453 2013-11-19 10:40:22Z mchatzidakis $
+ */
+public class UrlRewriter_1_04_UpdaterPreProcessorMultipleRulesSplitter implements UpdaterModule {
+
+
+    protected static final Logger log = LoggerFactory.getLogger(UrlRewriter_1_04_UpdaterPreProcessorMultipleRulesSplitter.class);
+
+    public void register(final UpdaterContext context) {
+
+        context.registerName("url-rewriter-updater-1-04-pre-processor-multiple-rules-splitter");
+        context.registerStartTag("url-rewriter-updater-1-04");
+        context.registerEndTag("url-rewriter-updater-1-04-pre-processed");
+
+        context.registerVisitor(new UpdaterItemVisitor.QueryVisitor("//*[@jcr:primaryType = 'urlrewriter:ruleset' or @jcr:primaryType = 'urlrewriter:rulesetxml'  and not( fn:name()= 'hipposysedit:prototype')]", "xpath") {
+            @Override
+            protected void leaving(Node node, int level) throws RepositoryException {
+                UpdaterUtils.checkURLRewriterRules(node);
+            }
+        });
+
+    }
+}
Index: urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPhaseD.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPhaseD.java	(revision 454)
+++ urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UrlRewriter_1_04_UpdaterPhaseD.java	(revision )
@@ -41,7 +41,7 @@
 
         context.registerName("url-rewriter-updater-1-04-phaseD");
         context.registerStartTag("url-rewriter-updater-1-04-phaseC");
-        context.registerEndTag("url-rewriter-updater-1-04-phaseD");
+        context.registerEndTag("url-rewriter-updater-1-04-completed");
 
         // visit hippo:initialize
         context.registerVisitor(new UpdaterItemVisitor.PathVisitor("/hippo:configuration/hippo:initialize") {
Index: urlrewriter-plugin-repository/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- urlrewriter-plugin-repository/pom.xml	(revision 454)
+++ urlrewriter-plugin-repository/pom.xml	(revision )
@@ -58,6 +58,7 @@
               <!-- versioning reloadonstartups: build reflects version -->
               <Implementation-Build>10400</Implementation-Build>
               <Hippo-Modules>
+                org.onehippo.forge.rewriting.updater.UrlRewriter_1_04_UpdaterPreProcessorMultipleRulesSplitter
                 org.onehippo.forge.rewriting.updater.UrlRewriter_1_04_UpdaterPhaseA
                 org.onehippo.forge.rewriting.updater.UrlRewriter_1_04_UpdaterPhaseB
                 org.onehippo.forge.rewriting.updater.UrlRewriter_1_04_UpdaterPhaseC
\ No newline at end of file
Index: urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UpdaterUtils.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UpdaterUtils.java	(revision 454)
+++ urlrewriter-plugin-repository/src/main/java/org/onehippo/forge/rewriting/updater/UpdaterUtils.java	(revision )
@@ -17,11 +17,15 @@
 
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
 import javax.jcr.RepositoryException;
-import javax.jcr.Value;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.lang.StringUtils;
 import org.hippoecm.repository.updater.UpdaterNode;
+import org.hippoecm.repository.util.JcrUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -65,13 +69,6 @@
                     log.info("processing ruleset {}", rulesetNode.getPath());
 
                     changePrimaryType(rulesetNode, "urlrewriter:advancedrule");
-
-                    //TODO We should create a new advanced rule for every rule we find.
-                    if (rulesetNode.getNodes("urlrewriter:rule").getSize() > 1) {
-                        log.warn("Rewriter rule has many rule compounds {}", rulesetNode.getPath());
-                    }
-
-                    //TODO Instead, we deal with the first we find
                     Node oldRewriterRule = rulesetNode.getNode("urlrewriter:rule");
 
                     if (oldRewriterRule != null) {
@@ -174,5 +171,118 @@
     }
 
 
+    public static void checkURLRewriterRules(final Node node) throws RepositoryException {
+
+        if( !node.getParent().isNodeType("hippo:handle") || !node.getParent().getName().equals(node.getName())){
+            log.warn("Node {} doesn't have a parent hippo:handle or its name differs from the name of the parent handle. Cleaning up...", node.getPath());
+            if(node.getParent().getNodes(node.getParent().getName()).getSize() > 1){
+                log.warn("Parent handle has more children, removing only faulty ruleset/rulesetxml child");
+                removeNode(node);
+                return;
+            } else {
+                log.warn("Removing parent handle {}", node.getParent().getPath());
+                removeNode(node.getParent());
+                return;
+            }
+        }
+
+        if (node.isNodeType("urlrewriter:rulesetxml")) {
+            log.warn("Node of type rulesetxml found {}, deleting", node.getPath());
+            removeNode(node.getParent());
+            return;
+        }
+
+        if (!node.isNodeType("urlrewriter:ruleset")) {
+            log.warn("Node is not of type 'ruleset' {}, ignoring", node.getPath());
+            return;
+        }
+
+        log.info("processing ruleset {}", node.getPath());
+
+        if (node.getNodes("urlrewriter:rule").getSize() > 1) {
+            log.warn("Rewriter rule has many rule compounds. Please check manually", node.getPath());
+            int indexNumber = 1;
+            for (NodeIterator rules = node.getNodes("urlrewriter:rule"); rules.hasNext(); indexNumber++) {
+                if (indexNumber == 1) {
+                    //we leave one
+                    rules.nextNode();
+                    continue;
+                }
+                Node oldRewriterRule = rules.nextNode();
+                createNewHandleForRewriterRule(node.getParent(), node, oldRewriterRule, indexNumber);
+                removeNode(oldRewriterRule);
+                log.info("Created new handle for ruleset rule {}", node.getPath());
+            }
+            log.info("Finished processing ruleset {}", node.getPath());
+        } else {
+            //TODO Change logging level here
+            log.info("No multiple rules for ruleset {}", node.getPath());
+        }
+
+
+    }
+
+    private static Node createNewHandleForRewriterRule(final Node handleNode, final Node rulesetNode, final Node oldRewriterRule, final int indexNumber) throws RepositoryException {
+        String newHandleNodeName = handleNode.getName() + "_" + indexNumber;
+        Node handleParentNode = handleNode.getParent();
+
+        //Create new handle under the same parent
+        copyTopLevelOnly(handleNode, newHandleNodeName, handleParentNode);
+
+        //Copy the rulesetNode only under this new handle
+        Node newHandleNode = handleParentNode.getNode(newHandleNodeName);
+        copyTopLevelOnly(rulesetNode, newHandleNodeName, newHandleNode);
+
+        //Copy the oldRewriterRule with all hierarchy below it, under the copied rulesetNode
+        Node copiedRulesetChild = newHandleNode.getNode(newHandleNodeName);
+        JcrUtils.copy(oldRewriterRule, oldRewriterRule.getName(), copiedRulesetChild);
+
+        return newHandleNode;
+    }
+
+    public static void copyTopLevelOnly(final Node srcNode, final String destNodeName, final Node destParentNode) throws RepositoryException {
+        if (JcrUtils.isVirtual(srcNode)) {
+            return;
+        }
+        final Node destNode = (isAutoCreatedNode(srcNode.getName(), destParentNode) && destParentNode.hasNode(srcNode.getName())) ?
+                destParentNode.getNode(destNodeName) :
+                destParentNode.addNode(destNodeName, srcNode.getPrimaryNodeType().getName());
+
+        for (NodeType nodeType : srcNode.getMixinNodeTypes()) {
+            destNode.addMixin(nodeType.getName());
+        }
+
+        final PropertyIterator properties = srcNode.getProperties();
+        while (properties.hasNext()) {
+            final Property property = properties.nextProperty();
+            if (!property.getDefinition().isProtected()) {
+                if (property.isMultiple()) {
+                    destNode.setProperty(property.getName(), property.getValues(), property.getType());
+                } else {
+                    destNode.setProperty(property.getName(), property.getValue());
+                }
+            }
+        }
+    }
+
+    private static boolean isAutoCreatedNode(final String childName, Node parent) throws RepositoryException {
+        for (NodeDefinition nodeDefinition : parent.getPrimaryNodeType().getChildNodeDefinitions()) {
+            if (childName.equals(nodeDefinition.getName())) {
+                if (nodeDefinition.isAutoCreated()) {
+                    return true;
+                }
+            }
+        }
+        for (NodeType nodeType : parent.getMixinNodeTypes()) {
+            for (NodeDefinition nodeDefinition : nodeType.getChildNodeDefinitions()) {
+                if (childName.equals(nodeDefinition.getName())) {
+                    if (nodeDefinition.isAutoCreated()) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
 }
 
