Index: addon/xinha/webResources/xinha/plugins/InsertImage/InsertImage.js
===================================================================
--- addon/xinha/webResources/xinha/plugins/InsertImage/InsertImage.js	(revision 21294)
+++ addon/xinha/webResources/xinha/plugins/InsertImage/InsertImage.js	(working copy)
@@ -20,6 +20,7 @@
 
     this.imgRE = new RegExp('<img[^>]+>', 'gi');
     this.srcRE = new RegExp('src="[^"]+"', 'i');
+    this.facetselectRE = new RegExp('facetselect="([^"]+)"', 'i');
     this.noReplacePrefixes = ['http:', 'https:', '/'];
 }
 
@@ -79,6 +80,7 @@
             self.editor.updateToolbar();
         } else {
             self.apply();
+            img = self.image;
         }
         self.editor.plugins.AutoSave.instance.save();
     };
@@ -102,15 +104,26 @@
  */
 InsertImage.prototype.inwardHtml = function(html) {
     var _this = this;
-    var prefix = this.getPrefix();    
+    var prefix = this.getPrefix();
+    var isPortletContext = this.isPortletContext();
     html = html.replace(this.imgRE, function(m) {
-        m = m.replace(_this.srcRE, function(n) {
-            var url = n.substring(5, n.length - 1);
-            if(_this.shouldPrefix(url)) {
-                return 'src="' + prefix + url + '"';
-            }
-            return n;
-        });
+        if (_this.facetselectRE.test(m)) {
+            var facetselect = RegExp.$1;
+            m = m.replace(_this.srcRE, function(n) {
+                if (!isPortletContext)
+                    return 'src="' + prefix + facetselect + '"';
+                else
+                    return 'src="' + prefix + "?_path=" + facetselect + '"';
+            });
+        } else {
+            m = m.replace(_this.srcRE, function(n) {
+                var url = n.substring(5, n.length - 1);
+                if (_this.shouldPrefix(url)) {
+                    return 'src="' + prefix + url + '"';
+                }
+                return n;
+            });
+        }
         return m;
     });
     return html;
@@ -123,14 +136,22 @@
     var _this = this;
     var prefix = this.getPrefix();
     html = html.replace(this.imgRE, function(m) {
-        m = m.replace(_this.srcRE, function(n) {
-            var idx = n.indexOf(prefix);
-            if (idx > -1) {
-                return 'src="' + n.substr(prefix.length + idx);
-            }
-            return n;
-        });
-        return m;
+        if (_this.facetselectRE.test(m)) {
+            var facetselect = RegExp.$1;
+            m = m.replace(_this.srcRE, function(n) {
+                return 'src="' + facetselect + '"';
+            });
+            return m;
+        } else {
+            m = m.replace(_this.srcRE, function(n) {
+                var idx = n.indexOf(prefix);
+                if (idx > -1) {
+                    return 'src="' + n.substr(prefix.length + idx);
+                }
+                return n;
+            });
+            return m;
+        }
     });
     return html;
 }
@@ -153,6 +174,10 @@
     return true;
 }
 
+InsertImage.prototype.isPortletContext = function() {
+    return (this.editor.config.isPortletContext);
+}
+
 //Workaround for method not found error
 InsertImage.prototype.stripBaseURL = function(url) {
     return url;
Index: addon/xinha/src/main/webapp/xinha/modules/InsertImage/pluginMethods.js
===================================================================
--- addon/xinha/src/main/webapp/xinha/modules/InsertImage/pluginMethods.js	(revision 1137)
+++ addon/xinha/src/main/webapp/xinha/modules/InsertImage/pluginMethods.js	(working copy)
@@ -29,6 +29,7 @@
     outparam =
     {
       f_url    : this.stripBaseURL(image.getAttribute('src',2)), // the second parameter makes IE return the value as it is set, as opposed to an "interpolated" (as MSDN calls it) value
+      f_facetselect : getSpecifiedAttribute(image,'facetselect'),
       f_alt    : image.alt,
       f_border : image.border,
       f_align  : image.align,
@@ -43,6 +44,7 @@
     outparam =
     {
       f_url    : '',
+      f_facetselect  : '',
       f_alt    : '',
       f_border : '',
       f_align  : '',
@@ -93,6 +95,7 @@
         img = range.startContainer.firstChild;
       }
     }
+    this.image = img;
   }
   else
   {
@@ -104,6 +107,12 @@
     var value = param[field];
     switch (field)
     {
+      case "f_facetselect":
+      if (value)
+      img.setAttribute("facetselect",value);
+      else
+      img.removeAttribute("facetselect");
+      break;
       case "f_alt":
       if (value)
       img.alt = value;
@@ -148,5 +157,4 @@
       break;
     }
   }
-
 };
Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/ImageItemFactory.java
===================================================================
--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/ImageItemFactory.java	(revision 21294)
+++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/ImageItemFactory.java	(working copy)
@@ -162,12 +162,35 @@
             return facetName;
         }
         
-        public String getUrl() {
-            String url = "binaries" + parentPath + "/" + facetName;
+        public String getFacetSelectPath() {
             if (selectedResourceDefinition != null) {
-                return XinhaUtil.encode(url + "/{_document}/" + selectedResourceDefinition);
+                return facetName + "/{_document}/" + selectedResourceDefinition;
+            } else {
+                return facetName;
+            }
+        }
+        
+        public String getUrl() {
+            String url = null;
+            String parentUrl = "binaries" + parentPath + "/";
+
+            if (!XinhaUtil.isPortletContext()) {
+                if (selectedResourceDefinition != null) {
+                    url = XinhaUtil.encode(parentUrl + facetName + "/{_document}/" + selectedResourceDefinition);
+                } else {
+                    url = XinhaUtil.encode(parentUrl + facetName);
+                }
+            } else {
+                parentUrl = XinhaUtil.encodeResourceURL(XinhaUtil.encode(parentUrl));
+                url = 
+                    new StringBuilder(80).append(parentUrl)
+                    .append(parentUrl.indexOf('?') == -1 ? '?' : '&')
+                    .append("_path=")
+                    .append(getFacetSelectPath())
+                    .toString();
             }
-            return XinhaUtil.encode(url);
+            
+            return url;
         }
 
         public boolean isValid() {
Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImageService.java
===================================================================
--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImageService.java	(revision 21294)
+++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImageService.java	(working copy)
@@ -52,9 +52,12 @@
         //TODO: fix drag-drop replacing
         ImageItem item = createImageItem(model);
         if (attachImageItem(item)) {
-            StringBuilder sb = new StringBuilder();
-            sb.append("xinha_editors.").append(getXinhaName()).append(".plugins.InsertImage.instance.insertImage(")
-                    .append('{').append(XinhaImage.URL).append(": '").append(item.getUrl()).append("'}, false)");
+            StringBuilder sb = new StringBuilder(80);
+            sb.append("xinha_editors.").append(getXinhaName()).append(".plugins.InsertImage.instance.insertImage(");
+            sb.append("{ ");
+            sb.append(XinhaImage.URL).append(": '").append(item.getUrl()).append("'");
+            sb.append(", ").append(XinhaImage.FACET_SELECT).append(": '").append(item.getFacetSelectPath()).append("'");
+            sb.append(" }, false)");
             return sb.toString();
         }
         return null;
@@ -70,10 +73,13 @@
                 if (isAttacheable()) {
                     if (isReplacing()) {
                         ImageItem remove = createImageItem(getInitialValues());
-                        detachImageItem(remove);
+                        if (remove != null) {
+                            detachImageItem(remove);
+                        }
                     }
                     ImageItem item = createImageItem(getNodeModel());
                     if (attachImageItem(item)) {
+                        setFacetSelectPath(item.getFacetSelectPath());
                         setUrl(item.getUrl());
                     }
                 }
@@ -82,6 +88,7 @@
             public void delete() {
                 ImageItem item = createImageItem(this);
                 detachImageItem(item);
+                setFacetSelectPath("");
                 setUrl("");
             }
 
Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImage.java
===================================================================
--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImage.java	(revision 21294)
+++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImage.java	(working copy)
@@ -22,6 +22,7 @@
 import javax.jcr.RepositoryException;
 
 import org.apache.wicket.Session;
+import org.apache.wicket.util.string.Strings;
 import org.hippoecm.frontend.model.JcrNodeModel;
 import org.hippoecm.frontend.plugins.xinha.XinhaUtil;
 import org.hippoecm.frontend.plugins.xinha.dialog.DocumentLink;
@@ -41,6 +42,7 @@
 
     public static final String BASE = "f_base";
     public static final String URL = "f_url";
+    public static final String FACET_SELECT = "f_facetselect";
     public static final String ALT = "f_alt";
     public static final String BORDER = "f_border";
     public static final String ALIGN = "f_align";
@@ -61,25 +63,38 @@
         return (String) get(URL);
     }
     
+    public void setFacetSelectPath(String facetSelectPath) {
+        put(FACET_SELECT, facetSelectPath);
+    }
+    
+    public String getFacetSelectPath() {
+        return (String) get(FACET_SELECT);
+    }
+    
     @Override
     protected JcrNodeModel createInitialModel(JcrNodeModel parentModel) {
+        String facetSelectPath = getFacetSelectPath();
         String url = getUrl();
-        if (url != null && url.startsWith(BINARIES_PREFIX)) {
-
-            // find the nodename of the facetselect
-            String path = XinhaUtil.decode(url.substring(BINARIES_PREFIX.length()));
+        String path = null;
+        
+        try {
+            if (!Strings.isEmpty(facetSelectPath)) {
+                path = XinhaUtil.decode(parentModel.getNode().getPath() + "/" + facetSelectPath);
+            } else if (url != null && url.startsWith(BINARIES_PREFIX)) {
+                // find the nodename of the facetselect
+                path = XinhaUtil.decode(url.substring(BINARIES_PREFIX.length()));
+            }
+            
             UserSession session = (UserSession) Session.get();
-            try {
-                HippoNode node = (HippoNode) session.getJcrSession().getRootNode().getNode(path).getParent();
-                Node imageNode = node.getCanonicalNode();
-                if (imageNode != null) {
-                    return new JcrNodeModel(imageNode.getPath());
-                }
-            } catch (PathNotFoundException e) {
-                log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
-            } catch (RepositoryException e) {
-                log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
+            HippoNode node = (HippoNode) session.getJcrSession().getRootNode().getNode(path).getParent();
+            Node imageNode = node.getCanonicalNode();
+            if (imageNode != null) {
+                return new JcrNodeModel(imageNode.getPath());
             }
+        } catch (PathNotFoundException e) {
+            log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
+        } catch (RepositoryException e) {
+            log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
         }
         return null;
     }
Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/AbstractXinhaPlugin.java
===================================================================
--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/AbstractXinhaPlugin.java	(revision 21294)
+++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/AbstractXinhaPlugin.java	(working copy)
@@ -124,7 +124,8 @@
             add(HeaderContributor.forJavaScript(XINHA_MODAL_JS));
 
             String nodePath = getValueModel().getJcrPropertymodel().getItemModel().getParentModel().getPath();
-            configuration.addProperty("prefix", XinhaUtil.encode(BINARIES_PREFIX + nodePath));
+            configuration.addProperty("prefix", XinhaUtil.encodeResourceURL(XinhaUtil.encode(BINARIES_PREFIX + nodePath + "/")));
+            configuration.addProperty("isPortletContext", Boolean.toString(XinhaUtil.isPortletContext()));
 
             JcrNodeModel nodeModel = new JcrNodeModel(nodePath);
             imageService = new XinhaImageService(nodeModel) {
@@ -196,9 +197,8 @@
                     String text = (String) getDefaultModelObject();
                     if (text != null) {
                         JcrPropertyValueModel propertyValueModel = getValueModel();
-                        String prefix = XinhaUtil.encode(BINARIES_PREFIX
-                                + propertyValueModel.getJcrPropertymodel().getItemModel().getParentModel().getPath())
-                                + "/";
+                        String prefix = XinhaUtil.encodeResourceURL(XinhaUtil.encode(BINARIES_PREFIX
+                                + propertyValueModel.getJcrPropertymodel().getItemModel().getParentModel().getPath()) + "/");
 
                         String processed = XinhaHtmlProcessor.prefixImageLinks(text, prefix);
                         processed = XinhaHtmlProcessor.decorateInternalLinks(processed, il);
Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaUtil.java
===================================================================
--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaUtil.java	(revision 21294)
+++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaUtil.java	(working copy)
@@ -16,8 +16,10 @@
 package org.hippoecm.frontend.plugins.xinha;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.wicket.RequestContext;
 import org.apache.wicket.protocol.http.WicketURLDecoder;
 import org.apache.wicket.protocol.http.WicketURLEncoder;
+import org.apache.wicket.protocol.http.portlet.PortletRequestContext;
 
 public class XinhaUtil {
     @SuppressWarnings("unused")
@@ -38,5 +40,27 @@
         }
         return StringUtils.join(elements, '/');
     }
-
+    
+    public static final String encodeResourceURL(String url) {
+        return encodeResourceURL(url, true);
+    }
+    
+    public static final String encodeResourceURL(String url, boolean useRelativeURL) {
+        // if it is in portlet environment, just wrap the url in portlet resource url.
+        RequestContext requestContext = RequestContext.get();
+        if (requestContext.isPortletRequest()) {
+            url = ((PortletRequestContext) requestContext).encodeResourceURL(url).toString();
+            if (useRelativeURL && (url.startsWith("http:") || url.startsWith("https:"))) {
+                int offset = url.indexOf('/', 8);
+                if (offset != -1) {
+                    url = url.substring(offset);
+                }
+            }
+        }
+        return url;
+    }
+    
+    public static final boolean isPortletContext() {
+        return RequestContext.get().isPortletRequest();
+    }
 }
Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaHtmlProcessor.java
===================================================================
--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaHtmlProcessor.java	(revision 21294)
+++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaHtmlProcessor.java	(working copy)
@@ -29,7 +29,8 @@
     private static Pattern LINK_AND_IMAGES_PATTERN = Pattern.compile("<(a|img)(\\s+)(.*?)(src|href)=\"(.*?)\"(.*?)>",
             Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
     private static Pattern IMG_PATTERN = Pattern.compile("<img[^>]+>", Pattern.CASE_INSENSITIVE);
-    private static Pattern SRC_PATTERN = Pattern.compile("src=\"[^\"]+\"", Pattern.CASE_INSENSITIVE);
+    private static Pattern SRC_PATTERN = Pattern.compile("src=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private static Pattern FACET_SELECT_PATTERN = Pattern.compile("facetselect=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
 
     private static Pattern LINK_PATTERN = Pattern.compile("<a[^>]+>", Pattern.CASE_INSENSITIVE);
     private static Pattern HREF_PATTERN = Pattern.compile("href=\"[^\"]+\"", Pattern.CASE_INSENSITIVE);
@@ -41,30 +42,43 @@
     public static String prefixImageLinks(String text, String prefix) {
         StringBuffer processed = new StringBuffer();
         Matcher m = IMG_PATTERN.matcher(text);
+        
         while (m.find()) {
             String img = m.group();
             StringBuffer newImg = new StringBuffer();
             Matcher s = SRC_PATTERN.matcher(img);
+            
             if (s.find()) {
                 String src = s.group();
-                // skip src=
-                String link = src.substring(4);
-                if (link.charAt(0) == '"') {
-                    link = link.substring(1);
-                }
-                if (link.charAt(link.length() - 1) == '"') {
-                    link = link.substring(0, link.length() - 1);
-                }
-                if (!link.startsWith("http:") && !link.startsWith("https:")) {
-                    s.appendReplacement(newImg, ("src=\"" + prefix + link + "\"").replace("\\", "\\\\").replace("$",
-                            "\\$"));
+                Matcher fs = FACET_SELECT_PATTERN.matcher(img);
+                
+                if (fs.find()) {
+                    String link = fs.group(1);
+                    
+                    if (!link.startsWith("http:") && !link.startsWith("https:")) {
+                        if (XinhaUtil.isPortletContext()) {
+                            s.appendReplacement(newImg, ("src=\"" + prefix + "?_path=" + link + "\"").replace("\\", "\\\\").replace("$", "\\$"));
+                        } else {
+                            s.appendReplacement(newImg, ("src=\"" + prefix + link + "\"").replace("\\", "\\\\").replace("$", "\\$"));
+                        }
+                    } else {
+                        s.appendReplacement(newImg, src.replace("\\", "\\\\").replace("$", "\\$"));
+                    }
                 } else {
-                    s.appendReplacement(newImg, src.replace("\\", "\\\\").replace("$", "\\$"));
+                    String link = s.group(1);
+                    
+                    if (!link.startsWith("http:") && !link.startsWith("https:")) {
+                        s.appendReplacement(newImg, ("src=\"" + prefix + link + "\"").replace("\\", "\\\\").replace("$", "\\$"));
+                    } else {
+                        s.appendReplacement(newImg, src.replace("\\", "\\\\").replace("$", "\\$"));
+                    }
                 }
             }
+            
             s.appendTail(newImg);
             m.appendReplacement(processed, newImg.toString().replace("\\", "\\\\").replace("$", "\\$"));
         }
+        
         m.appendTail(processed);
 
         return processed.toString();
Index: addon/xinha-frontend/src/main/resources/html-cleaner-service.xml
===================================================================
--- addon/xinha-frontend/src/main/resources/html-cleaner-service.xml	(revision 21294)
+++ addon/xinha-frontend/src/main/resources/html-cleaner-service.xml	(working copy)
@@ -312,6 +312,7 @@
           <sv:value>width</sv:value>
           <sv:value>height</sv:value>
           <sv:value>title</sv:value>
+          <sv:value>facetselect</sv:value>
         </sv:property>
       </sv:node>
 
Index: HREPTWO-3634.patch
===================================================================
--- HREPTWO-3634.patch	(revision 0)
+++ HREPTWO-3634.patch	(revision 0)
@@ -0,0 +1,477 @@
+Index: frontend/engine/src/main/java/org/hippoecm/frontend/Main.java
+===================================================================
+--- frontend/engine/src/main/java/org/hippoecm/frontend/Main.java	(revision 21294)
++++ frontend/engine/src/main/java/org/hippoecm/frontend/Main.java	(working copy)
+@@ -33,6 +33,8 @@
+ import javax.jcr.observation.EventListenerIterator;
+ import javax.servlet.ServletContext;
+ 
++import org.apache.commons.lang.ArrayUtils;
++import org.apache.commons.lang.StringUtils;
+ import org.apache.wicket.Application;
+ import org.apache.wicket.Component;
+ import org.apache.wicket.IRequestTarget;
+@@ -42,8 +44,6 @@
+ import org.apache.wicket.Session;
+ import org.apache.wicket.ajax.AjaxRequestTarget;
+ import org.apache.wicket.application.IClassResolver;
+-import org.apache.wicket.authorization.Action;
+-import org.apache.wicket.authorization.IAuthorizationStrategy;
+ import org.apache.wicket.protocol.http.HttpSessionStore;
+ import org.apache.wicket.protocol.http.WebApplication;
+ import org.apache.wicket.request.IRequestCycleProcessor;
+@@ -219,8 +219,15 @@
+         mount(new AbstractRequestTargetUrlCodingStrategy("binaries") {
+ 
+             public IRequestTarget decode(RequestParameters requestParameters) {
+-                String path = requestParameters.getPath().substring("binaries/".length());
+-                path = urlDecodePathComponent(path);
++                String pathInfo = StringUtils.removeEnd(requestParameters.getPath().substring("binaries/".length()), "/");
++                String pathInParams = StringUtils.removeStart(getRequestParameter(requestParameters, "_path", true), "/");
++                String path = null;
++                if (!StringUtils.isEmpty(pathInfo)) {
++                    path = StringUtils.join(new String [] { pathInfo, pathInParams }, '/');
++                } else {
++                    path = pathInParams;
++                }
++                path = urlDecodePathComponent(StringUtils.removeStart(path, "/"));
+                 // FIXME: workaround use a subsession because we can't refresh the session
+                 // the logout is actually performed by the JcrResourceRequestTarget
+                 UserSession session = (UserSession) Session.get();
+@@ -249,6 +256,25 @@
+             public boolean matches(IRequestTarget requestTarget) {
+                 return false;
+             }
++            
++            private String getRequestParameter(RequestParameters requestParameters, String paramName, boolean concatenateAll) {
++                String paramValue = null;
++                Object param = requestParameters.getParameters().get(paramName);
++                
++                if (param != null) {
++                    if (param.getClass().isArray() && ArrayUtils.getLength(param) > 0) {
++                        if (concatenateAll) {
++                            paramValue = StringUtils.join((String []) param);
++                        } else {
++                            paramValue = ((String []) param)[0];
++                        }
++                    } else {
++                        paramValue = param.toString();
++                    }
++                }
++                
++                return paramValue;
++            }
+         });
+ 
+         resourceSettings.setLocalizer(new StagedLocalizer());
+Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/ImageItemFactory.java
+===================================================================
+--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/ImageItemFactory.java	(revision 21294)
++++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/ImageItemFactory.java	(working copy)
+@@ -162,14 +162,37 @@
+             return facetName;
+         }
+         
+-        public String getUrl() {
+-            String url = "binaries" + parentPath + "/" + facetName;
++        public String getFacetSelectPath() {
+             if (selectedResourceDefinition != null) {
+-                return XinhaUtil.encode(url + "/{_document}/" + selectedResourceDefinition);
++                return facetName + "/{_document}/" + selectedResourceDefinition;
++            } else {
++                return facetName;
+             }
+-            return XinhaUtil.encode(url);
+         }
++        
++        public String getUrl() {
++            String url = null;
++            String parentUrl = "binaries" + parentPath + "/";
+ 
++            if (!XinhaUtil.isPortletContext()) {
++                if (selectedResourceDefinition != null) {
++                    url = XinhaUtil.encode(parentUrl + facetName + "/{_document}/" + selectedResourceDefinition);
++                } else {
++                    url = XinhaUtil.encode(parentUrl + facetName);
++                }
++            } else {
++                parentUrl = XinhaUtil.encodeResourceURL(XinhaUtil.encode(parentUrl));
++                url = 
++                    new StringBuilder(80).append(parentUrl)
++                    .append(parentUrl.indexOf('?') == -1 ? '?' : '&')
++                    .append("_path=")
++                    .append(getFacetSelectPath())
++                    .toString();
++            }
++            
++            return url;
++        }
++
+         public boolean isValid() {
+             return path != null && uuid != null
+                     && !(resourceDefinitions.size() > 1 && selectedResourceDefinition == null);
+Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImage.java
+===================================================================
+--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImage.java	(revision 21294)
++++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImage.java	(working copy)
+@@ -22,6 +22,7 @@
+ import javax.jcr.RepositoryException;
+ 
+ import org.apache.wicket.Session;
++import org.apache.wicket.util.string.Strings;
+ import org.hippoecm.frontend.model.JcrNodeModel;
+ import org.hippoecm.frontend.plugins.xinha.XinhaUtil;
+ import org.hippoecm.frontend.plugins.xinha.dialog.DocumentLink;
+@@ -41,6 +42,7 @@
+ 
+     public static final String BASE = "f_base";
+     public static final String URL = "f_url";
++    public static final String FACET_SELECT = "f_facetselect";
+     public static final String ALT = "f_alt";
+     public static final String BORDER = "f_border";
+     public static final String ALIGN = "f_align";
+@@ -61,25 +63,38 @@
+         return (String) get(URL);
+     }
+     
++    public void setFacetSelectPath(String facetSelectPath) {
++        put(FACET_SELECT, facetSelectPath);
++    }
++    
++    public String getFacetSelectPath() {
++        return (String) get(FACET_SELECT);
++    }
++    
+     @Override
+     protected JcrNodeModel createInitialModel(JcrNodeModel parentModel) {
++        String facetSelectPath = getFacetSelectPath();
+         String url = getUrl();
+-        if (url != null && url.startsWith(BINARIES_PREFIX)) {
+-
+-            // find the nodename of the facetselect
+-            String path = XinhaUtil.decode(url.substring(BINARIES_PREFIX.length()));
++        String path = null;
++        
++        try {
++            if (!Strings.isEmpty(facetSelectPath)) {
++                path = XinhaUtil.decode(parentModel.getNode().getPath() + "/" + facetSelectPath);
++            } else if (url != null && url.startsWith(BINARIES_PREFIX)) {
++                // find the nodename of the facetselect
++                path = XinhaUtil.decode(url.substring(BINARIES_PREFIX.length()));
++            }
++            
+             UserSession session = (UserSession) Session.get();
+-            try {
+-                HippoNode node = (HippoNode) session.getJcrSession().getRootNode().getNode(path).getParent();
+-                Node imageNode = node.getCanonicalNode();
+-                if (imageNode != null) {
+-                    return new JcrNodeModel(imageNode.getPath());
+-                }
+-            } catch (PathNotFoundException e) {
+-                log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
+-            } catch (RepositoryException e) {
+-                log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
++            HippoNode node = (HippoNode) session.getJcrSession().getRootNode().getNode(path).getParent();
++            Node imageNode = node.getCanonicalNode();
++            if (imageNode != null) {
++                return new JcrNodeModel(imageNode.getPath());
+             }
++        } catch (PathNotFoundException e) {
++            log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
++        } catch (RepositoryException e) {
++            log.error("Error retrieving canonical node for imageNode[" + path + "]", e);
+         }
+         return null;
+     }
+Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImageService.java
+===================================================================
+--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImageService.java	(revision 21294)
++++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/services/images/XinhaImageService.java	(working copy)
+@@ -52,9 +52,12 @@
+         //TODO: fix drag-drop replacing
+         ImageItem item = createImageItem(model);
+         if (attachImageItem(item)) {
+-            StringBuilder sb = new StringBuilder();
+-            sb.append("xinha_editors.").append(getXinhaName()).append(".plugins.InsertImage.instance.insertImage(")
+-                    .append('{').append(XinhaImage.URL).append(": '").append(item.getUrl()).append("'}, false)");
++            StringBuilder sb = new StringBuilder(80);
++            sb.append("xinha_editors.").append(getXinhaName()).append(".plugins.InsertImage.instance.insertImage(");
++            sb.append("{ ");
++            sb.append(XinhaImage.URL).append(": '").append(item.getUrl()).append("'");
++            sb.append(", ").append(XinhaImage.FACET_SELECT).append(": '").append(item.getFacetSelectPath()).append("'");
++            sb.append(" }, false)");
+             return sb.toString();
+         }
+         return null;
+@@ -70,10 +73,13 @@
+                 if (isAttacheable()) {
+                     if (isReplacing()) {
+                         ImageItem remove = createImageItem(getInitialValues());
+-                        detachImageItem(remove);
++                        if (remove != null) {
++                            detachImageItem(remove);
++                        }
+                     }
+                     ImageItem item = createImageItem(getNodeModel());
+                     if (attachImageItem(item)) {
++                        setFacetSelectPath(item.getFacetSelectPath());
+                         setUrl(item.getUrl());
+                     }
+                 }
+@@ -82,6 +88,7 @@
+             public void delete() {
+                 ImageItem item = createImageItem(this);
+                 detachImageItem(item);
++                setFacetSelectPath("");
+                 setUrl("");
+             }
+ 
+Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaUtil.java
+===================================================================
+--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaUtil.java	(revision 21294)
++++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaUtil.java	(working copy)
+@@ -16,8 +16,10 @@
+ package org.hippoecm.frontend.plugins.xinha;
+ 
+ import org.apache.commons.lang.StringUtils;
++import org.apache.wicket.RequestContext;
+ import org.apache.wicket.protocol.http.WicketURLDecoder;
+ import org.apache.wicket.protocol.http.WicketURLEncoder;
++import org.apache.wicket.protocol.http.portlet.PortletRequestContext;
+ 
+ public class XinhaUtil {
+     @SuppressWarnings("unused")
+@@ -38,5 +40,27 @@
+         }
+         return StringUtils.join(elements, '/');
+     }
+-
++    
++    public static final String encodeResourceURL(String url) {
++        return encodeResourceURL(url, true);
++    }
++    
++    public static final String encodeResourceURL(String url, boolean useRelativeURL) {
++        // if it is in portlet environment, just wrap the url in portlet resource url.
++        RequestContext requestContext = RequestContext.get();
++        if (requestContext.isPortletRequest()) {
++            url = ((PortletRequestContext) requestContext).encodeResourceURL(url).toString();
++            if (useRelativeURL && (url.startsWith("http:") || url.startsWith("https:"))) {
++                int offset = url.indexOf('/', 8);
++                if (offset != -1) {
++                    url = url.substring(offset);
++                }
++            }
++        }
++        return url;
++    }
++    
++    public static final boolean isPortletContext() {
++        return RequestContext.get().isPortletRequest();
++    }
+ }
+Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/AbstractXinhaPlugin.java
+===================================================================
+--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/AbstractXinhaPlugin.java	(revision 21294)
++++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/AbstractXinhaPlugin.java	(working copy)
+@@ -124,7 +124,8 @@
+             add(HeaderContributor.forJavaScript(XINHA_MODAL_JS));
+ 
+             String nodePath = getValueModel().getJcrPropertymodel().getItemModel().getParentModel().getPath();
+-            configuration.addProperty("prefix", XinhaUtil.encode(BINARIES_PREFIX + nodePath));
++            configuration.addProperty("prefix", XinhaUtil.encodeResourceURL(XinhaUtil.encode(BINARIES_PREFIX + nodePath + "/")));
++            configuration.addProperty("isPortletContext", Boolean.toString(XinhaUtil.isPortletContext()));
+ 
+             JcrNodeModel nodeModel = new JcrNodeModel(nodePath);
+             imageService = new XinhaImageService(nodeModel) {
+@@ -196,9 +197,8 @@
+                     String text = (String) getDefaultModelObject();
+                     if (text != null) {
+                         JcrPropertyValueModel propertyValueModel = getValueModel();
+-                        String prefix = XinhaUtil.encode(BINARIES_PREFIX
+-                                + propertyValueModel.getJcrPropertymodel().getItemModel().getParentModel().getPath())
+-                                + "/";
++                        String prefix = XinhaUtil.encodeResourceURL(XinhaUtil.encode(BINARIES_PREFIX
++                                + propertyValueModel.getJcrPropertymodel().getItemModel().getParentModel().getPath()) + "/");
+ 
+                         String processed = XinhaHtmlProcessor.prefixImageLinks(text, prefix);
+                         processed = XinhaHtmlProcessor.decorateInternalLinks(processed, il);
+Index: addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaHtmlProcessor.java
+===================================================================
+--- addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaHtmlProcessor.java	(revision 21294)
++++ addon/xinha-frontend/src/main/java/org/hippoecm/frontend/plugins/xinha/XinhaHtmlProcessor.java	(working copy)
+@@ -29,7 +29,8 @@
+     private static Pattern LINK_AND_IMAGES_PATTERN = Pattern.compile("<(a|img)(\\s+)(.*?)(src|href)=\"(.*?)\"(.*?)>",
+             Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+     private static Pattern IMG_PATTERN = Pattern.compile("<img[^>]+>", Pattern.CASE_INSENSITIVE);
+-    private static Pattern SRC_PATTERN = Pattern.compile("src=\"[^\"]+\"", Pattern.CASE_INSENSITIVE);
++    private static Pattern SRC_PATTERN = Pattern.compile("src=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
++    private static Pattern FACET_SELECT_PATTERN = Pattern.compile("facetselect=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+ 
+     private static Pattern LINK_PATTERN = Pattern.compile("<a[^>]+>", Pattern.CASE_INSENSITIVE);
+     private static Pattern HREF_PATTERN = Pattern.compile("href=\"[^\"]+\"", Pattern.CASE_INSENSITIVE);
+@@ -41,30 +42,43 @@
+     public static String prefixImageLinks(String text, String prefix) {
+         StringBuffer processed = new StringBuffer();
+         Matcher m = IMG_PATTERN.matcher(text);
++        
+         while (m.find()) {
+             String img = m.group();
+             StringBuffer newImg = new StringBuffer();
+             Matcher s = SRC_PATTERN.matcher(img);
++            
+             if (s.find()) {
+                 String src = s.group();
+-                // skip src=
+-                String link = src.substring(4);
+-                if (link.charAt(0) == '"') {
+-                    link = link.substring(1);
+-                }
+-                if (link.charAt(link.length() - 1) == '"') {
+-                    link = link.substring(0, link.length() - 1);
+-                }
+-                if (!link.startsWith("http:") && !link.startsWith("https:")) {
+-                    s.appendReplacement(newImg, ("src=\"" + prefix + link + "\"").replace("\\", "\\\\").replace("$",
+-                            "\\$"));
++                Matcher fs = FACET_SELECT_PATTERN.matcher(img);
++                
++                if (fs.find()) {
++                    String link = fs.group(1);
++                    
++                    if (!link.startsWith("http:") && !link.startsWith("https:")) {
++                        if (XinhaUtil.isPortletContext()) {
++                            s.appendReplacement(newImg, ("src=\"" + prefix + "?_path=" + link + "\"").replace("\\", "\\\\").replace("$", "\\$"));
++                        } else {
++                            s.appendReplacement(newImg, ("src=\"" + prefix + link + "\"").replace("\\", "\\\\").replace("$", "\\$"));
++                        }
++                    } else {
++                        s.appendReplacement(newImg, src.replace("\\", "\\\\").replace("$", "\\$"));
++                    }
+                 } else {
+-                    s.appendReplacement(newImg, src.replace("\\", "\\\\").replace("$", "\\$"));
++                    String link = s.group(1);
++                    
++                    if (!link.startsWith("http:") && !link.startsWith("https:")) {
++                        s.appendReplacement(newImg, ("src=\"" + prefix + link + "\"").replace("\\", "\\\\").replace("$", "\\$"));
++                    } else {
++                        s.appendReplacement(newImg, src.replace("\\", "\\\\").replace("$", "\\$"));
++                    }
+                 }
+             }
++            
+             s.appendTail(newImg);
+             m.appendReplacement(processed, newImg.toString().replace("\\", "\\\\").replace("$", "\\$"));
+         }
++        
+         m.appendTail(processed);
+ 
+         return processed.toString();
+Index: addon/xinha-frontend/src/main/resources/html-cleaner-service.xml
+===================================================================
+--- addon/xinha-frontend/src/main/resources/html-cleaner-service.xml	(revision 21294)
++++ addon/xinha-frontend/src/main/resources/html-cleaner-service.xml	(working copy)
+@@ -312,6 +312,7 @@
+           <sv:value>width</sv:value>
+           <sv:value>height</sv:value>
+           <sv:value>title</sv:value>
++          <sv:value>facetselect</sv:value>
+         </sv:property>
+       </sv:node>
+ 
+Index: addon/xinha/webResources/xinha/plugins/InsertImage/InsertImage.js
+===================================================================
+--- addon/xinha/webResources/xinha/plugins/InsertImage/InsertImage.js	(revision 21294)
++++ addon/xinha/webResources/xinha/plugins/InsertImage/InsertImage.js	(working copy)
+@@ -20,6 +20,7 @@
+ 
+     this.imgRE = new RegExp('<img[^>]+>', 'gi');
+     this.srcRE = new RegExp('src="[^"]+"', 'i');
++    this.facetselectRE = new RegExp('facetselect="([^"]+)"', 'i');
+     this.noReplacePrefixes = ['http:', 'https:', '/'];
+ }
+ 
+@@ -79,6 +80,7 @@
+             self.editor.updateToolbar();
+         } else {
+             self.apply();
++            img = self.image;
+         }
+         self.editor.plugins.AutoSave.instance.save();
+     };
+@@ -102,15 +104,26 @@
+  */
+ InsertImage.prototype.inwardHtml = function(html) {
+     var _this = this;
+-    var prefix = this.getPrefix();    
++    var prefix = this.getPrefix();
++    var isPortletContext = this.isPortletContext();
+     html = html.replace(this.imgRE, function(m) {
+-        m = m.replace(_this.srcRE, function(n) {
+-            var url = n.substring(5, n.length - 1);
+-            if(_this.shouldPrefix(url)) {
+-                return 'src="' + prefix + url + '"';
+-            }
+-            return n;
+-        });
++        if (_this.facetselectRE.test(m)) {
++            var facetselect = RegExp.$1;
++            m = m.replace(_this.srcRE, function(n) {
++                if (!isPortletContext)
++                    return 'src="' + prefix + facetselect + '"';
++                else
++                    return 'src="' + prefix + "?_path=" + facetselect + '"';
++            });
++        } else {
++            m = m.replace(_this.srcRE, function(n) {
++                var url = n.substring(5, n.length - 1);
++                if (_this.shouldPrefix(url)) {
++                    return 'src="' + prefix + url + '"';
++                }
++                return n;
++            });
++        }
+         return m;
+     });
+     return html;
+@@ -123,14 +136,22 @@
+     var _this = this;
+     var prefix = this.getPrefix();
+     html = html.replace(this.imgRE, function(m) {
+-        m = m.replace(_this.srcRE, function(n) {
+-            var idx = n.indexOf(prefix);
+-            if (idx > -1) {
+-                return 'src="' + n.substr(prefix.length + idx);
+-            }
+-            return n;
+-        });
+-        return m;
++        if (_this.facetselectRE.test(m)) {
++            var facetselect = RegExp.$1;
++            m = m.replace(_this.srcRE, function(n) {
++                return 'src="' + facetselect + '"';
++            });
++            return m;
++        } else {
++            m = m.replace(_this.srcRE, function(n) {
++                var idx = n.indexOf(prefix);
++                if (idx > -1) {
++                    return 'src="' + n.substr(prefix.length + idx);
++                }
++                return n;
++            });
++            return m;
++        }
+     });
+     return html;
+ }
+@@ -153,6 +174,10 @@
+     return true;
+ }
+ 
++InsertImage.prototype.isPortletContext = function() {
++    return (this.editor.config.isPortletContext);
++}
++
+ //Workaround for method not found error
+ InsertImage.prototype.stripBaseURL = function(url) {
+     return url;
Index: frontend/engine/src/main/java/org/hippoecm/frontend/Main.java
===================================================================
--- frontend/engine/src/main/java/org/hippoecm/frontend/Main.java	(revision 21294)
+++ frontend/engine/src/main/java/org/hippoecm/frontend/Main.java	(working copy)
@@ -33,6 +33,8 @@
 import javax.jcr.observation.EventListenerIterator;
 import javax.servlet.ServletContext;
 
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.IRequestTarget;
@@ -42,8 +44,6 @@
 import org.apache.wicket.Session;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.application.IClassResolver;
-import org.apache.wicket.authorization.Action;
-import org.apache.wicket.authorization.IAuthorizationStrategy;
 import org.apache.wicket.protocol.http.HttpSessionStore;
 import org.apache.wicket.protocol.http.WebApplication;
 import org.apache.wicket.request.IRequestCycleProcessor;
@@ -219,8 +219,15 @@
         mount(new AbstractRequestTargetUrlCodingStrategy("binaries") {
 
             public IRequestTarget decode(RequestParameters requestParameters) {
-                String path = requestParameters.getPath().substring("binaries/".length());
-                path = urlDecodePathComponent(path);
+                String pathInfo = StringUtils.removeEnd(requestParameters.getPath().substring("binaries/".length()), "/");
+                String pathInParams = StringUtils.removeStart(getRequestParameter(requestParameters, "_path", true), "/");
+                String path = null;
+                if (!StringUtils.isEmpty(pathInfo)) {
+                    path = StringUtils.join(new String [] { pathInfo, pathInParams }, '/');
+                } else {
+                    path = pathInParams;
+                }
+                path = urlDecodePathComponent(StringUtils.removeStart(path, "/"));
                 // FIXME: workaround use a subsession because we can't refresh the session
                 // the logout is actually performed by the JcrResourceRequestTarget
                 UserSession session = (UserSession) Session.get();
@@ -249,6 +256,25 @@
             public boolean matches(IRequestTarget requestTarget) {
                 return false;
             }
+            
+            private String getRequestParameter(RequestParameters requestParameters, String paramName, boolean concatenateAll) {
+                String paramValue = null;
+                Object param = requestParameters.getParameters().get(paramName);
+                
+                if (param != null) {
+                    if (param.getClass().isArray() && ArrayUtils.getLength(param) > 0) {
+                        if (concatenateAll) {
+                            paramValue = StringUtils.join((String []) param);
+                        } else {
+                            paramValue = ((String []) param)[0];
+                        }
+                    } else {
+                        paramValue = param.toString();
+                    }
+                }
+                
+                return paramValue;
+            }
         });
 
         resourceSettings.setLocalizer(new StagedLocalizer());
