Index: api/src/main/java/org/hippoecm/frontend/util/CodecUtils.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- api/src/main/java/org/hippoecm/frontend/util/CodecUtils.java	(revision )
+++ api/src/main/java/org/hippoecm/frontend/util/CodecUtils.java	(revision )
@@ -0,0 +1,167 @@
+/*
+ *  Copyright 2014 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.hippoecm.frontend.util;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.hippoecm.frontend.plugin.IPluginContext;
+import org.hippoecm.frontend.service.ISettingsService;
+import org.hippoecm.repository.api.HippoNodeType;
+import org.hippoecm.repository.api.StringCodec;
+import org.hippoecm.repository.api.StringCodecFactory;
+import org.hippoecm.repository.translation.HippoTranslationNodeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CodecUtils {
+    public static final Logger log = LoggerFactory.getLogger(CodecUtils.class);
+
+    public static final String ENCODING_NODE    = "encoding.node";
+    public static final String ENCODING_DISPLAY = "encoding.display";
+
+    /**
+     * Return a {@link StringCodecFactory} from the {@link ISettingsService} or throw an {@link IllegalStateException} 
+     * if not found.
+     * 
+     * @param context The {@link IPluginContext} should contain a reference to the {@link ISettingsService}, otherwise
+     *                an {@link IllegalStateException} is thrown.
+     * @return a {@link StringCodecFactory} if found, otherwise an {@link IllegalStateException} is thrown.
+     */
+    public static StringCodecFactory getStringCodecFactory(final IPluginContext context) {
+        ISettingsService settingsService = context.getService(ISettingsService.SERVICE_ID, ISettingsService.class);
+        if (settingsService == null) {
+            throw new IllegalStateException("ISettingsService not found.");
+        }
+        
+        StringCodecFactory factory = settingsService.getStringCodecFactory();
+        if (factory == null) {
+            throw new IllegalStateException("StringCodecFactory not found.");
+        }
+
+        return factory;
+    }
+
+    /**
+     * Lookup a {@link StringCodec} for encoding/decoding a display name.
+     * 
+     * @param context Used for retrieving the {@link StringCodecFactory}, see {@link #getStringCodecFactory}
+     * @return a {@link StringCodec} for encoding/decoding a display name.
+     */
+    public static StringCodec getDisplayNameCodec(final IPluginContext context) {
+        //TODO: remove the null and revert to default single arg implementation
+        return getStringCodecFactory(context).getStringCodec(ENCODING_DISPLAY, null);
+    }
+
+    /**
+     * Lookup a {@link StringCodec} for encoding/decoding a node name for a specific locale (optional).
+     *
+     * @param context Used for retrieving the {@link StringCodecFactory}, see {@link #getStringCodecFactory}
+     * @param locale Simplified string representation of a locale like <em>en_US</em> or <em>de</em>
+     * @return a {@link StringCodec} for encoding/decoding a node name.
+     */
+    public static StringCodec getNodeNameCodec(final IPluginContext context, final String locale) {
+        return getStringCodecFactory(context).getStringCodec(ENCODING_NODE, locale); 
+    }
+
+    /**
+     * Lookup a {@link StringCodec} for encoding/decoding a node name. The {@link Node} is used for retrieving an 
+     * optional locale.
+     * 
+     * @param context Used for retrieving the {@link StringCodecFactory}, see {@link #getStringCodecFactory}
+     * @param node If the node or any of its parents have property {@link HippoTranslationNodeType#LOCALE} set, the 
+     *             value is used to localize the {@link StringCodec}. 
+     * @return a {@link StringCodec} for encoding/decoding a node name. 
+     */
+    public static StringCodec getNodeNameCodec(final IPluginContext context, final Node node) {
+        final String locale = getLocaleFromNodeAndAncestors(node);
+        return getNodeNameCodec(context, locale);
+    }
+
+    /**
+     * Convenience method for wrapping a {@link StringCodec} in a {@link LoadableDetachableModel}. See 
+     * {@link #getNodeNameCodec(IPluginContext, String)}
+     *
+     * @param context Used for retrieving the {@link StringCodecFactory}, see {@link #getStringCodecFactory}
+     * @param locale Simplified string representation of a locale like <em>en_US</em> or <em>de</em>
+     * @return A {@link LoadableDetachableModel} wrapping a {@link StringCodec} for encoding/decoding a node name.
+     */
+    public static IModel<StringCodec> getNodeNameCodecModel(final IPluginContext context, final String locale) {
+        return new LoadableDetachableModel<StringCodec>() {
+            @Override
+            protected StringCodec load() {
+                return getNodeNameCodec(context, locale);
+            }
+        };
+    }
+
+    /**
+     * Return the value of property {@link HippoTranslationNodeType#LOCALE} for the first translated node found. If
+     * the provided node is of type <code>hippo:translated</code> and is a handle, start with the first child. 
+     * Traverse up the ancestor tree until a locale is found.
+     * 
+     * @param node Node to start traversal with
+     * @return String representation of locale associated with subtree
+     */
+    public static String getLocaleFromNodeAndAncestors(Node node) {
+        try {
+            if (node.isNodeType(HippoNodeType.NT_TRANSLATED) && node.hasNode(node.getName())) {
+                node = node.getNode(node.getName());
+            }
+
+            while (node != null && node.getDepth() > 0) {
+                if (node.isNodeType(HippoTranslationNodeType.NT_TRANSLATED)) {
+                    return node.getProperty(HippoTranslationNodeType.LOCALE).getString();
+                }
+                node = node.getParent();
+            }
+        } catch (RepositoryException e) {
+            log.error("Could not determine visibility of language field");
+        }
+
+        return null;
+    }
+
+    public static String getLocaleFromNode(Node node) {
+        try {
+            if (node.isNodeType(HippoNodeType.NT_TRANSLATED) && node.hasNode(node.getName())) {
+                node = node.getNode(node.getName());
+            }
+
+            if (node.isNodeType(HippoTranslationNodeType.NT_TRANSLATED)) {
+                return node.getProperty(HippoTranslationNodeType.LOCALE).getString();
+            }
+        } catch (RepositoryException e) {
+            log.error("Could not determine visibility of language field");
+        }
+
+        return null;
+    }
+
+    /**
+     * Helper method for fetching a locale for a document or a folder.
+     */
+    public static String getLocaleFromDocumentOrFolder(final Node document, final Node folder) {
+        String locale = CodecUtils.getLocaleFromNode(document);
+        if (locale == null) {
+            // otherwise use locale of folder
+            locale = CodecUtils.getLocaleFromNodeAndAncestors(folder);
+        }
+        return locale;
+    }
+}
Index: workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/DocumentWorkflowPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/DocumentWorkflowPlugin.java	(revision 48312)
+++ workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/DocumentWorkflowPlugin.java	(revision )
@@ -23,11 +23,13 @@
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.apache.wicket.model.AbstractReadOnlyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.StringResourceModel;
 import org.apache.wicket.request.resource.PackageResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.string.Strings;
 import org.hippoecm.addon.workflow.DestinationDialog;
 import org.hippoecm.addon.workflow.StdWorkflow;
 import org.hippoecm.addon.workflow.WorkflowDescriptorModel;
@@ -42,6 +44,7 @@
 import org.hippoecm.frontend.plugin.config.IPluginConfig;
 import org.hippoecm.frontend.plugins.reviewedactions.dialogs.HistoryDialog;
 import org.hippoecm.frontend.session.UserSession;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNode;
 import org.hippoecm.repository.api.Localized;
@@ -96,8 +99,10 @@
 
             @Override
             protected IDialogService.Dialog createRequestDialog() {
+                String locale = null;
                 try {
                     final HippoNode node = getModelNode();
+                    locale = CodecUtils.getLocaleFromNodeAndAncestors(node);
                     uriName = node.getName();
                     targetName = getLocalizedNameForSession(node);
                     localizedNames = node.getLocalizedNames();
@@ -105,14 +110,15 @@
                     uriName = targetName = "";
                     localizedNames = Collections.emptyMap();
                 }
+
+                IModel<StringCodec> codecModel = CodecUtils.getNodeNameCodecModel(context, locale);
                 return new RenameDocumentDialog(this,
                         new StringResourceModel("rename-title", DocumentWorkflowPlugin.this, null),
-                        context);
+                        codecModel);
             }
 
             private HippoNode getModelNode() throws RepositoryException {
-                final WorkflowDescriptorModel model = (WorkflowDescriptorModel) getDefaultModel();
-                return (HippoNode) model.getNode();
+                return (HippoNode) getModel().getNode();
             }
 
             private String getLocalizedNameForSession(final HippoNode node) throws RepositoryException {
@@ -123,15 +129,21 @@
 
             @Override
             protected String execute(Workflow wf) throws Exception {
-                if (targetName == null || targetName.trim().equals("")) {
-                    throw new WorkflowException("No name for destination given");
+                if (Strings.isEmpty(targetName)) {
+                    throw new WorkflowException("No name given for document node");
                 }
+                if (Strings.isEmpty(uriName)) {
+                    throw new WorkflowException("No URL name given for document node");
+                }
+
                 final HippoNode node = getModelNode();
-                String nodeName = getNodeNameCodec().encode(uriName);
+                String nodeName = getNodeNameCodec(node).encode(uriName);
                 String localName = getLocalizeCodec().encode(targetName);
-                if ("".equals(nodeName)) {
+
+                if (Strings.isEmpty(nodeName)) {
                     throw new IllegalArgumentException("You need to enter a name");
                 }
+
                 WorkflowManager manager = UserSession.get().getWorkflowManager();
                 DefaultWorkflow defaultWorkflow = (DefaultWorkflow) manager.getWorkflow("core", node);
                 if (!((WorkflowDescriptorModel) getDefaultModel()).getNode().getName().equals(nodeName)) {
@@ -165,11 +177,23 @@
             @Override
             protected IDialogService.Dialog createRequestDialog() {
                 destination = new NodeModelWrapper(getFolder()) {};
-                CopyNameHelper copyNameHelper = new CopyNameHelper(getNodeNameCodec(), new StringResourceModel(
-                        "copyof", DocumentWorkflowPlugin.this, null).getString());
+
                 try {
-                    name = copyNameHelper.getCopyName(((HippoNode) ((WorkflowDescriptorModel) getDefaultModel())
-                            .getNode()).getLocalizedName(), destination.getNodeModel().getNode());
+                    IModel<StringCodec> codec = new AbstractReadOnlyModel<StringCodec>() {
+                        @Override
+                        public StringCodec getObject() {
+                            try {
+                                return getNodeNameCodec(getModelNode(), getFolder().getNode());
+                            } catch (RepositoryException e) {
+                                return getNodeNameCodec(getFolder().getNode());
+                            }
+                        }
+                    };
+
+                    final CopyNameHelper copyNameHelper = new CopyNameHelper(codec,
+                            new StringResourceModel("copyof", DocumentWorkflowPlugin.this, null).getString());
+                    name = copyNameHelper.getCopyName(getModelNode().getLocalizedName(),
+                            destination.getNodeModel().getNode());
                 } catch (RepositoryException ex) {
                     return new ExceptionDialog(ex);
                 }
@@ -196,18 +220,15 @@
 
             @Override
             protected String execute(Workflow wf) throws Exception {
-                JcrNodeModel folderModel;
-                if (destination != null) {
-                    folderModel = destination.getNodeModel();
-                } else {
-                    folderModel = new JcrNodeModel("/");
-                }
-                StringCodec codec = getNodeNameCodec();
-                String nodeName = codec.encode(name);
+                Node folder = destination != null ? destination.getNodeModel().getNode() : new JcrNodeModel("/").getNode();
+                Node document = getModel().getNode();
+
+                String nodeName = getNodeNameCodec(document, folder).encode(name);
+
                 DocumentWorkflow workflow = (DocumentWorkflow) wf;
+                workflow.copy(new Document(folder), nodeName);
 
-                workflow.copy(new Document(folderModel.getNode()), nodeName);
-                JcrNodeModel resultModel = new JcrNodeModel(folderModel.getItemModel().getPath() + "/" + nodeName);
+                JcrNodeModel resultModel = new JcrNodeModel(folder.getPath() + "/" + nodeName);
                 Node result = resultModel.getNode();
 
                 WorkflowManager manager = UserSession.get().getWorkflowManager();
@@ -217,6 +238,11 @@
                 browseTo(resultModel);
                 return null;
             }
+
+            private HippoNode getModelNode() throws RepositoryException {
+                return (HippoNode) getModel().getNode();
+            }
+
         });
 
         add(moveAction = new StdWorkflow("move", new StringResourceModel("move-label", this, null), context, getModel()) {
@@ -266,14 +292,14 @@
 
             @Override
             protected String execute(Workflow wf) throws Exception {
-                JcrNodeModel folderModel = new JcrNodeModel("/");
-                if (destination != null) {
-                    folderModel = destination.getNodeModel();
-                }
-                String nodeName = getModel().getNode().getName();
+                Node document = getModel().getNode();
+                Node folder = destination != null ? destination.getNodeModel().getObject()
+                        : new JcrNodeModel("/").getNode();
+
+                String nodeName = document.getName();
                 DocumentWorkflow workflow = (DocumentWorkflow) wf;
-                workflow.move(new Document(folderModel.getNode()), nodeName);
-                browseTo(new JcrNodeModel(folderModel.getItemModel().getPath() + "/" + nodeName));
+                workflow.move(new Document(folder), nodeName);
+                browseTo(new JcrNodeModel(folder.getPath() + "/" + nodeName));
                 return null;
             }
         });
@@ -422,6 +448,16 @@
 
         hideOrDisable(info, "copy", copyAction);
         hideOrDisable(info, "listVersions", historyAction);
+    }
+
+    /**
+     * Helper method for fetching a StringCodec for a document. If document has a locale, use it to find a fitting
+     * {@link StringCodec}, otherwise search the destination tree for a locale and use that to find a fitting
+     * {@link StringCodec}.
+     */
+    private StringCodec getNodeNameCodec(final Node document, final Node destination) {
+        String locale = CodecUtils.getLocaleFromDocumentOrFolder(document, destination);
+        return CodecUtils.getNodeNameCodec(getPluginContext(), locale);
     }
 
     private static boolean isWritePermissionGranted(IModel<Node> model) {
Index: gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/upload/UploadDialog.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/upload/UploadDialog.java	(revision 48312)
+++ gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/upload/UploadDialog.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2008-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2008-2015 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.
@@ -19,7 +19,6 @@
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 
-import org.apache.wicket.Session;
 import org.apache.wicket.extensions.wizard.IWizardModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.StringResourceModel;
@@ -28,20 +27,18 @@
 import org.hippoecm.frontend.model.JcrNodeModel;
 import org.hippoecm.frontend.plugin.IPluginContext;
 import org.hippoecm.frontend.plugin.config.IPluginConfig;
-import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.session.UserSession;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.repository.api.StringCodec;
-import org.hippoecm.repository.api.StringCodecFactory;
 import org.hippoecm.repository.api.Workflow;
 import org.hippoecm.repository.api.WorkflowManager;
 import org.hippoecm.repository.gallery.GalleryWorkflow;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class UploadDialog extends AbstractDialog {
+public class UploadDialog extends AbstractDialog<Node> {
     private static final long serialVersionUID = 1L;
 
-
     static final Logger log = LoggerFactory.getLogger(UploadDialog.class);
 
     UploadWizard wizard;
@@ -52,7 +49,7 @@
         this(context, config, null);
     }
 
-    public UploadDialog(IPluginContext context, IPluginConfig config, IModel model) {
+    public UploadDialog(IPluginContext context, IPluginConfig config, IModel<Node> model) {
         super(model);
         setOkVisible(false);
         setCancelVisible(false);
@@ -68,29 +65,22 @@
     }
 
     String getWorkflowCategory() {
-        String workflowCats = pluginConfig.getString("workflow.categories");
-        return workflowCats;
+        return pluginConfig.getString("workflow.categories");
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = pluginContext
-                .getService(ISettingsService.SERVICE_ID, ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(pluginContext);
     }
 
-    protected StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = pluginContext
-                .getService(ISettingsService.SERVICE_ID, ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
+    protected StringCodec getNodeNameCodec(Node node) {
+        return CodecUtils.getNodeNameCodec(pluginContext, node);
     }
 
     IWizardModel getWizardModel() {
         return wizard.getWizardModel();
     }
 
-    public IModel getTitle() {
+    public IModel<String> getTitle() {
         return new StringResourceModel(pluginConfig.getString("option.text", ""), this, null);
     }
 
@@ -99,14 +89,13 @@
     }
 
     Node getGalleryNode() {
-        Object modelObject = getModelObject();
-        Node node = null;
+        Node galleryNode = getModelObject();
         try {
-            if (modelObject != null && modelObject instanceof Node) {
+            if (galleryNode != null) {
                 WorkflowManager manager = UserSession.get().getWorkflowManager();
-                Workflow workflow = manager.getWorkflow(getWorkflowCategory(), (Node) modelObject);
+                Workflow workflow = manager.getWorkflow(getWorkflowCategory(), galleryNode);
                 if (workflow instanceof GalleryWorkflow) {
-                    return (Node) modelObject;
+                    return galleryNode;
                 }
             }
             String location = pluginConfig.getString("option.location");
@@ -116,7 +105,10 @@
                 }
                 javax.jcr.Session jcrSession = UserSession.get().getJcrSession();
                 if (jcrSession.getRootNode().hasNode(location)) {
-                    node = jcrSession.getRootNode().getNode(location);
+                    return jcrSession.getRootNode().getNode(location);
+                } else {
+                    log.warn("Failed to retrieve gallery node from configuration using option.location={}",
+                            pluginConfig.getString("option.location"));
                 }
             }
         } catch (PathNotFoundException e) {
@@ -124,6 +116,6 @@
         } catch (RepositoryException e) {
             log.error("Error while accessing upload directory " + e.getMessage());
         }
-        return node;
+        return null;
     }
 }
Index: workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/AbstractDocumentWorkflowPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/AbstractDocumentWorkflowPlugin.java	(revision 48312)
+++ workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/AbstractDocumentWorkflowPlugin.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2014 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2015 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.
@@ -35,12 +35,11 @@
 import org.hippoecm.frontend.plugin.config.IPluginConfig;
 import org.hippoecm.frontend.service.IBrowseService;
 import org.hippoecm.frontend.service.IEditorManager;
-import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.service.render.RenderPlugin;
 import org.hippoecm.frontend.session.UserSession;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.repository.HippoStdNodeType;
 import org.hippoecm.repository.api.StringCodec;
-import org.hippoecm.repository.api.StringCodecFactory;
 import org.hippoecm.repository.api.WorkflowException;
 import org.hippoecm.repository.util.NodeIterable;
 import org.onehippo.repository.documentworkflow.DocumentWorkflow;
@@ -90,17 +89,11 @@
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
-    protected StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
+    protected StringCodec getNodeNameCodec(final Node node) {
+        return CodecUtils.getNodeNameCodec(getPluginContext(), node);
     }
 
     protected void hideOrDisable(Map<String, Serializable> info, String key, StdWorkflow... actions) {
Index: translation/frontend/src/main/java/org/hippoecm/frontend/translation/workflow/DocumentTranslationDialog.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- translation/frontend/src/main/java/org/hippoecm/frontend/translation/workflow/DocumentTranslationDialog.java	(revision 48312)
+++ translation/frontend/src/main/java/org/hippoecm/frontend/translation/workflow/DocumentTranslationDialog.java	(revision )
@@ -28,6 +28,7 @@
 import org.hippoecm.frontend.translation.ILocaleProvider;
 import org.hippoecm.frontend.translation.components.document.DocumentTranslationView;
 import org.hippoecm.frontend.translation.components.document.FolderTranslation;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.frontend.widgets.BooleanFieldWidget;
 import org.hippoecm.repository.api.StringCodec;
 import org.hippoecm.repository.api.StringCodecFactory;
@@ -41,7 +42,7 @@
 
     public DocumentTranslationDialog(ISettingsService settings,
             IWorkflowInvoker action, IModel<String> title, List<FolderTranslation> folders, IModel<Boolean> autoTranslateContent,
-            String sourceLanguage, String targetLanguage,
+            String sourceLanguage, final String targetLanguage,
             ILocaleProvider provider) {
         super(null, action);
         this.settingsService = settings;
@@ -55,7 +56,7 @@
                     @Override
                     protected StringCodec load() {
                         StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-                        return stringCodecFactory.getStringCodec("encoding.node");
+                        return stringCodecFactory.getStringCodec(CodecUtils.ENCODING_NODE, targetLanguage);
                     }
                 }, provider);
         dtv.setFrame(false);
@@ -67,7 +68,7 @@
         }
     }
 
-    public IModel getTitle() {
+    public IModel<String> getTitle() {
         return title;
     }
 
Index: gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/upload/UploadForm.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/upload/UploadForm.java	(revision 48312)
+++ gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/upload/UploadForm.java	(revision )
@@ -41,7 +41,6 @@
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNode;
-import org.hippoecm.repository.api.MappingException;
 import org.hippoecm.repository.api.WorkflowException;
 import org.hippoecm.repository.api.WorkflowManager;
 import org.hippoecm.repository.gallery.GalleryWorkflow;
@@ -49,7 +48,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-class UploadForm extends Form {
+class UploadForm extends Form<Node> {
 
     private static final long serialVersionUID = 1L;
 
@@ -83,17 +82,13 @@
                 } else {
                     galleryTypes = workflow.getGalleryTypes();
                 }
-            } catch (MappingException ex) {
+            } catch (RemoteException | RepositoryException ex) {
                 log.error(ex.getMessage(), ex);
-            } catch (RepositoryException ex) {
-                log.error(ex.getMessage(), ex);
-            } catch (RemoteException ex) {
-                log.error(ex.getMessage(), ex);
             }
             if (galleryTypes != null && galleryTypes.size() > 1) {
                 DropDownChoice folderChoice;
                 type = galleryTypes.get(0);
-                add(folderChoice = new DropDownChoice("type", new PropertyModel(this, "type"), galleryTypes,
+                add(folderChoice = new DropDownChoice<>("type", new PropertyModel<String>(this, "type"), galleryTypes,
                         new TypeChoiceRenderer(this)));
                 folderChoice.setNullValid(false);
                 folderChoice.setRequired(true);
@@ -144,24 +139,18 @@
                     Node galleryNode = uploadDialog.getGalleryNode();
                     GalleryWorkflow workflow = (GalleryWorkflow) manager.getWorkflow(this.uploadDialog
                             .getWorkflowCategory(), galleryNode);
-                    String nodeName = uploadDialog.getNodeNameCodec().encode(filename);
+                    String nodeName = uploadDialog.getNodeNameCodec(galleryNode).encode(filename);
                     String localName = uploadDialog.getLocalizeCodec().encode(filename);
                     Document document = workflow.createGalleryItem(nodeName, type);
-                    node = (HippoNode) UserSession.get().getJcrSession().getNodeByUUID(
+                    node = (HippoNode) UserSession.get().getJcrSession().getNodeByIdentifier(
                             document.getIdentity());
                     DefaultWorkflow defaultWorkflow = (DefaultWorkflow) manager.getWorkflow("core", node);
                     if (!node.getLocalizedName().equals(localName)) {
                         defaultWorkflow.localizeName(localName);
                     }
-                } catch (WorkflowException ex) {
+                } catch (WorkflowException | RepositoryException ex) {
                     log.error(ex.getMessage());
                     error(ex);
-                } catch (MappingException ex) {
-                    log.error(ex.getMessage());
-                    error(ex);
-                } catch (RepositoryException ex) {
-                    log.error(ex.getMessage());
-                    error(ex);
                 }
                 if (node != null) {
                     try {
@@ -179,11 +168,7 @@
                         try {
                             DefaultWorkflow defaultWorkflow = (DefaultWorkflow) manager.getWorkflow("core", node);
                             defaultWorkflow.delete();
-                        } catch (WorkflowException e) {
-                            log.error(e.getMessage());
-                        } catch (MappingException e) {
-                            log.error(e.getMessage());
-                        } catch (RepositoryException e) {
+                        } catch (WorkflowException | RepositoryException e) {
                             log.error(e.getMessage());
                         }
                         try {
Index: builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/FolderWorkflowPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/FolderWorkflowPlugin.java	(revision 48312)
+++ builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/FolderWorkflowPlugin.java	(revision )
@@ -36,7 +36,6 @@
 import org.apache.wicket.markup.repeater.data.IDataProvider;
 import org.apache.wicket.markup.repeater.data.ListDataProvider;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.StringResourceModel;
 import org.apache.wicket.request.resource.PackageResource;
 import org.apache.wicket.request.resource.PackageResourceReference;
@@ -46,6 +45,7 @@
 import org.hippoecm.addon.workflow.IWorkflowInvoker;
 import org.hippoecm.addon.workflow.StdWorkflow;
 import org.hippoecm.addon.workflow.WorkflowDescriptorModel;
+import org.hippoecm.frontend.dialog.DialogConstants;
 import org.hippoecm.frontend.dialog.IDialogService.Dialog;
 import org.hippoecm.frontend.i18n.model.NodeTranslator;
 import org.hippoecm.frontend.model.JcrNodeModel;
@@ -55,11 +55,11 @@
 import org.hippoecm.frontend.service.IBrowseService;
 import org.hippoecm.frontend.service.IEditor;
 import org.hippoecm.frontend.service.IEditorManager;
-import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.service.ServiceException;
 import org.hippoecm.frontend.service.render.RenderPlugin;
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.frontend.translation.ILocaleProvider;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.frontend.widgets.AbstractView;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNode;
@@ -67,7 +67,6 @@
 import org.hippoecm.repository.api.HippoWorkspace;
 import org.hippoecm.repository.api.Localized;
 import org.hippoecm.repository.api.StringCodec;
-import org.hippoecm.repository.api.StringCodecFactory;
 import org.hippoecm.repository.api.Workflow;
 import org.hippoecm.repository.api.WorkflowDescriptor;
 import org.hippoecm.repository.api.WorkflowException;
@@ -91,7 +90,7 @@
 
         try {
             WorkflowDescriptorModel model = getModel();
-            List<StdWorkflow> list = new LinkedList<StdWorkflow>();
+            List<StdWorkflow> list = new LinkedList<>();
             WorkflowDescriptor descriptor = model.getObject();
             WorkflowManager manager = UserSession.get().getWorkflowManager();
             Workflow workflow = manager.getWorkflow(descriptor);
@@ -139,7 +138,7 @@
                         // and there is some logic here to look up the parent.  The real solution is
                         // in the visual component to merge two workflows.
                         HippoNode node = (HippoNode) model.getNode();
-                        String nodeName = getNodeNameCodec().encode(renameDocumentModel.getUriName());
+                        String nodeName = getNodeNameCodec(node).encode(renameDocumentModel.getUriName());
                         String localName = getLocalizeCodec().encode(renameDocumentModel.getTargetName());
                         WorkflowManager manager = UserSession.get().getWorkflowManager();
                         DefaultWorkflow defaultWorkflow = (DefaultWorkflow) manager.getWorkflow("core", node);
@@ -156,7 +155,7 @@
 
             if (isActionAvailable("reorder", hints)) {
                 add(new StdWorkflow("reorder", new StringResourceModel("reorder-folder", this, null), context, getModel()) {
-                    public List<String> order = new LinkedList<String>();
+                    public List<String> order = new LinkedList<>();
 
                     @Override
                     protected ResourceReference getIcon() {
@@ -171,7 +170,7 @@
                     @Override
                     protected void execute(WorkflowDescriptorModel model) throws Exception {
                         WorkflowManager manager = UserSession.get().getWorkflowManager();
-                        FolderWorkflow workflow = (FolderWorkflow) manager.getWorkflow((WorkflowDescriptor) model.getObject());
+                        FolderWorkflow workflow = (FolderWorkflow) manager.getWorkflow(model.getObject());
                         workflow.reorder(order);
                     }
                 });
@@ -232,13 +231,13 @@
                         }
 
                         @Override
-                        public IModel getTitle() {
+                        public IModel<String> getTitle() {
                             return new StringResourceModel("delete-title", FolderWorkflowPlugin.this, null);
                         }
 
                         @Override
                         public IValueMap getProperties() {
-                            return SMALL;
+                            return DialogConstants.SMALL;
                         }
                     }
 
@@ -255,7 +254,7 @@
                 });
             }
 
-            final Set<String> translated = new TreeSet<String>();
+            final Set<String> translated = new TreeSet<>();
             if (getPluginConfig().containsKey("workflow.translated")) {
                 Collections.addAll(translated, getPluginConfig().getStringArray("workflow.translated"));
             }
@@ -301,13 +300,13 @@
                                     log.error("unknown folder type " + addDocumentModel.getPrototype());
                                     return "Unknown folder type " + addDocumentModel.getPrototype();
                                 }
-                                String nodeName = getNodeNameCodec().encode(addDocumentModel.getUriName());
+                                String nodeName = getNodeNameCodec(getModel().getNode()).encode(addDocumentModel.getUriName());
                                 String localName = getLocalizeCodec().encode(addDocumentModel.getTargetName());
                                 if ("".equals(nodeName)) {
                                     throw new IllegalArgumentException("You need to enter a name");
                                 }
 
-                                TreeMap<String, String> arguments = new TreeMap<String, String>();
+                                TreeMap<String, String> arguments = new TreeMap<>();
                                 arguments.put("name", nodeName);
                                 arguments.put("localName", localName);
 
@@ -354,17 +353,17 @@
     }
 
     protected Dialog newRenameDocumentDialog(RenameDocumentArguments renameDocumentModel, IWorkflowInvoker invoker) {
+
+        String locale = getCodecLocale();
+        IModel<StringCodec> codecModel = CodecUtils.getNodeNameCodecModel(getPluginContext(), locale);
+
         return new RenameDocumentDialog(
                 renameDocumentModel,
                 new StringResourceModel("rename-title", this, null),
                 invoker,
-                new LoadableDetachableModel<StringCodec>() {
-                    @Override
-                    protected StringCodec load() {
-                        return getNodeNameCodec();
+                codecModel
+        );
                     }
-                });
-    }
 
     protected boolean isLanguageKnown() {
         WorkflowDescriptorModel descriptorModel = (WorkflowDescriptorModel) getDefaultModel();
@@ -385,24 +384,29 @@
     protected AddDocumentDialog createAddDocumentDialog(AddDocumentArguments addDocumentModel,
                                                      String category, Set<String> prototypes, boolean translated,
                                                      IWorkflowInvoker invoker) {
-        return new AddDocumentDialog(
+        String locale = getCodecLocale();
+        IModel<StringCodec> codecModel = CodecUtils.getNodeNameCodecModel(getPluginContext(), locale);
+
+        AddDocumentDialog dialog = new AddDocumentDialog(
                 addDocumentModel,
                 new StringResourceModel(category, this, null),
                 category,
                 prototypes,
                 translated && !isLanguageKnown(),
                 invoker,
-                new LoadableDetachableModel<StringCodec>() {
-                    @Override
-                    protected StringCodec load() {
-                        return getNodeNameCodec();
+                codecModel,
+                getLocaleProvider()
+        );
+
+        if (locale != null) {
+            dialog.getLanguageField().setVisible(false);
                     }
-                },
-                getLocaleProvider());
+
+        return dialog;
     }
 
     protected IDataProvider<StdWorkflow> createListDataProvider(List<StdWorkflow> list) {
-        return new ListDataProvider<StdWorkflow>(list);
+        return new ListDataProvider<>(list);
     }
 
     @SuppressWarnings("unchecked")
@@ -470,21 +474,25 @@
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID, ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
-    protected StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID, ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
+    protected StringCodec getNodeNameCodec(Node node) {
+        return CodecUtils.getNodeNameCodec(getPluginContext(), node);
     }
 
     protected ILocaleProvider getLocaleProvider() {
         return getPluginContext().getService(
                 getPluginConfig().getString(ILocaleProvider.SERVICE_ID, ILocaleProvider.class.getName()),
                 ILocaleProvider.class);
+    }
+
+    private String getCodecLocale() {
+        try {
+            return CodecUtils.getLocaleFromNode(getModel().getNode());
+        } catch (RepositoryException e) {
+            return null;
+        }
     }
 
 }
Index: test/src/test/java/org/hippoecm/frontend/editor/workflow/CopyNameHelperTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/src/test/java/org/hippoecm/frontend/editor/workflow/CopyNameHelperTest.java	(revision 48312)
+++ test/src/test/java/org/hippoecm/frontend/editor/workflow/CopyNameHelperTest.java	(revision )
@@ -15,18 +15,21 @@
  */
 package org.hippoecm.frontend.editor.workflow;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
+import org.hippoecm.repository.api.StringCodec;
 import org.hippoecm.repository.api.StringCodecFactory.UriEncoding;
 import org.junit.Test;
 
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
 public class CopyNameHelperTest {
     
     @Test
@@ -35,7 +38,7 @@
         expect(folder.hasNode("bla-kopietje")).andReturn(false);
         replay(folder);
 
-        CopyNameHelper helper = new CopyNameHelper(new UriEncoding(), "kopietje");
+        CopyNameHelper helper = new CopyNameHelper(newStringCodecModel(new UriEncoding()), "kopietje");
         assertEquals("bla (kopietje)", helper.getCopyName("bla", folder));
         verify();
     }
@@ -47,7 +50,7 @@
         expect(folder.hasNode("bla-kopietje-2")).andReturn(false);
         replay(folder);
 
-        CopyNameHelper helper = new CopyNameHelper(new UriEncoding(), "kopietje");
+        CopyNameHelper helper = new CopyNameHelper(newStringCodecModel(new UriEncoding()), "kopietje");
         String newName = helper.getCopyName("bla", folder);
         verify();
         assertEquals("bla (kopietje 2)", newName); 
@@ -61,9 +64,19 @@
         expect(folder.hasNode("bla-kopietje-3")).andReturn(false);
         replay(folder);
 
-        CopyNameHelper helper = new CopyNameHelper(new UriEncoding(), "kopietje");
+        CopyNameHelper helper = new CopyNameHelper(newStringCodecModel(new UriEncoding()), "kopietje");
         String newName = helper.getCopyName("bla", folder);
         verify();
         assertEquals("bla (kopietje 3)", newName); 
     }
+
+    private IModel<StringCodec> newStringCodecModel(final StringCodec codec) {
+        return new AbstractReadOnlyModel<StringCodec>() {
+            @Override
+            public StringCodec getObject() {
+                return codec;
+            }
+        };
+    }
+
 }
Index: api/src/main/java/org/hippoecm/frontend/i18n/types/TypeChoiceRenderer.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- api/src/main/java/org/hippoecm/frontend/i18n/types/TypeChoiceRenderer.java	(revision 48312)
+++ api/src/main/java/org/hippoecm/frontend/i18n/types/TypeChoiceRenderer.java	(revision )
@@ -20,7 +20,7 @@
 import org.apache.wicket.model.StringResourceModel;
 import org.hippoecm.frontend.model.nodetypes.JcrNodeTypeModel;
 
-public class TypeChoiceRenderer implements IChoiceRenderer {
+public class TypeChoiceRenderer implements IChoiceRenderer<String> {
 
     private static final long serialVersionUID = 1L;
 
@@ -30,8 +30,8 @@
         this.component = component;
     }
 
-    public Object getDisplayValue(Object object) {
-        String type = (String) object;
+    @Override
+    public Object getDisplayValue(final String type) {
         JcrNodeTypeModel nodeTypeModel = new JcrNodeTypeModel(type);
         if (nodeTypeModel.getObject() != null) {
             return new TypeTranslator(nodeTypeModel).getTypeName().getObject();
@@ -40,7 +40,8 @@
         }
     }
 
-    public String getIdValue(Object object, int index) {
-        return object.toString();
+    @Override
+    public String getIdValue(final String type, final int index) {
+        return type;
     }
 }
Index: translation/frontend/src/main/java/org/hippoecm/frontend/translation/workflow/TranslationWorkflowPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- translation/frontend/src/main/java/org/hippoecm/frontend/translation/workflow/TranslationWorkflowPlugin.java	(revision 48312)
+++ translation/frontend/src/main/java/org/hippoecm/frontend/translation/workflow/TranslationWorkflowPlugin.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2010-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2010-2015 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.
@@ -68,12 +68,12 @@
 import org.hippoecm.frontend.translation.components.document.FolderTranslation;
 import org.hippoecm.frontend.types.IFieldDescriptor;
 import org.hippoecm.frontend.types.ITypeDescriptor;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.repository.HippoStdNodeType;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNode;
 import org.hippoecm.repository.api.HippoWorkspace;
 import org.hippoecm.repository.api.StringCodec;
-import org.hippoecm.repository.api.StringCodecFactory;
 import org.hippoecm.repository.api.Workflow;
 import org.hippoecm.repository.api.WorkflowDescriptor;
 import org.hippoecm.repository.api.WorkflowException;
@@ -325,9 +325,9 @@
                 if (autoTranslateContent) {
                     Workflow translateWorkflow = manager.getWorkflow("translate", translatedVariant);
                     if (translateWorkflow instanceof TranslateWorkflow) {
-                        Set<String> plainTextFields = new TreeSet<String>();
-                        Set<String> richTextFields = new TreeSet<String>();
-                        Set<String> allTextFields = new TreeSet<String>();
+                        Set<String> plainTextFields = new TreeSet<>();
+                        Set<String> richTextFields = new TreeSet<>();
+                        Set<String> allTextFields = new TreeSet<>();
                         String primaryNodeTypeName = session.getNodeByIdentifier(
                                 translatedVariant.getIdentity()).getPrimaryNodeType().getName();
                         collectFields(null, primaryNodeTypeName, plainTextFields, richTextFields);
@@ -700,10 +700,7 @@
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                                                                         ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
     @Override
Index: richtext/frontend/src/main/java/org/hippoecm/frontend/plugins/richtext/dialog/images/ImageBrowserDialog.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- richtext/frontend/src/main/java/org/hippoecm/frontend/plugins/richtext/dialog/images/ImageBrowserDialog.java	(revision 48312)
+++ richtext/frontend/src/main/java/org/hippoecm/frontend/plugins/richtext/dialog/images/ImageBrowserDialog.java	(revision )
@@ -76,6 +76,7 @@
 import org.hippoecm.frontend.plugins.yui.upload.validation.FileUploadValidationService;
 import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.session.UserSession;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.frontend.validation.IValidationResult;
 import org.hippoecm.frontend.validation.ValidationException;
 import org.hippoecm.frontend.widgets.ThrottledTextFieldWidget;
@@ -394,7 +395,7 @@
                         Node folderNode = getFolderModel().getObject();
 
                         //TODO replace shortcuts with custom workflow category(?)
-                        String nodeName = getNodeNameCodec().encode(filename);
+                        String nodeName = getNodeNameCodec(folderNode).encode(filename);
                         localName = getLocalizeCodec().encode(filename);
                         GalleryWorkflow workflow = (GalleryWorkflow) manager.getWorkflow("gallery", folderNode);
                         Document document = workflow.createGalleryItem(nodeName, getGalleryType());
@@ -523,16 +524,12 @@
         return new DefaultGalleryProcessor();
     }
 
-    private StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID, ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
+    private StringCodec getNodeNameCodec(Node node) {
+        return CodecUtils.getNodeNameCodec(getPluginContext(), node);
     }
 
     private StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID, ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
     private String getGalleryType() {
Index: api/src/main/java/org/hippoecm/frontend/editor/workflow/CopyNameHelper.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- api/src/main/java/org/hippoecm/frontend/editor/workflow/CopyNameHelper.java	(revision 48312)
+++ api/src/main/java/org/hippoecm/frontend/editor/workflow/CopyNameHelper.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2010-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2010-2015 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.
@@ -21,17 +21,23 @@
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
 import org.hippoecm.repository.api.StringCodec;
 
 public class CopyNameHelper {
 
     private final Pattern firstcopy;
     private final Pattern othercopies;
-    private final StringCodec codec;
+    private final IModel<StringCodec> codecModel;
     private final String copyOf;
 
     public CopyNameHelper(StringCodec codec, String copyOf) {
-        this.codec = codec;
+        this(createModel(codec), copyOf);
+    }
+
+    public CopyNameHelper(IModel<StringCodec> codecModel, String copyOf) {
+        this.codecModel = codecModel;
         this.copyOf = copyOf;
         this.firstcopy = Pattern.compile(".* \\(" + copyOf + "\\)$");
         this.othercopies = Pattern.compile(".* \\(" + copyOf + " ([0-9]*?)\\)$");
@@ -61,7 +67,7 @@
                 } else {
                     name = base + " (" + copyOf + " " + (number) + ")";
                 }
-                nodeName = codec.encode(name);
+                nodeName = codecModel.getObject().encode(name);
                 number++;
             } while (folder.hasNode(nodeName));
         } else {
@@ -69,4 +75,14 @@
         }
         return name;
     }
+
+    private static IModel<StringCodec> createModel(final StringCodec codec) {
+        return new AbstractReadOnlyModel<StringCodec>() {
+            @Override
+            public StringCodec getObject() {
+                return codec;
+            }
+        };
+    }
+
 }
Index: builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/components/LanguageField.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/components/LanguageField.java	(revision 48312)
+++ builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/components/LanguageField.java	(revision )
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2013 Hippo B.V. (http://www.onehippo.com)
+ * Copyright 2010-2015 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.
@@ -20,6 +20,8 @@
 import java.util.Comparator;
 import java.util.List;
 
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.IChoiceRenderer;
@@ -30,15 +32,13 @@
 public class LanguageField extends WebMarkupContainer {
     private static final long serialVersionUID = 1L;
 
-    private final DropDownChoice<String> languageChoice;
-
     public LanguageField(String id, IModel<String> languageModel, final ILocaleProvider provider) {
         super(id);
 
         List<String> languages = Collections.emptyList();
         if (provider != null) {
             List<? extends HippoLocale> locales = provider.getLocales();
-            ArrayList<HippoLocale> ordered = new ArrayList<HippoLocale>(locales);
+            ArrayList<HippoLocale> ordered = new ArrayList<>(locales);
             Collections.sort(ordered, new Comparator<HippoLocale>() {
 
                 @Override
@@ -47,17 +47,21 @@
                 }
 
             });
-            languages = new ArrayList<String>(ordered.size());
+            languages = new ArrayList<>(ordered.size());
             for (HippoLocale locale : ordered) {
                 languages.add(locale.getName());
             }
         }
-        add(languageChoice = new DropDownChoice<String>("select", languageModel, languages,
+
+        final DropDownChoice<String> languageChoice;
+        add(languageChoice = new DropDownChoice<>("select", languageModel, languages,
                 new IChoiceRenderer<String>() {
                     private static final long serialVersionUID = 1L;
 
-                    @SuppressWarnings("null")
                     public Object getDisplayValue(String object) {
+                        if (provider == null) {
+                            return object;
+                        }
                         return provider.getLocale(object).getDisplayName(getLocale());
                     }
 
@@ -68,7 +72,17 @@
                 }));
         languageChoice.setNullValid(false);
         languageChoice.setRequired(true);
+        languageChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                LanguageField.this.onSelectionChanged();
+            }
+        });
         setOutputMarkupPlaceholderTag(true);
+    }
+
+    protected void onSelectionChanged() {
     }
 
 }
Index: gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/GalleryShortcutPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/GalleryShortcutPlugin.java	(revision 48312)
+++ gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/GalleryShortcutPlugin.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2008-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2008-2015 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.
@@ -15,6 +15,8 @@
  */
 package org.hippoecm.frontend.plugins.gallery;
 
+import javax.jcr.Node;
+
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.markup.html.basic.Label;
@@ -25,7 +27,7 @@
 import org.hippoecm.frontend.plugins.gallery.upload.UploadDialog;
 import org.hippoecm.frontend.service.render.RenderPlugin;
 
-public class GalleryShortcutPlugin extends RenderPlugin {
+public class GalleryShortcutPlugin extends RenderPlugin<Node> {
     private static final long serialVersionUID = 1L;
 
     public GalleryShortcutPlugin(IPluginContext context, IPluginConfig config) {
@@ -39,7 +41,7 @@
                 IDialogService dialogService = getDialogService();
                 UploadDialog dialog = new UploadDialog(GalleryShortcutPlugin.this.getPluginContext(),
                                                        GalleryShortcutPlugin.this.getPluginConfig(),
-                                                       GalleryShortcutPlugin.this.getDefaultModel());
+                                                       GalleryShortcutPlugin.this.getModel());
                 dialogService.show(dialog);
             }
         };
Index: builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/RenameDocumentDialog.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/RenameDocumentDialog.java	(revision 48312)
+++ builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/RenameDocumentDialog.java	(revision )
@@ -34,31 +34,33 @@
 import org.apache.wicket.util.value.IValueMap;
 import org.hippoecm.addon.workflow.AbstractWorkflowDialog;
 import org.hippoecm.addon.workflow.IWorkflowInvoker;
+import org.hippoecm.frontend.dialog.DialogConstants;
 import org.hippoecm.frontend.plugins.standards.list.resolvers.CssClassAppender;
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.repository.api.StringCodec;
 
 public class RenameDocumentDialog extends AbstractWorkflowDialog<RenameDocumentArguments> {
-    private IModel title;
+
+    private IModel<String> title;
     private TextField nameComponent;
     private TextField uriComponent;
     private boolean uriModified;
     private final IModel<StringCodec> nodeNameCodecModel;
 
-    public RenameDocumentDialog(RenameDocumentArguments renameDocumentModel, IModel title, IWorkflowInvoker invoker,
-            IModel<StringCodec> nodeNameCodec) {
+    public RenameDocumentDialog(RenameDocumentArguments renameDocumentModel, IModel<String> title,
+                                IWorkflowInvoker invoker, IModel<StringCodec> nodeNameCodec) {
         super(Model.of(renameDocumentModel), invoker);
         this.title = title;
         this.nodeNameCodecModel = nodeNameCodec;
 
-        final PropertyModel<String> nameModel = new PropertyModel<String>(renameDocumentModel, "targetName");
-        final PropertyModel<String> uriModel = new PropertyModel<String>(renameDocumentModel, "uriName");
+        final PropertyModel<String> nameModel = new PropertyModel<>(renameDocumentModel, "targetName");
+        final PropertyModel<String> uriModel = new PropertyModel<>(renameDocumentModel, "uriName");
 
         String s1 = nameModel.getObject();
         String s2 = uriModel.getObject();
         uriModified = !s1.equals(s2);
 
-        nameComponent = new TextField<String>("name", nameModel);
+        nameComponent = new TextField<>("name", nameModel);
         nameComponent.setRequired(true);
         nameComponent.setLabel(new StringResourceModel("name-label", this, null));
         nameComponent.add(new OnChangeAjaxBehavior() {
@@ -126,17 +128,17 @@
         final RenameMessage message = new RenameMessage(cmsLocale, renameDocumentModel.getLocalizedNames());
         if (message.shouldShow()) {
             warn(message.forFolder());
-        };
-    }
+        }
+    }
 
     @Override
-    public IModel getTitle() {
+    public IModel<String> getTitle() {
         return title;
     }
 
     @Override
     public IValueMap getProperties() {
-        return MEDIUM;
+        return DialogConstants.MEDIUM;
     }
 
     protected StringCodec getNodeNameCodec() {
Index: builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/AddDocumentDialog.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/AddDocumentDialog.java	(revision 48312)
+++ builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/AddDocumentDialog.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2012-2015 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.
@@ -40,6 +40,7 @@
 import org.apache.wicket.util.value.IValueMap;
 import org.hippoecm.addon.workflow.AbstractWorkflowDialog;
 import org.hippoecm.addon.workflow.IWorkflowInvoker;
+import org.hippoecm.frontend.dialog.DialogConstants;
 import org.hippoecm.frontend.i18n.types.SortedTypeChoiceRenderer;
 import org.hippoecm.frontend.plugins.standards.list.resolvers.CssClassAppender;
 import org.hippoecm.frontend.plugins.standardworkflow.components.LanguageField;
@@ -47,23 +48,26 @@
 import org.hippoecm.repository.api.StringCodec;
 
 public class AddDocumentDialog extends AbstractWorkflowDialog<AddDocumentArguments> {
-    private IModel title;
+
+    private IModel<String> title;
     private TextField nameComponent;
     private TextField uriComponent;
     private boolean uriModified = false;
     private LanguageField languageField;
     private final IModel<StringCodec> nodeNameCodecModel;
 
-    public AddDocumentDialog(AddDocumentArguments addDocumentModel, IModel title, String category, Set<String> prototypes, boolean translated, final IWorkflowInvoker invoker, IModel<StringCodec> nodeNameCodec, ILocaleProvider localeProvider) {
+    public AddDocumentDialog(AddDocumentArguments addDocumentModel, IModel<String> title, String category,
+                             Set<String> prototypes, boolean translated, final IWorkflowInvoker invoker,
+                             IModel<StringCodec> nodeNameCodec, ILocaleProvider localeProvider) {
         super(Model.of(addDocumentModel), invoker);
         this.title = title;
         this.nodeNameCodecModel = nodeNameCodec;
 
-        final PropertyModel<String> nameModel = new PropertyModel<String>(addDocumentModel, "targetName");
-        final PropertyModel<String> uriModel = new PropertyModel<String>(addDocumentModel, "uriName");
-        final PropertyModel<String> prototypeModel = new PropertyModel<String>(addDocumentModel, "prototype");
+        final PropertyModel<String> nameModel = new PropertyModel<>(addDocumentModel, "targetName");
+        final PropertyModel<String> uriModel = new PropertyModel<>(addDocumentModel, "uriName");
+        final PropertyModel<String> prototypeModel = new PropertyModel<>(addDocumentModel, "prototype");
 
-        nameComponent = new TextField<String>("name", new IModel<String>() {
+        nameComponent = new TextField<>("name", new IModel<String>() {
             private static final long serialVersionUID = 1L;
 
             public String getObject() {
@@ -102,14 +106,14 @@
         setFocus(nameComponent);
         add(nameComponent);
 
-        final Label typelabel;
-        add(typelabel = new Label("typelabel", new StringResourceModel("document-type", this, null)));
+        final Label typeLabel;
+        add(typeLabel = new Label("typelabel", new StringResourceModel("document-type", this, null)));
 
         if (prototypes.size() > 1) {
-            final List<String> prototypesList = new LinkedList<String>(prototypes);
+            final List<String> prototypesList = new LinkedList<>(prototypes);
             final DropDownChoice<String> folderChoice;
             SortedTypeChoiceRenderer typeChoiceRenderer = new SortedTypeChoiceRenderer(this, prototypesList);
-            add(folderChoice = new DropDownChoice<String>("prototype", prototypeModel, typeChoiceRenderer, typeChoiceRenderer));
+            add(folderChoice = new DropDownChoice<>("prototype", prototypeModel, typeChoiceRenderer, typeChoiceRenderer));
             folderChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
                 @Override
                 protected void onUpdate(AjaxRequestTarget target) {
@@ -119,19 +123,16 @@
             folderChoice.setNullValid(false);
             folderChoice.setRequired(true);
             folderChoice.setLabel(new StringResourceModel("document-type", this, null));
+
             // while not a prototype chosen, disable ok button
-            Component notypes;
-            add(notypes = new EmptyPanel("notypes"));
-            notypes.setVisible(false);
+            add(new EmptyPanel("notypes").setVisible(false));
         } else if (prototypes.size() == 1) {
             Component component;
             add(component = new EmptyPanel("prototype"));
             component.setVisible(false);
             prototypeModel.setObject(prototypes.iterator().next());
-            Component notypes;
-            add(notypes = new EmptyPanel("notypes"));
-            notypes.setVisible(false);
-            typelabel.setVisible(false);
+            add(new EmptyPanel("notypes").setVisible(false));
+            typeLabel.setVisible(false);
         } else {
             // if the folderWorkflowPlugin.templates.get(category).size() = 0 you cannot add this
             // category currently.
@@ -142,7 +143,7 @@
             add(new Label("notypes", "There are no types available for : [" + category
                     + "] First create document types please."));
             nameComponent.setVisible(false);
-            typelabel.setVisible(false);
+            typeLabel.setVisible(false);
         }
 
         add(uriComponent = new TextField<String>("uriinput", uriModel) {
@@ -192,13 +193,13 @@
     }
 
     @Override
-    public IModel getTitle() {
+    public IModel<String> getTitle() {
         return title;
     }
 
     @Override
     public IValueMap getProperties() {
-        return MEDIUM;
+        return DialogConstants.MEDIUM;
     }
 
     public LanguageField getLanguageField() {
Index: engine/src/main/java/org/hippoecm/frontend/service/settings/SettingsStorePlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- engine/src/main/java/org/hippoecm/frontend/service/settings/SettingsStorePlugin.java	(revision 48312)
+++ engine/src/main/java/org/hippoecm/frontend/service/settings/SettingsStorePlugin.java	(revision )
@@ -16,13 +16,12 @@
 package org.hippoecm.frontend.service.settings;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import org.hippoecm.frontend.service.ISettingsService;
-import org.hippoecm.frontend.service.preferences.*;
+
 import org.hippoecm.frontend.plugin.IPluginContext;
 import org.hippoecm.frontend.plugin.Plugin;
 import org.hippoecm.frontend.plugin.config.IPluginConfig;
+import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.repository.api.StringCodec;
 import org.hippoecm.repository.api.StringCodecFactory;
 import org.slf4j.Logger;
@@ -30,11 +29,9 @@
 
 public class SettingsStorePlugin extends Plugin implements ISettingsService {
     private static final long serialVersionUID = 1L;
-    @SuppressWarnings("unused")
 
+    public static final Logger log = LoggerFactory.getLogger(SettingsStorePlugin.class);
 
-    static final Logger log = LoggerFactory.getLogger(SettingsStorePlugin.class);
-
     transient StringCodecFactory stringCodecFactory;
 
     public SettingsStorePlugin(IPluginContext context, IPluginConfig config) {
@@ -46,19 +43,13 @@
     public StringCodecFactory getStringCodecFactory() {
         if (stringCodecFactory == null) {
             IPluginConfig codecsConfig = getPluginConfig().getPluginConfig("codecs");
-            Map<String, StringCodec> codecs = new HashMap<String, StringCodec>();
+            Map<String, StringCodec> codecs = new HashMap<>();
             for (String codecName : codecsConfig.keySet()) {
                 try {
                     String className = codecsConfig.getString(codecName);
                     Class<? extends StringCodec> clazz = Thread.currentThread().getContextClassLoader().loadClass(className).asSubclass(StringCodec.class);
                     codecs.put(codecName, clazz.newInstance());
-                } catch (InstantiationException ex) {
-                    log.error("unable to create " + codecName, ex);
-                } catch (IllegalAccessException ex) {
-                    log.error("unable to create " + codecName, ex);
-                } catch (ClassCastException ex) {
-                    log.error("1`unable to create " + codecName, ex);
-                } catch (ClassNotFoundException ex) {
+                } catch (InstantiationException | ClassNotFoundException | ClassCastException | IllegalAccessException ex) {
                     log.error("unable to create " + codecName, ex);
                 }
             }
Index: workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RenameDocumentDialog.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RenameDocumentDialog.java	(revision 48312)
+++ workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RenameDocumentDialog.java	(revision )
@@ -34,27 +34,25 @@
 import org.apache.wicket.util.value.IValueMap;
 import org.hippoecm.addon.workflow.AbstractWorkflowDialog;
 import org.hippoecm.addon.workflow.StdWorkflow;
-import org.hippoecm.frontend.plugin.IPluginContext;
+import org.hippoecm.frontend.dialog.DialogConstants;
 import org.hippoecm.frontend.plugins.standards.list.resolvers.CssClassAppender;
 import org.hippoecm.frontend.plugins.standardworkflow.RenameMessage;
-import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.repository.api.Localized;
 import org.hippoecm.repository.api.StringCodec;
-import org.hippoecm.repository.api.StringCodecFactory;
 
 public  class RenameDocumentDialog extends AbstractWorkflowDialog<Void> {
         private IModel<String> title;
-        private TextField nameComponent;
-        private TextField uriComponent;
+        private IModel<StringCodec> codec;
+        private TextField<String> nameComponent;
+        private TextField<String> uriComponent;
         private boolean uriModified;
-        private IPluginContext context;
 
-        public RenameDocumentDialog(StdWorkflow action, IModel<String> title, IPluginContext context) {
+        public RenameDocumentDialog(StdWorkflow action, IModel<String> title, IModel<StringCodec> codecModel) {
             super(null, action);
 
             this.title = title;
-            this.context = context;
+            this.codec = codecModel;
 
             final PropertyModel<String> nameModel = new PropertyModel<>(action, "targetName");
             final PropertyModel<String> uriModel = new PropertyModel<>(action, "uriName");
@@ -72,12 +70,26 @@
                 @Override
                 protected void onUpdate(AjaxRequestTarget target) {
                     if (!uriModified) {
-                        uriModel.setObject(getNodeNameCodec().encode(nameModel.getObject()));
+                        String encoded = codec.getObject().encode(nameModel.getObject());
+                        uriModel.setObject(encoded);
                         target.add(uriComponent);
                     }
                 }
 
                 @Override
+                protected void onError(final AjaxRequestTarget target, final RuntimeException e) {
+                    super.onError(target, e);
+
+                    //if we get past the super call, RunTimeException e is null and we are dealing with
+                    //either a validation or a conversion error, so we can/should update the URI component if needed
+                    String rawInput = nameComponent.getInput();
+                    if (!uriModified && Strings.isEmpty(rawInput)) {
+                        uriModel.setObject("");
+                        target.add(uriComponent);
+                    }
+                }
+
+                @Override
                 protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
                     super.updateAjaxAttributes(attributes);
                     attributes.setThrottlingSettings(new ThrottlingSettings(nameComponent.getPath(), Duration.milliseconds(500)));
@@ -107,8 +119,9 @@
                 public void onClick(AjaxRequestTarget target) {
                     uriModified = !uriModified;
                     if (!uriModified) {
-                        uriModel.setObject(Strings.isEmpty(nameModel.getObject()) ? "" : getNodeNameCodec().encode(
-                                nameModel.getObject()));
+                        String uri = Strings.isEmpty(nameModel.getObject()) ? ""
+                                : codec.getObject().encode(nameModel.getObject());
+                        uriModel.setObject(uri);
                     } else {
                         target.focusComponent(uriComponent);
                     }
@@ -130,13 +143,6 @@
             }
         }
 
-        protected StringCodec getNodeNameCodec() {
-            ISettingsService settingsService = context.getService(ISettingsService.SERVICE_ID,
-                    ISettingsService.class);
-            StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-            return stringCodecFactory.getStringCodec("encoding.node");
-        }
-
         @Override
         public IModel<String> getTitle() {
             return title;
@@ -144,6 +150,6 @@
 
         @Override
         public IValueMap getProperties() {
-            return MEDIUM;
+            return DialogConstants.MEDIUM;
         }
     }
\ No newline at end of file
Index: builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/components/NameUriField.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/components/NameUriField.java	(revision 48312)
+++ builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/components/NameUriField.java	(revision )
@@ -37,31 +37,30 @@
 public class NameUriField extends WebMarkupContainer {
     private static final long serialVersionUID = 1L;
 
-    private final Component urlComponent;
-
-    private boolean urlModified = false;
-
-    private PropertyModel<String> urlModel;
-    private PropertyModel<String> nameModel;
-
-    private String name;
+    @SuppressWarnings("unused")
     private String url;
+    @SuppressWarnings("unused")
+    private String name;
-    
+
-    private Component nameComponent;
+    private final Component urlComponent;
+    private final Component nameComponent;
 
+    private final PropertyModel<String> urlModel;
+    private final PropertyModel<String> nameModel;
     private final IModel<StringCodec> codecModel;
 
+    private boolean urlModified = false;
+
     public NameUriField(String id, IModel<StringCodec> codecModel) {
         super(id);
         this.codecModel = codecModel;
 
-        nameModel = new PropertyModel<String>(this, "name");
-        urlModel = new PropertyModel<String>(this, "url");
+        urlModel = PropertyModel.of(this, "url");
+        nameModel = PropertyModel.of(this, "name");
 
-        nameComponent = createNameComponent(nameModel);
-        add(nameComponent);
+        add(urlComponent = createUriComponent(urlModel));
+        add(nameComponent = createNameComponent(nameModel));
 
-        add(urlComponent = createUriComponent(nameModel, urlModel));
         add(createUrlAction());
     }
 
@@ -74,12 +73,12 @@
         super.onBeforeRender();
     }
 
-    private StringCodec getNodeNameCodec() {
-        return codecModel.getObject();
+    private String encode(final IModel<String> text) {
+        return codecModel.getObject().encode(text.getObject());
     }
     
     private Component createNameComponent(final PropertyModel<String> nameModel) {
-        final FormComponent nameComponent = new TextField<String>("name", new IModel<String>() {
+        final FormComponent nameComponent = new TextField<>("name", new IModel<String>() {
             private static final long serialVersionUID = 1L;
 
             public String getObject() {
@@ -89,7 +88,7 @@
             public void setObject(String object) {
                 nameModel.setObject(object);
                 if (!urlModified) {
-                    urlModel.setObject(getNodeNameCodec().encode(nameModel.getObject()));
+                    urlModel.setObject(encode(nameModel));
                 }
             }
 
@@ -117,7 +116,7 @@
         return nameComponent;
     }
 
-    private Component createUriComponent(final PropertyModel<String> nameModel, final PropertyModel<String> urlModel) {
+    private Component createUriComponent(final PropertyModel<String> urlModel) {
         FormComponent urlComponent = new TextField<String>("url", urlModel) {
             @Override
             public boolean isEnabled() {
@@ -141,8 +140,7 @@
             public void onClick(AjaxRequestTarget target) {
                 urlModified = !urlModified;
                 if (!urlModified) {
-                    urlModel.setObject(Strings.isEmpty(nameModel.getObject()) ? "" : getNodeNameCodec().encode(
-                            nameModel.getObject()));
+                    urlModel.setObject(Strings.isEmpty(nameModel.getObject()) ? "" : encode(nameModel));
                 } else {
                     target.focusComponent(urlComponent);
                 }
@@ -164,5 +162,16 @@
 
     public String getUrl() {
         return url;
+    }
+
+    public void encodeUri() {
+        if (!urlModified) {
+            final String name = Strings.isEmpty(nameModel.getObject()) ? "" : encode(nameModel);
+            urlModel.setObject(name);
+            AjaxRequestTarget target = RequestCycle.get().find(AjaxRequestTarget.class);
+            if (target != null) {
+                target.add(urlComponent);
+            }
+        }
     }
 }
Index: gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/GalleryWorkflowPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/GalleryWorkflowPlugin.java	(revision 48312)
+++ gallery/frontend/src/main/java/org/hippoecm/frontend/plugins/gallery/GalleryWorkflowPlugin.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2009-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2009-2015 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.
@@ -53,6 +53,7 @@
 import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.frontend.translation.ILocaleProvider;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.frontend.widgets.AbstractView;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNode;
@@ -121,18 +122,20 @@
 
     private void createGalleryItem(FileUpload upload) throws GalleryException {
         try (InputStream is = upload.getInputStream()) {
-            String filename = upload.getClientFileName();
-            String mimetype = upload.getContentType();
+            String fileName = upload.getClientFileName();
+            String mimeType = upload.getContentType();
 
             WorkflowManager manager = UserSession.get().getWorkflowManager();
             HippoNode node;
             try {
                 WorkflowDescriptorModel workflowDescriptorModel = (WorkflowDescriptorModel) GalleryWorkflowPlugin.this
                         .getDefaultModel();
+
                 GalleryWorkflow workflow = (GalleryWorkflow) manager
                         .getWorkflow(workflowDescriptorModel.getObject());
-                String nodeName = getNodeNameCodec().encode(filename);
-                String localName = getLocalizeCodec().encode(filename);
+
+                String nodeName = getNodeNameCodec(workflowDescriptorModel.getNode()).encode(fileName);
+                String localName = getLocalizeCodec().encode(fileName);
                 Document document = workflow.createGalleryItem(nodeName, type);
                 node = (HippoNode) UserSession.get().getJcrSession()
                         .getNodeByIdentifier(document.getIdentity());
@@ -149,14 +152,14 @@
             }
 
             try {
-                getGalleryProcessor().makeImage(node, is, mimetype, filename);
+                getGalleryProcessor().makeImage(node, is, mimeType, fileName);
                 node.getSession().save();
                 onGalleryItemCreation(node);
                 newItems.add(node.getPath());
             } catch (Exception ex) {
                 remove(manager, node);
                 final StringResourceModel messageModel = new StringResourceModel("upload-failed-named-label",
-                        GalleryWorkflowPlugin.this, null, null, filename);
+                        GalleryWorkflowPlugin.this, null, null, fileName);
                 throw new GalleryException(messageModel.getString(), ex);
             }
         } catch (IOException ex) {
@@ -259,17 +262,11 @@
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
-    protected StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
+    protected StringCodec getNodeNameCodec(final Node node) {
+        return CodecUtils.getNodeNameCodec(getPluginContext(), node);
     }
 
     protected ILocaleProvider getLocaleProvider() {
Index: editor/frontend/src/main/java/org/hippoecm/frontend/editor/workflow/DefaultWorkflowPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- editor/frontend/src/main/java/org/hippoecm/frontend/editor/workflow/DefaultWorkflowPlugin.java	(revision 48312)
+++ editor/frontend/src/main/java/org/hippoecm/frontend/editor/workflow/DefaultWorkflowPlugin.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2008-2014 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2008-2015 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.
@@ -68,8 +68,10 @@
 import org.hippoecm.frontend.service.render.RenderPlugin;
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.frontend.skin.Icon;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNode;
+import org.hippoecm.repository.api.HippoNodeType;
 import org.hippoecm.repository.api.Localized;
 import org.hippoecm.repository.api.StringCodec;
 import org.hippoecm.repository.api.StringCodecFactory;
@@ -189,11 +191,11 @@
 
             @Override
             protected String execute(Workflow wf) throws Exception {
-                if (targetName == null || targetName.trim().equals("")) {
+                if (Strings.isEmpty(targetName)) {
                     throw new WorkflowException("No name for destination given");
                 }
                 HippoNode node = (HippoNode) getModel().getNode();
-                String nodeName = getNodeNameCodec().encode(uriName);
+                String nodeName = getNodeNameCodec(node).encode(uriName);
                 String localName = getLocalizeCodec().encode(targetName);
                 if ("".equals(nodeName)) {
                     throw new IllegalArgumentException("You need to enter a name");
@@ -211,7 +213,7 @@
         });
 
         add(copyAction = new StdWorkflow("copy", new StringResourceModel("copy-label", this, null), context, getModel()) {
-            NodeModelWrapper destination = null;
+            NodeModelWrapper<Node> destination = null;
             String name = null;
 
             @Override
@@ -226,7 +228,7 @@
 
             @Override
             protected Dialog createRequestDialog() {
-                destination = new NodeModelWrapper(getFolder()) {
+                destination = new NodeModelWrapper<Node>(getFolder()) {
                 };
                 try {
                     HippoNode node = (HippoNode) getModel().getNode();
@@ -235,9 +237,12 @@
                     if (isExtension(nodeName, KNOWN_IMAGE_EXTENSIONS)) {
                         createNewNodeNameForImage(nodeName);
                     } else {
+                        String locale = CodecUtils.getLocaleFromNode(getFolder().getNode());
+                        IModel<StringCodec> codec = CodecUtils.getNodeNameCodecModel(context, locale);
                         String copyof = new StringResourceModel("copyof", DefaultWorkflowPlugin.this, null).getString();
-                        CopyNameHelper copyNameHelper = new CopyNameHelper(getNodeNameCodec(), copyof);
-                        name = copyNameHelper.getCopyName(nodeName, destination.getNodeModel().getNode());
+                        CopyNameHelper copyNameHelper = new CopyNameHelper(codec, copyof);
+
+                        name = copyNameHelper.getCopyName(nodeName, destination.getChainedModel().getObject());
                     }
                 } catch (RepositoryException ex) {
                     return new ExceptionDialog(ex);
@@ -245,7 +250,7 @@
                 return new DestinationDialog(
                         new StringResourceModel("copy-title", DefaultWorkflowPlugin.this, null),
                         new StringResourceModel("copy-name", DefaultWorkflowPlugin.this, null),
-                        new PropertyModel(this, "name"), destination, context, config) {
+                        new PropertyModel<String>(this, "name"), destination, context, config) {
                     {
                         setOkEnabled(true);
                     }
@@ -267,7 +272,7 @@
              */
             private void createNewNodeNameForImage(final String nodeName) throws RepositoryException {
                 name = nodeName;
-                Node gallery = destination.getNodeModel().getNode();
+                Node gallery = destination.getChainedModel().getObject();
                 if (gallery.hasNode(name)) {
                     name = addOrIncrementNodeNameSuffixForImage(name);
                     createNewNodeNameForImage(name);
@@ -306,31 +311,32 @@
 
             @Override
             protected String execute(Workflow wf) throws Exception {
-                JcrNodeModel folderModel = new JcrNodeModel("/");
-                if (destination != null) {
-                    folderModel = destination.getNodeModel();
-                }
-                StringCodec codec = getNodeNameCodec();
+                final Node folder = destination != null ?
+                        destination.getChainedModel().getObject() : UserSession.get().getJcrSession().getRootNode();
+
+                final String locale = CodecUtils.getLocaleFromDocumentOrFolder(getModel().getNode(), folder);
+                final StringCodec codec = CodecUtils.getNodeNameCodec(getPluginContext(), locale);
                 String nodeName = codec.encode(name);
 
                 DefaultWorkflow workflow = (DefaultWorkflow) wf;
-                workflow.copy(new Document(folderModel.getNode()), nodeName);
-                JcrNodeModel copyMode = new JcrNodeModel(folderModel.getItemModel().getPath() + "/" + nodeName);
-                HippoNode node = (HippoNode) copyMode.getNode().getNode(nodeName);
+                workflow.copy(new Document(folder), nodeName);
 
+                JcrNodeModel copyModel = new JcrNodeModel(folder.getPath() + "/" + nodeName);
+                HippoNode node = (HippoNode) copyModel.getNode().getNode(nodeName);
+
                 String localName = getLocalizeCodec().encode(name);
                 if (!node.getLocalizedName().equals(localName)) {
                     WorkflowManager manager = UserSession.get().getWorkflowManager();
                     DefaultWorkflow defaultWorkflow = (DefaultWorkflow) manager.getWorkflow("core", node);
                     defaultWorkflow.localizeName(localName);
                 }
-                browseTo(copyMode);
+                browseTo(copyModel);
                 return null;
             }
         });
 
         add(moveAction = new StdWorkflow("move", new StringResourceModel("move-label", this, null), context, getModel()) {
-            public NodeModelWrapper destination = null;
+            public NodeModelWrapper<Node> destination = null;
 
             @Override
             public String getSubMenu() {
@@ -344,7 +350,7 @@
 
             @Override
             protected Dialog createRequestDialog() {
-                destination = new NodeModelWrapper(getFolder()) {
+                destination = new NodeModelWrapper<Node>(getFolder()) {
                 };
                 return new DestinationDialog(new StringResourceModel("move-title",
                         DefaultWorkflowPlugin.this, null), null, null, destination, context, config) {
@@ -357,15 +363,54 @@
 
             @Override
             protected String execute(Workflow wf) throws Exception {
-                JcrNodeModel folderModel = new JcrNodeModel("/");
-                if (destination != null) {
-                    folderModel = destination.getNodeModel();
+
+                final Node src = getModel().getNode();
+                final Node dest = destination != null ?
+                        destination.getChainedModel().getObject() : UserSession.get().getJcrSession().getRootNode();
+
+                final String srcLocale = CodecUtils.getLocaleFromNodeAndAncestors(src);
+                final String destLocale = CodecUtils.getLocaleFromNodeAndAncestors(dest);
+
+                StringCodec codec = null;
+                if (srcLocale == null) {
+                    if (destLocale != null) {
+                        codec = CodecUtils.getNodeNameCodec(getPluginContext(), destLocale);
                 }
-                String nodeName = getModel().getNode().getName();
+                } else if (!srcLocale.equals(destLocale)) {
+                    codec = CodecUtils.getNodeNameCodec(getPluginContext(), destLocale);
+                }
+
+                String nodeName;
+                if (codec != null) {
+                    // we are moving between locales so re-encode the display name
+                    nodeName = codec.encode(getDisplayOrNodeName(src));
+                } else {
+                    // use original node name
+                    nodeName = src.getName();
+                }
+
                 DefaultWorkflow workflow = (DefaultWorkflow) wf;
-                workflow.move(new Document(folderModel.getNode()), nodeName);
+                workflow.move(new Document(dest), nodeName);
                 return null;
             }
+
+            private String getDisplayOrNodeName(final Node node) throws RepositoryException {
+                Node handle = node;
+                if (!node.isNodeType(HippoNodeType.NT_HANDLE)) {
+                    Node parent = node.getParent();
+                    if (parent != null && parent.isNodeType(HippoNodeType.NT_HANDLE)) {
+                        handle = parent;
+                    }
+                }
+
+                if (handle.isNodeType(HippoNodeType.NT_TRANSLATED) && handle.hasNode(HippoNodeType.NT_TRANSLATION)) {
+                    // use the first translation node message
+                    Node translationNode = handle.getNode(HippoNodeType.NT_TRANSLATION);
+                    return translationNode.getProperty(HippoNodeType.HIPPO_MESSAGE).getString();
+                } else {
+                    return node.getName();
+                }
+            }
         });
 
         add(deleteAction = new StdWorkflow("delete",
@@ -458,24 +503,19 @@
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
-    protected StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
+    protected StringCodec getNodeNameCodec(final Node node) {
+        return CodecUtils.getNodeNameCodec(getPluginContext(), node);
     }
 
     private void browseTo(JcrNodeModel nodeModel) throws RepositoryException {
         //refresh session before IBrowseService.browse is called
         obtainUserSession().getJcrSession().refresh(false);
 
-        IBrowseService service = getPluginContext().getService(getPluginConfig().getString(IBrowseService.BROWSER_ID),
+        @SuppressWarnings("unchecked")
+        IBrowseService<IModel<Node>> service = getPluginContext().getService(getPluginConfig().getString(IBrowseService.BROWSER_ID),
                 IBrowseService.class);
         if (service != null) {
             service.browse(nodeModel);
@@ -489,7 +529,7 @@
             return (new NodeTranslator(new JcrNodeModel(getModel().getNode()))).getNodeName();
         } catch (RepositoryException ex) {
             try {
-                return new Model<String>(getModel().getNode().getName());
+                return new Model<>(getModel().getNode().getName());
             } catch (RepositoryException e) {
                 return new StringResourceModel("unknown", this, null);
             }
@@ -513,12 +553,8 @@
                 Workflow workflow = manager.getWorkflow(workflowDescriptor);
                 info = workflow.hints();
             }
-        } catch (RepositoryException ex) {
+        } catch (RepositoryException | WorkflowException | RemoteException ex) {
             log.error(ex.getMessage());
-        } catch (RemoteException e) {
-            log.error(e.getMessage());
-        } catch (WorkflowException e) {
-            log.error(e.getMessage());
         }
         return info;
     }
@@ -536,31 +572,41 @@
         whereUsedAction.setVisible(!Boolean.FALSE.equals(workflowHints.get("status")));
     }
 
-    public class RenameDocumentDialog extends AbstractWorkflowDialog {
-        private IModel title;
+    public class RenameDocumentDialog extends AbstractWorkflowDialog<WorkflowDescriptor> {
+        private IModel<String> title;
         private TextField nameComponent;
         private TextField uriComponent;
         private boolean uriModified;
 
-        public RenameDocumentDialog(StdWorkflow action, IModel title) {
+        public RenameDocumentDialog(StdWorkflow action, IModel<String> title) {
             super(DefaultWorkflowPlugin.this.getModel(), action);
             this.title = title;
 
-            final PropertyModel<String> nameModel = new PropertyModel<String>(action, "targetName");
-            final PropertyModel<String> uriModel = new PropertyModel<String>(action, "uriName");
+            String locale = null;
+            try {
+                locale = CodecUtils.getLocaleFromNodeAndAncestors(DefaultWorkflowPlugin.this.getModel().getNode());
+            } catch (RepositoryException e) {
+                //ignore
+            }
 
+            final IModel<StringCodec> codecModel = CodecUtils.getNodeNameCodecModel(getPluginContext(), locale);
+
+            final PropertyModel<String> nameModel = new PropertyModel<>(action, "targetName");
+            final PropertyModel<String> uriModel = new PropertyModel<>(action, "uriName");
+
             String s1 = nameModel.getObject();
             String s2 = uriModel.getObject();
             uriModified = !s1.equals(s2);
 
-            nameComponent = new TextField<String>("name", nameModel);
+            nameComponent = new TextField<>("name", nameModel);
             nameComponent.setRequired(true);
             nameComponent.setLabel(new StringResourceModel("name-label", DefaultWorkflowPlugin.this, null));
             nameComponent.add(new OnChangeAjaxBehavior() {
                 @Override
                 protected void onUpdate(AjaxRequestTarget target) {
                     if (!uriModified) {
-                        uriModel.setObject(getNodeNameCodec().encode(nameModel.getObject()));
+                        String uri = codecModel.getObject().encode(nameModel.getObject());
+                        uriModel.setObject(uri);
                         target.add(uriComponent);
                     }
                 }
@@ -595,8 +641,10 @@
                 public void onClick(AjaxRequestTarget target) {
                     uriModified = !uriModified;
                     if (!uriModified) {
-                        uriModel.setObject(Strings.isEmpty(nameModel.getObject()) ? "" : getNodeNameCodec().encode(
-                                nameModel.getObject()));
+                        StringCodec codec = codecModel.getObject();
+                        String uri = Strings.isEmpty(nameModel.getObject()) ? "" : codec.encode(nameModel.getObject());
+                        uriModel.setObject(uri);
+                        uriComponent.modelChanged();
                     } else {
                         target.focusComponent(uriComponent);
                     }
Index: builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/FolderShortcutPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/FolderShortcutPlugin.java	(revision 48312)
+++ builtin/src/main/java/org/hippoecm/frontend/plugins/standardworkflow/FolderShortcutPlugin.java	(revision )
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2008-2013 Hippo B.V. (http://www.onehippo.com)
+ *  Copyright 2008-2015 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.
@@ -56,17 +56,16 @@
 import org.hippoecm.frontend.service.IBrowseService;
 import org.hippoecm.frontend.service.IEditor;
 import org.hippoecm.frontend.service.IEditorManager;
-import org.hippoecm.frontend.service.ISettingsService;
 import org.hippoecm.frontend.service.ServiceException;
 import org.hippoecm.frontend.service.render.RenderPlugin;
 import org.hippoecm.frontend.session.UserSession;
 import org.hippoecm.frontend.translation.ILocaleProvider;
+import org.hippoecm.frontend.util.CodecUtils;
 import org.hippoecm.repository.api.Document;
 import org.hippoecm.repository.api.HippoNodeType;
 import org.hippoecm.repository.api.HippoWorkspace;
 import org.hippoecm.repository.api.MappingException;
 import org.hippoecm.repository.api.StringCodec;
-import org.hippoecm.repository.api.StringCodecFactory;
 import org.hippoecm.repository.api.Workflow;
 import org.hippoecm.repository.api.WorkflowDescriptor;
 import org.hippoecm.repository.api.WorkflowException;
@@ -183,14 +182,8 @@
                                     editorMgr.openEditor(editNodeModel);
                                 }
                             }
-                        } catch (WorkflowException ex) {
+                        } catch (WorkflowException | ServiceException | RepositoryException | RemoteException ex) {
                             log.error("Cannot auto-edit document", ex);
-                        } catch (RemoteException ex) {
-                            log.error("Cannot auto-edit document", ex);
-                        } catch (RepositoryException ex) {
-                            log.error("Cannot auto-edit document", ex);
-                        } catch (ServiceException ex) {
-                            log.error("Cannot auto-edit document", ex);
                         }
                     }
                 }
@@ -201,26 +194,16 @@
     }
 
     protected StringCodec getLocalizeCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.display");
+        return CodecUtils.getDisplayNameCodec(getPluginContext());
     }
 
-    protected StringCodec getNodeNameCodec() {
-        ISettingsService settingsService = getPluginContext().getService(ISettingsService.SERVICE_ID,
-                ISettingsService.class);
-        StringCodecFactory stringCodecFactory = settingsService.getStringCodecFactory();
-        return stringCodecFactory.getStringCodec("encoding.node");
-    }
-
     protected ILocaleProvider getLocaleProvider() {
         return getPluginContext().getService(
                 getPluginConfig().getString(ILocaleProvider.SERVICE_ID, ILocaleProvider.class.getName()),
                 ILocaleProvider.class);
     }
 
-    public class Dialog extends AbstractDialog {
+    public class Dialog extends AbstractDialog<WorkflowDescriptor> {
         private static final long serialVersionUID = 1L;
 
         private String templateCategory = null;
@@ -231,8 +214,8 @@
         private final IServiceReference<IEditorManager> editServiceRef;
         private Map<String, Set<String>> templates;
 
-        private final DropDownChoice prototypeChoice;
-        private final DropDownChoice templateChoice;
+        private final DropDownChoice<String> prototypeChoice;
+        private final DropDownChoice<String> templateChoice;
 
         private String optionSelectOnly = null;
         private boolean optionSelectFirst = false;
@@ -268,7 +251,8 @@
                 folderWorkflowDescriptorModel = new WorkflowDescriptorModel(workflowCategory, folder);
                 Workflow workflow = folderWorkflowDescriptorModel.getWorkflow();
                 if (workflow instanceof FolderWorkflow) {
-                    templates = ((FolderWorkflow) workflow).list();
+                    FolderWorkflow folderWorkflow = (FolderWorkflow) workflow;
+                    templates = (Map<String, Set<String>>) folderWorkflow.hints().get("prototypes");
                 } else {
                     folder = null;
                     templates = Collections.emptyMap();
@@ -276,13 +260,13 @@
 
                 if (optionSelectFirst) {
                     if (optionSelectOnly != null) {
-                        Map<String, Set<String>> newTemplates = new TreeMap<String, Set<String>>();
+                        Map<String, Set<String>> newTemplates = new TreeMap<>();
                         if (templates.containsKey(optionSelectOnly)) {
                             newTemplates.put(optionSelectOnly, templates.get(optionSelectOnly));
                         }
                         templates = newTemplates;
                     } else {
-                        Map<String, Set<String>> newTemplates = new TreeMap<String, Set<String>>();
+                        Map<String, Set<String>> newTemplates = new TreeMap<>();
                         if (templates.size() > 0) {
                             Map.Entry<String, Set<String>> firstEntry = templates.entrySet().iterator().next();
                             newTemplates.put(firstEntry.getKey(), firstEntry.getValue());
@@ -290,7 +274,7 @@
                         templates = newTemplates;
                     }
                 } else if (optionSelectOnly != null) {
-                    Map<String, Set<String>> newTemplates = new TreeMap<String, Set<String>>();
+                    Map<String, Set<String>> newTemplates = new TreeMap<>();
                     if (templates.containsKey(optionSelectOnly)) {
                         newTemplates.put(optionSelectOnly, templates.get(optionSelectOnly));
                     }
@@ -310,22 +294,23 @@
                 folder = null;
             }
 
-            add(new Label("message", new Model("")));
+            add(new Label("message", Model.of("")));
 
-            add(nameUriContainer = new NameUriField("name-url", new LoadableDetachableModel<StringCodec>() {
-                private static final long serialVersionUID = 1L;
-
+            final IModel<StringCodec> codecModel = new LoadableDetachableModel<StringCodec>() {
                 @Override
                 protected StringCodec load() {
-                    return getNodeNameCodec();
+                    //language value can change between load() calls
+                    return CodecUtils.getNodeNameCodec(getPluginContext(), language);
                 }
-            }));
+            };
 
-            List<String> emptyList = new LinkedList<String>();
+            add(nameUriContainer = new NameUriField("name-url", codecModel));
+
+            List<String> emptyList = new LinkedList<>();
             emptyList.add("");
 
             prototypeContainer = new WebMarkupContainer("prototype");
-            prototypeContainer.add(prototypeChoice = new DropDownChoice("select", new PropertyModel(this, "prototype"),
+            prototypeContainer.add(prototypeChoice = new DropDownChoice<>("select", new PropertyModel<String>(this, "prototype"),
                     emptyList));
             prototypeChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
                 private static final long serialVersionUID = 1L;
@@ -341,7 +326,7 @@
             add(prototypeContainer);
 
             templateContainer = new WebMarkupContainer("template");
-            templateContainer.add(templateChoice = new DropDownChoice<String>("select", new PropertyModel<String>(this,
+            templateContainer.add(templateChoice = new DropDownChoice<>("select", new PropertyModel<String>(this,
                     "templateCategory"), emptyList, new IChoiceRenderer<String>() {
                 private static final long serialVersionUID = 1L;
 
@@ -360,6 +345,10 @@
                 protected void onUpdate(AjaxRequestTarget target) {
                     prototype = null;
                     evaluateChoices();
+                    // Detach the codec model to load the correct codec for the selected template
+                    codecModel.detach();
+                    // Re-encode the URI value
+                    nameUriContainer.encodeUri();
                 }
             });
             templateChoice.setNullValid(false);
@@ -368,18 +357,21 @@
             templateContainer.add(new Label("typelabel", new StringResourceModel("document-type", this, null)));
             add(templateContainer);
 
-            languageContainer = new LanguageField("language", new PropertyModel<String>(this, "language"), getLocaleProvider());
+            languageContainer = new LanguageField("language", new PropertyModel<String>(this, "language"), getLocaleProvider()) {
+                @Override
+                protected void onSelectionChanged() {
+                    // Detach the codec model to load the correct codec for the selected language
+                    codecModel.detach();
+                    // Re-encode the URI value
+                    nameUriContainer.encodeUri();
+                }
+            };
             add(languageContainer);
 
-            setOkEnabled(false);
-
-            if (folder != null && folderWorkflowDescriptorModel != null) {
-                setModel(folderWorkflowDescriptorModel);
+            setModel(folderWorkflowDescriptorModel);
-                setOkEnabled(true);
-            } else {
-                setModel(null);
-            }
-            if (templates.keySet().size() >= 1) {
+            setOkEnabled(folder != null);
+
+            if (templates != null && templates.keySet().size() >= 1) {
                 // pre-select the first item in the template category
                 templateCategory = templates.keySet().iterator().next();
             }
@@ -387,18 +379,18 @@
         }
 
         private void evaluateChoices() {
-            if (templates.keySet().size() == 1) {
-                templateChoice.setChoices(new LinkedList<String>(templates.keySet()));
+            if (templates == null || templates.keySet().size() == 0) {
                 templateContainer.setVisible(false);
+            } else if (templates.keySet().size() == 1) {
+                templateChoice.setChoices(new LinkedList<>(templates.keySet()));
+                templateContainer.setVisible(false);
             } else if (templates.keySet().size() > 1) {
-                templateChoice.setChoices(new LinkedList<String>(templates.keySet()));
+                templateChoice.setChoices(new LinkedList<>(templates.keySet()));
                 templateContainer.setVisible(true);
-            } else {
-                templateContainer.setVisible(false);
             }
             boolean languageVisible = false;
             if (templateCategory != null) {
-                final List<String> prototypesList = new LinkedList<String>(templates.get(templateCategory));
+                final List<String> prototypesList = new LinkedList<>(templates.get(templateCategory));
                 prototypeChoice.setChoices(prototypesList);
                 prototypeChoice.setChoiceRenderer(new TypeChoiceRenderer(this));
                 if (prototypesList.size() > 1) {
@@ -444,9 +436,15 @@
                     target.add(this);
                 }
             }
+
+            // By resetting the language the URI is re-encoded using the correct StringCodec
+            // when switching between translated and non-translated root folders
+            if (!languageVisible) {
+                language = null;
         }
+     }
 
-        public IModel getTitle() {
+        public IModel<String> getTitle() {
             return new StringResourceModel("new-document-label", this, null);
         }
 
@@ -462,8 +460,8 @@
                 if (model != null && model instanceof WorkflowDescriptorModel) {
                     Session jcrSession = UserSession.get().getJcrSession();
                     WorkflowManager manager = ((HippoWorkspace) (jcrSession.getWorkspace())).getWorkflowManager();
-                    FolderWorkflow workflow = (FolderWorkflow) manager
-                            .getWorkflow((WorkflowDescriptor) ((WorkflowDescriptorModel) model).getObject());
+                    FolderWorkflow workflow = (FolderWorkflow) manager.getWorkflow(((WorkflowDescriptorModel) model)
+                            .getObject());
                     if (prototype == null) {
                         error("You need to select a type");
                         return;
@@ -476,9 +474,9 @@
                         }
 
                         String localName = getLocalizeCodec().encode(name);
-                        String nodeName = getNodeNameCodec().encode(url);
+                        String nodeName = CodecUtils.getNodeNameCodec(getPluginContext(), language).encode(url);
 
-                        TreeMap<String, String> arguments = new TreeMap<String, String>();
+                        TreeMap<String, String> arguments = new TreeMap<>();
                         arguments.put("name", nodeName);
                         if (language != null) {
                             arguments.put("hippotranslation:locale", language);
