Merging in master
diff --git a/README.md b/README.md
index c707ce0..d3df15d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 [<img src="http://sling.apache.org/res/logos/sling.png"/>](http://sling.apache.org)
 
- [![Build Status](https://builds.apache.org/buildStatus/icon?job=sling-org-apache-sling-app-cms-1.8)](https://builds.apache.org/view/S-Z/view/Sling/job/sling-org-apache-sling-app-cms-1.8) [![Test Status](https://img.shields.io/jenkins/t/https/builds.apache.org/view/S-Z/view/Sling/job/sling-org-apache-sling-app-cms-1.8.svg)](https://builds.apache.org/view/S-Z/view/Sling/job/sling-org-apache-sling-app-cms-1.8/test_results_analyzer/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
+ [![Build Status](https://builds.apache.org/buildStatus/icon?job=sling-org-apache-sling-app-cms-1.8)](https://builds.apache.org/view/S-Z/view/Sling/job/sling-org-apache-sling-app-cms-1.8) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.sling/org.apache.sling.cms/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.apache.sling%22%20a%3A%22org.apache.sling.cms%22) [![JavaDocs](https://www.javadoc.io/badge/org.apache.sling/org.apache.sling.cms.api.svg)](https://www.javadoc.io/doc/org.apache.sling/org.apache.sling.cms.api) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
 
 # Apache Sling CMS
 
@@ -11,4 +11,8 @@
  * [Quickstart](docs/quickstart.md)
  * [Administration](docs/administration.md)
  * [Developers](docs/developers.md)
+ * [Releases](docs/releases.md)
  * [Users](docs/users.md)
+ 
+### [Download Latest Version](https://search.maven.org/remotecontent?filepath=org/apache/sling/org.apache.sling.cms.builder/0.10.0/org.apache.sling.cms.builder-0.10.0.jar)
+### [Report an Issue](https://issues.apache.org/jira)
diff --git a/core/pom.xml b/core/pom.xml
index 2b20be9..8362b93 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1,15 +1,12 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-    license agreements. See the NOTICE file distributed with this work for additional 
-    information regarding copyright ownership. The ASF licenses this file to 
-    you 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to you 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+>
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <artifactId>org.apache.sling.cms</artifactId>
@@ -191,6 +188,10 @@
             <scope>provided</scope>
             <version>2.0.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>oak-core</artifactId>
+        </dependency>
     </dependencies>
     <properties>
         <sling.java.version>8</sling.java.version>
diff --git a/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java b/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java
index ae73a0a..635ba8f 100644
--- a/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java
+++ b/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java
@@ -28,6 +28,7 @@
 import javax.servlet.ServletResponse;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.WordUtils;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
@@ -88,6 +89,14 @@
             if (er != null) {
                 component = er.getComponent();
             }
+            String componentTitle = "";
+            if (component != null) {
+                componentTitle = component.getTitle();
+            }
+            if (StringUtils.isEmpty(componentTitle)) {
+                String componentName = StringUtils.substringAfterLast(resource.getResourceType(), "/");
+                WordUtils.capitalizeFully(componentName.replace('-', ' '));
+            }
             writer.write("<div class=\"sling-cms-component\" data-sling-cms-title=\""
                     + (component != null ? component.getTitle() : "") + "\" data-sling-cms-resource-path=\""
                     + resource.getPath() + "\" data-sling-cms-resource-type=\"" + resource.getResourceType()
@@ -98,18 +107,18 @@
             writer.write(
                     "<div class=\"control\"><button class=\"level-item button\" data-sling-cms-action=\"edit\" data-sling-cms-path=\""
                             + resource.getPath() + "\" data-sling-cms-edit=\"" + editPath
-                            + "\" title=\"Edit\"><span class=\"jam jam-pencil-f\"></span></button></div>");
+                            + "\" title=\"Edit Component\"><span class=\"jam jam-pencil-f\"></span></button></div>");
             if (!first || !last) {
                 writer.write(
                         "<div class=\"control\"><button class=\"level-item button\" data-sling-cms-action=\"reorder\" data-sling-cms-path=\""
                                 + resource.getPath()
-                                + "\" title=\"Reorder\"><span class=\"jam jam-arrows-v\"></span></button></div>");
+                                + "\" title=\"Reorder Component\"><span class=\"jam jam-arrows-v\"></span></button></div>");
             }
             if (!resource.getName().equals(JcrConstants.JCR_CONTENT) && exists) {
                 writer.write(
                         "<div class=\"control\"><button class=\"level-item button\" data-sling-cms-action=\"delete\" data-sling-cms-path=\""
                                 + resource.getPath()
-                                + "\" title=\"Delete\"><span class=\"jam jam-trash\"></span></button></div>");
+                                + "\" title=\"Delete Component\"><span class=\"jam jam-trash\"></span></button></div>");
             }
 
             writer.write("</div></div>");
diff --git a/core/src/main/java/org/apache/sling/cms/core/internal/operations/BulkReplaceOperation.java b/core/src/main/java/org/apache/sling/cms/core/internal/operations/BulkReplaceOperation.java
index f2df10b..18c5d05 100644
--- a/core/src/main/java/org/apache/sling/cms/core/internal/operations/BulkReplaceOperation.java
+++ b/core/src/main/java/org/apache/sling/cms/core/internal/operations/BulkReplaceOperation.java
@@ -44,129 +44,136 @@
  * replacing the find string with the replacement value.
  */
 @Component(immediate = true, service = { PostOperation.class }, property = PostOperation.PROP_OPERATION_NAME
-		+ "=bulkreplace")
+        + "=bulkreplace")
 public class BulkReplaceOperation implements PostOperation {
 
-	private static final Logger log = LoggerFactory.getLogger(BulkReplaceOperation.class);
+    private static final Logger log = LoggerFactory.getLogger(BulkReplaceOperation.class);
 
-	public static final String PN_UPDATE_PROPERTIES = "updateProperties";
-	public static final String MODE_REGEX = "regex";
-	public static final String PN_FIND = "find";
-	public static final String PN_REPLACE = "replace";
-	public static final String PN_MODE = "mode";
+    public static final String PN_UPDATE_PROPERTIES = "updateProperties";
+    public static final String MODE_REGEX = "regex";
+    public static final String PN_FIND = "find";
+    public static final String PN_REPLACE = "replace";
+    public static final String PN_MODE = "mode";
 
-	@Override
-	public void run(SlingHttpServletRequest request, PostResponse response, SlingPostProcessor[] processors) {
+    @Override
+    public void run(SlingHttpServletRequest request, PostResponse response, SlingPostProcessor[] processors) {
 
-		try {
-			// calculate the paths
-			String path = request.getResource().getPath();
-			response.setPath(path);
+        try {
+            // calculate the paths
+            String path = request.getResource().getPath();
+            response.setPath(path);
 
-			// perform the bulk replacement
-			Pattern updateProperties = Pattern.compile(request.getParameter(PN_UPDATE_PROPERTIES));
-			log.debug("Updating properties matching: {}", updateProperties.pattern());
-			Pattern rfind = null;
-			String find = request.getParameter(PN_FIND);
-			if (MODE_REGEX.equals(request.getParameter(PN_MODE))) {
-				log.debug("Using regular expressions to search for {}", find);
-				rfind = Pattern.compile(find);
-			} else {
-				log.debug("Searching for {}", find);
-			}
-			String replace = request.getParameter(PN_REPLACE);
-			log.debug("Replacing with {}", replace);
+            // perform the bulk replacement
+            Pattern updateProperties = Pattern.compile(request.getParameter(PN_UPDATE_PROPERTIES));
+            log.debug("Updating properties matching: {}", updateProperties.pattern());
+            Pattern rfind = null;
+            String find = request.getParameter(PN_FIND);
+            if (MODE_REGEX.equals(request.getParameter(PN_MODE))) {
+                log.debug("Using regular expressions to search for {}", find);
+                rfind = Pattern.compile(find);
+            } else {
+                log.debug("Searching for {}", find);
+            }
+            String replace = request.getParameter(PN_REPLACE);
+            log.debug("Replacing with {}", replace);
 
-			final List<Modification> changes = new ArrayList<>();
-			updateProperties(request.getResource(), updateProperties, rfind, find, replace, response, changes);
+            final List<Modification> changes = new ArrayList<>();
+            updateProperties(request.getResource(), updateProperties, rfind, find, replace, response, changes);
 
-			// invoke processors
-			if (processors != null) {
-				for (SlingPostProcessor processor : processors) {
-					processor.process(request, changes);
-				}
-			}
+            // invoke processors
+            if (processors != null) {
+                for (SlingPostProcessor processor : processors) {
+                    processor.process(request, changes);
+                }
+            }
 
-			// check modifications for remaining postfix and store the base path
-			final Map<String, String> modificationSourcesContainingPostfix = new HashMap<>();
-			final Set<String> allModificationSources = new HashSet<>(changes.size());
-			for (final Modification modification : changes) {
-				final String source = modification.getSource();
-				if (source != null) {
-					allModificationSources.add(source);
-					final int atIndex = source.indexOf('@');
-					if (atIndex > 0) {
-						modificationSourcesContainingPostfix.put(source.substring(0, atIndex), source);
-					}
-				}
-			}
-			request.getResourceResolver().commit();
+            // check modifications for remaining postfix and store the base path
+            final Map<String, String> modificationSourcesContainingPostfix = new HashMap<>();
+            final Set<String> allModificationSources = new HashSet<>(changes.size());
+            for (final Modification modification : changes) {
+                final String source = modification.getSource();
+                if (source != null) {
+                    allModificationSources.add(source);
+                    final int atIndex = source.indexOf('@');
+                    if (atIndex > 0) {
+                        modificationSourcesContainingPostfix.put(source.substring(0, atIndex), source);
+                    }
+                }
+            }
+            request.getResourceResolver().commit();
 
-		} catch (Exception e) {
+        } catch (Exception e) {
 
-			log.error("Exception during response processing.", e);
-			response.setError(e);
+            log.error("Exception during response processing.", e);
+            response.setError(e);
 
-		}
-	}
+        }
+    }
 
-	private void updateProperties(Resource resource, Pattern updateProperties, Pattern rfind, String find,
-			String replace, PostResponse response, List<Modification> changes) {
-		ModifiableValueMap properties = resource.adaptTo(ModifiableValueMap.class);
-		boolean updated = false;
-		for (Entry<String, Object> entry : properties.entrySet()) {
+    private void updateProperties(Resource resource, Pattern updateProperties, Pattern rfind, String find,
+            String replace, PostResponse response, List<Modification> changes) {
+        ModifiableValueMap properties = resource.adaptTo(ModifiableValueMap.class);
+        boolean updated = false;
+        for (Entry<String, Object> entry : properties.entrySet()) {
 
-			if (updateProperties.matcher(entry.getKey()).matches()) {
-				log.trace("Checking property {}@{}", resource.getPath(), entry.getKey());
-				if (properties.get(entry.getKey()) instanceof String) {
-					String value = (String) entry.getValue();
-					if (rfind == null && (value.contains(find) || value.equals(find))) {
-						value = value.replace(find, replace);
-						log.trace("Value after replacement: {}", value);
-						properties.put(entry.getKey(), value);
-						updated = true;
-					} else if (rfind != null) {
-						Matcher m = rfind.matcher(value);
-						if (m.find()) {
-							value = rfind.matcher(value).replaceAll(replace);
-							log.trace("Value after replacement: {}", value);
-							properties.put(entry.getKey(), value);
-							updated = true;
-						}
-					}
-				} else if (properties.get(entry) instanceof String[]) {
-					log.trace("Found array value");
-					boolean arrUpdated = false;
-					String[] v = (String[]) entry.getValue();
-					for (int i = 0; i < v.length; i++) {
-						String value = v[i];
-						if (rfind == null && (value.contains(find) || value.equals(find))) {
-							v[i] = value.replace(find, replace);
-							arrUpdated = true;
-						} else if (rfind != null) {
-							Matcher m = rfind.matcher(value);
-							if (m.find()) {
-								v[i] = rfind.matcher(value).replaceAll(replace);
-								arrUpdated = true;
-							}
-						}
-					}
-					if (arrUpdated) {
-						if (log.isTraceEnabled()) {
-							log.trace("Value after replacement: {}", Arrays.toString(v));
-						}
-						properties.put(entry.getKey(), v);
-						updated = true;
-					}
-				}
-			}
-		}
-		if (updated) {
-			response.onModified(resource.getPath());
-			changes.add(Modification.onModified(resource.getPath()));
-		}
-		for (Resource child : resource.getChildren()) {
-			updateProperties(child, updateProperties, rfind, find, replace, response, changes);
-		}
-	}
+            if (updateProperties.matcher(entry.getKey()).matches()) {
+                updated = updateProperty(resource, rfind, find, replace, properties, updated, entry);
+            }
+        }
+        if (updated) {
+            response.onModified(resource.getPath());
+            changes.add(Modification.onModified(resource.getPath()));
+        }
+        for (Resource child : resource.getChildren()) {
+            updateProperties(child, updateProperties, rfind, find, replace, response, changes);
+        }
+    }
+
+    @SuppressWarnings("unlikely-arg-type")
+    private boolean updateProperty(Resource resource, Pattern rfind, String find, String replace,
+            ModifiableValueMap properties, boolean updated, Entry<String, Object> entry) {
+        log.trace("Checking property {}@{}", resource.getPath(), entry.getKey());
+        if (properties.get(entry.getKey()) instanceof String) {
+            String value = (String) entry.getValue();
+            if (rfind == null && (value.contains(find) || value.equals(find))) {
+                value = value.replace(find, replace);
+                log.trace("Value after replacement: {}", value);
+                properties.put(entry.getKey(), value);
+                updated = true;
+            } else if (rfind != null) {
+                Matcher m = rfind.matcher(value);
+                if (m.find()) {
+                    value = rfind.matcher(value).replaceAll(replace);
+                    log.trace("Value after replacement: {}", value);
+                    properties.put(entry.getKey(), value);
+                    updated = true;
+                }
+            }
+        } else if (properties.get(entry) instanceof String[]) {
+            log.trace("Found array value");
+            boolean arrUpdated = false;
+            String[] v = (String[]) entry.getValue();
+            for (int i = 0; i < v.length; i++) {
+                String value = v[i];
+                if (rfind == null && (value.contains(find) || value.equals(find))) {
+                    v[i] = value.replace(find, replace);
+                    arrUpdated = true;
+                } else if (rfind != null) {
+                    Matcher m = rfind.matcher(value);
+                    if (m.find()) {
+                        v[i] = rfind.matcher(value).replaceAll(replace);
+                        arrUpdated = true;
+                    }
+                }
+            }
+            if (arrUpdated) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Value after replacement: {}", Arrays.toString(v));
+                }
+                properties.put(entry.getKey(), v);
+                updated = true;
+            }
+        }
+        return updated;
+    }
 }
diff --git a/core/src/main/java/org/apache/sling/cms/core/models/ErrorHandler.java b/core/src/main/java/org/apache/sling/cms/core/models/ErrorHandler.java
index ac0ba8d..9c738b0 100644
--- a/core/src/main/java/org/apache/sling/cms/core/models/ErrorHandler.java
+++ b/core/src/main/java/org/apache/sling/cms/core/models/ErrorHandler.java
@@ -20,14 +20,21 @@
 
 import javax.annotation.PostConstruct;
 import javax.inject.Named;
+import javax.servlet.RequestDispatcher;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.request.RequestDispatcherOptions;
+import org.apache.sling.api.request.RequestPathInfo;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
 import org.apache.sling.cms.CMSUtils;
 import org.apache.sling.cms.Site;
 import org.apache.sling.cms.SiteManager;
@@ -51,30 +58,159 @@
 @Model(adaptables = SlingHttpServletRequest.class)
 public class ErrorHandler {
 
-    public static final String SERVICE_USER_NAME = "sling-cms-error";
+    private static class GetRequest extends SlingHttpServletRequestWrapper {
+
+        public GetRequest(SlingHttpServletRequest wrappedRequest) {
+            super(wrappedRequest);
+        }
+
+        @Override
+        public String getMethod() {
+            return "GET";
+        }
+
+        @Override
+        public RequestPathInfo getRequestPathInfo() {
+            return new HTMLRequestPathInfo(super.getRequestPathInfo());
+        }
+    }
+
+    private static class HTMLRequestPathInfo implements RequestPathInfo {
+
+        private RequestPathInfo info;
+
+        public HTMLRequestPathInfo(RequestPathInfo info) {
+            this.info = info;
+        }
+
+        @Override
+        public String getResourcePath() {
+            return info.getResourcePath();
+        }
+
+        @Override
+        public String getExtension() {
+            return "html";
+        }
+
+        @Override
+        public String getSelectorString() {
+            return "";
+        }
+
+        @Override
+        public String[] getSelectors() {
+            return new String[0];
+        }
+
+        @Override
+        public String getSuffix() {
+            return "";
+        }
+
+        @Override
+        public Resource getSuffixResource() {
+            return null;
+        }
+
+    }
+
+    /**
+     * The page to fall back to if there is not an error page for the specific code
+     */
+    public static final String DEFAULT_ERROR_PAGE = "default";
 
     private static final Logger log = LoggerFactory.getLogger(ErrorHandler.class);
 
+    /**
+     * Service User Name for the Error Handler
+     */
+    public static final String SERVICE_USER_NAME = "sling-cms-error";
+
+    /**
+     * The subpath under which to find the error pages
+     */
+    public static final String SITE_ERRORS_SUBPATH = "errors/";
+
+    /**
+     * Path under which the error pages for Sling CMS can be found.
+     */
+    public static final String SLING_CMS_ERROR_PATH = "/content/sling-cms/errorhandling/";
+
     @RequestAttribute
     @Named(SlingConstants.ERROR_STATUS)
     @Optional
-    @Default(intValues = 500)
+    @Default(intValues = HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
     private Integer errorCode;
 
-    private SlingHttpServletRequest slingRequest;
-
-    private Resource handler;
-
-    @SlingObject
-    private HttpServletResponse response;
-
     @OSGiService
     private ResourceResolverFactory factory;
 
+    private Resource handler;
+
+    @SlingObject
+    private SlingHttpServletResponse slingResponse;
+
+    private SlingHttpServletRequest slingRequest;
+
     public ErrorHandler(SlingHttpServletRequest slingRequest) {
         this.slingRequest = slingRequest;
     }
 
+    private void calculateErrorCode(ResourceResolver resolver) {
+        if (errorCode == HttpServletResponse.SC_NOT_FOUND) {
+            log.debug("Validating the resource does not exist for all users");
+            ResourceResolver adminResolver = null;
+            try {
+                adminResolver = factory.getServiceResourceResolver(new HashMap<String, Object>() {
+                    private static final long serialVersionUID = 1L;
+                    {
+                        put(ResourceResolverFactory.SUBSERVICE, SERVICE_USER_NAME);
+                    }
+                });
+                Resource pResource = adminResolver.resolve(slingRequest, slingRequest.getResource().getPath());
+                if (!CMSUtils.isPublished(pResource) || pResource.isResourceType(Resource.RESOURCE_TYPE_NON_EXISTING)) {
+                    errorCode = HttpServletResponse.SC_NOT_FOUND;
+                } else if (UserConstants.DEFAULT_ANONYMOUS_ID.equals(resolver.getUserID())) {
+                    errorCode = HttpServletResponse.SC_UNAUTHORIZED;
+                } else {
+                    errorCode = HttpServletResponse.SC_FORBIDDEN;
+                }
+            } catch (LoginException e) {
+                log.error("Exception retrieving service user", e);
+            } finally {
+                if (adminResolver != null) {
+                    adminResolver.close();
+                }
+            }
+        }
+    }
+
+    private void doInclude() {
+
+        Resource handlerContent = handler.getChild(JcrConstants.JCR_CONTENT);
+        if (handlerContent != null) {
+            log.debug("Including handler {}", handlerContent);
+
+            RequestDispatcherOptions rdo = new RequestDispatcherOptions();
+            rdo.setReplaceSelectors("");
+            rdo.setReplaceSuffix("");
+            rdo.setForceResourceType(handlerContent.getResourceType());
+            final RequestDispatcher dispatcher = slingRequest.getRequestDispatcher(handlerContent, rdo);
+            if (dispatcher != null) {
+                try {
+                    dispatcher.include(new GetRequest(slingRequest), slingResponse);
+                } catch (Exception e) {
+                    log.debug("Exception swallowed while including error page", e);
+                }
+            } else {
+                log.warn("Failed to get request dispatcher for handler {}", handler.getPath());
+            }
+        } else {
+            log.warn("Error hander {} content is null", handler);
+        }
+    }
+
     @PostConstruct
     public void init() {
 
@@ -96,11 +232,10 @@
                 Site site = siteMgr.getSite();
                 log.debug("Checking for error pages in the site {}", site.getPath());
 
-                handler = site.getResource().getChild("errors/" + errorCode.toString());
+                handler = site.getResource().getChild(SITE_ERRORS_SUBPATH + errorCode.toString());
                 if (handler == null) {
-                    handler = site.getResource().getChild("errors/default");
+                    handler = site.getResource().getChild(SITE_ERRORS_SUBPATH + DEFAULT_ERROR_PAGE);
                 }
-
                 if (handler != null) {
                     log.debug("Using error handler {}", handler);
                 } else {
@@ -113,49 +248,21 @@
 
         if (handler == null) {
             log.debug("Using Sling CMS default error pages");
-            handler = resolver.getResource("/content/sling-cms/errorhandling/" + errorCode.toString());
+            handler = resolver.getResource(SLING_CMS_ERROR_PATH + errorCode.toString());
             if (handler == null) {
-                handler = resolver.getResource("/content/sling-cms/errorhandling/default");
+                handler = resolver.getResource(SLING_CMS_ERROR_PATH + DEFAULT_ERROR_PAGE);
             }
             log.debug("Using Sling CMS error handler {}", handler);
         }
 
         log.debug("Sending error {}", errorCode);
-        response.setStatus(errorCode);
+        slingResponse.reset();
+        slingResponse.setContentType("text/html");
+        slingResponse.setStatus(errorCode);
+
+        doInclude();
 
         log.debug("Error handler initialized successfully!");
     }
 
-    private void calculateErrorCode(ResourceResolver resolver) {
-        if (errorCode == 404) {
-            log.debug("Validating the resource does not exist for all users");
-            ResourceResolver adminResolver;
-            try {
-                adminResolver = factory.getServiceResourceResolver(new HashMap<String, Object>() {
-                    private static final long serialVersionUID = 1L;
-                    {
-                        put(ResourceResolverFactory.SUBSERVICE, SERVICE_USER_NAME);
-                    }
-                });
-                Resource pResource = adminResolver.resolve(slingRequest, slingRequest.getResource().getPath());
-                if (!CMSUtils.isPublished(pResource)) {
-                    errorCode = 404;
-                } else if ("anonymous".equals(resolver.getUserID())) {
-                    errorCode = 401;
-                } else {
-                    errorCode = 403;
-                }
-            } catch (LoginException e) {
-                log.error("Exception retrieving service user", e);
-            }
-        }
-    }
-
-    public Resource getHandler() {
-        return handler;
-    }
-
-    public int getErrorCode() {
-        return errorCode;
-    }
 }
diff --git a/core/src/main/java/org/apache/sling/cms/core/models/package-info.java b/core/src/main/java/org/apache/sling/cms/core/models/package-info.java
index da2cdc7..1118341 100644
--- a/core/src/main/java/org/apache/sling/cms/core/models/package-info.java
+++ b/core/src/main/java/org/apache/sling/cms/core/models/package-info.java
@@ -19,8 +19,6 @@
 
 /**
  * Package with all of the core models used to support the Sling reference CMS
- *
- * @version 0.9.0
  */
 @Version("1.1.0")
 package org.apache.sling.cms.core.models;
diff --git a/docs/admin-tools.md b/docs/admin-tools.md
index c57ecdd..fdf6c11 100644
--- a/docs/admin-tools.md
+++ b/docs/admin-tools.md
@@ -18,7 +18,7 @@
 
 ![Bulk Replace](img/bulk-replace.png)
 
-This tool can be accessed at [http://localhost:8080/cms/admin/bulkreplace.html{SUFFIX}](http://localhost:8080/cms/admin/bulkreplace.html{SUFFIX}), with the *{SUFFIX}* being the path under which you want the replacement to take place. This will find and replace the target term with the replacement term in all matching properties.
+This tool can be accessed  from *Tools > Content Import* or at [http://localhost:8080/cms/admin/bulkreplace.html](http://localhost:8080/cms/admin/bulkreplace.html). First, select the path under which to perform the bulk replacement, then specify replacement configuration. This will find and replace the target term with the replacement term in all matching properties.
 
 ## Content Packages
 
@@ -30,7 +30,7 @@
 
 ![Load Content](img/load-content.png)
 
-This tool can be accessed at [http://localhost:8080/cms/admin/loadcontent.html{SUFFIX}](http://localhost:8080/cms/admin/loadcontent.html{SUFFIX}), with the *{SUFFIX}* being the path under which you want load the content. This will load a JSON string of content into the Sling CMS repository.
+This tool can be accessed from *Tools > Load Content* or at [http://localhost:8080/cms/admin/loadcontent.html](http://localhost:8080/cms/admin/loadcontent.html). First specify the path under which to load the content, then the import configuration This will load a string of content into the Sling CMS repository.
 
 ## Internationalization
 
diff --git a/docs/administration.md b/docs/administration.md
index bc374d3..8d71528 100644
--- a/docs/administration.md
+++ b/docs/administration.md
@@ -19,4 +19,5 @@
  - [Creating a Template](templates.md)
  - [Error Pages](error-pages.md)
  - [MongoDB Support](mongodb.md)
- - [Securing Sling CMS](securing.md)
\ No newline at end of file
+ - [Securing Sling CMS](securing.md)
+ - [User Generated Content](user-generated-content.md)
\ No newline at end of file
diff --git a/docs/developers.md b/docs/developers.md
index cb15e92..145f1b3 100644
--- a/docs/developers.md
+++ b/docs/developers.md
@@ -17,4 +17,5 @@
 * [Editor Field Types](editor-field-types.md)
 * [Extending Sling CMS](extending.md)
 * [Project Intro](intro.md)
-* [Reference Project](reference.md)
\ No newline at end of file
+* [Reference Project](reference.md)
+* [User Generated Content](user-generated-content.md)
\ No newline at end of file
diff --git a/docs/img/add-config.png b/docs/img/add-config.png
index c404a2a..5610b9c 100644
--- a/docs/img/add-config.png
+++ b/docs/img/add-config.png
Binary files differ
diff --git a/docs/img/add-taxonomy.png b/docs/img/add-taxonomy.png
index 2f9c834..d17cc52 100644
--- a/docs/img/add-taxonomy.png
+++ b/docs/img/add-taxonomy.png
Binary files differ
diff --git a/docs/img/add-template.png b/docs/img/add-template.png
index 7e4bd41..0afba28 100644
--- a/docs/img/add-template.png
+++ b/docs/img/add-template.png
Binary files differ
diff --git a/docs/img/bulk-replace.png b/docs/img/bulk-replace.png
index aecd777..20436f3 100644
--- a/docs/img/bulk-replace.png
+++ b/docs/img/bulk-replace.png
Binary files differ
diff --git a/docs/img/component-configurations.png b/docs/img/component-configurations.png
index e3a7cc9..a510176 100644
--- a/docs/img/component-configurations.png
+++ b/docs/img/component-configurations.png
Binary files differ
diff --git a/docs/img/component-editor.png b/docs/img/component-editor.png
index 61d169c..f737101 100644
--- a/docs/img/component-editor.png
+++ b/docs/img/component-editor.png
Binary files differ
diff --git a/docs/img/configuration-fields.png b/docs/img/configuration-fields.png
index 377d252..be88322 100644
--- a/docs/img/configuration-fields.png
+++ b/docs/img/configuration-fields.png
Binary files differ
diff --git a/docs/img/configure-security-filter.png b/docs/img/configure-security-filter.png
index 64b50ac..246213e 100644
--- a/docs/img/configure-security-filter.png
+++ b/docs/img/configure-security-filter.png
Binary files differ
diff --git a/docs/img/container-add.png b/docs/img/container-add.png
index f3cff3b..bd2fde8 100644
--- a/docs/img/container-add.png
+++ b/docs/img/container-add.png
Binary files differ
diff --git a/docs/img/content-packages.png b/docs/img/content-packages.png
index 6b07718..1dd16ca 100644
--- a/docs/img/content-packages.png
+++ b/docs/img/content-packages.png
Binary files differ
diff --git a/docs/img/create-site-configuration.png b/docs/img/create-site-configuration.png
index 68aca1f..e7912f0 100644
--- a/docs/img/create-site-configuration.png
+++ b/docs/img/create-site-configuration.png
Binary files differ
diff --git a/docs/img/create-site-group.png b/docs/img/create-site-group.png
index b015b10..ab37ccc 100644
--- a/docs/img/create-site-group.png
+++ b/docs/img/create-site-group.png
Binary files differ
diff --git a/docs/img/create-site.png b/docs/img/create-site.png
index a974d4d..f6609f4 100644
--- a/docs/img/create-site.png
+++ b/docs/img/create-site.png
Binary files differ
diff --git a/docs/img/delete-dialog.png b/docs/img/delete-dialog.png
index 3a97012..2a9bbc6 100644
--- a/docs/img/delete-dialog.png
+++ b/docs/img/delete-dialog.png
Binary files differ
diff --git a/docs/img/edit-file-config.png b/docs/img/edit-file-config.png
index 249bb07..62a6f8d 100644
--- a/docs/img/edit-file-config.png
+++ b/docs/img/edit-file-config.png
Binary files differ
diff --git a/docs/img/edit-site-configuration.png b/docs/img/edit-site-configuration.png
index aa275aa..29d47c4 100644
--- a/docs/img/edit-site-configuration.png
+++ b/docs/img/edit-site-configuration.png
Binary files differ
diff --git a/docs/img/edit-template.png b/docs/img/edit-template.png
index 3559c51..6d095fe 100644
--- a/docs/img/edit-template.png
+++ b/docs/img/edit-template.png
Binary files differ
diff --git a/docs/img/editor-topbar.png b/docs/img/editor-topbar.png
index 9c58cf1..61722fd 100644
--- a/docs/img/editor-topbar.png
+++ b/docs/img/editor-topbar.png
Binary files differ
diff --git a/docs/img/internationalization.png b/docs/img/internationalization.png
index 0f0a2a4..57719c5 100644
--- a/docs/img/internationalization.png
+++ b/docs/img/internationalization.png
Binary files differ
diff --git a/docs/img/load-content.png b/docs/img/load-content.png
index 0d8f8ca..d5333ba 100644
--- a/docs/img/load-content.png
+++ b/docs/img/load-content.png
Binary files differ
diff --git a/docs/img/manage-versions.png b/docs/img/manage-versions.png
index a01a266..c7d3b4f 100644
--- a/docs/img/manage-versions.png
+++ b/docs/img/manage-versions.png
Binary files differ
diff --git a/docs/img/mappings.png b/docs/img/mappings.png
index e2a4c95..ef54c2d 100644
--- a/docs/img/mappings.png
+++ b/docs/img/mappings.png
Binary files differ
diff --git a/docs/img/move-copy.png b/docs/img/move-copy.png
index ac8c119..cbbdb46 100644
--- a/docs/img/move-copy.png
+++ b/docs/img/move-copy.png
Binary files differ
diff --git a/docs/img/node-browser.png b/docs/img/node-browser.png
index 6ffe358..90c09c8 100644
--- a/docs/img/node-browser.png
+++ b/docs/img/node-browser.png
Binary files differ
diff --git a/docs/img/osgi-console.png b/docs/img/osgi-console.png
index a252968..193d026 100644
--- a/docs/img/osgi-console.png
+++ b/docs/img/osgi-console.png
Binary files differ
diff --git a/docs/img/sample-console.png b/docs/img/sample-console.png
index 5127ec9..5fbd179 100644
--- a/docs/img/sample-console.png
+++ b/docs/img/sample-console.png
Binary files differ
diff --git a/docs/img/select-config-component-type.png b/docs/img/select-config-component-type.png
index 4241df2..e56364f 100644
--- a/docs/img/select-config-component-type.png
+++ b/docs/img/select-config-component-type.png
Binary files differ
diff --git a/docs/img/select-field-type.png b/docs/img/select-field-type.png
index a57bfcd..157afcc 100644
--- a/docs/img/select-field-type.png
+++ b/docs/img/select-field-type.png
Binary files differ
diff --git a/docs/img/site-content.png b/docs/img/site-content.png
index e57ea56..2f4cddd 100644
--- a/docs/img/site-content.png
+++ b/docs/img/site-content.png
Binary files differ
diff --git a/docs/img/ugc-approval.png b/docs/img/ugc-approval.png
new file mode 100644
index 0000000..e343b5c
--- /dev/null
+++ b/docs/img/ugc-approval.png
Binary files differ
diff --git a/docs/img/ugc-console.png b/docs/img/ugc-console.png
new file mode 100644
index 0000000..ffc6679
--- /dev/null
+++ b/docs/img/ugc-console.png
Binary files differ
diff --git a/docs/img/use-taxonomy.png b/docs/img/use-taxonomy.png
index f240ec5..67fecd8 100644
--- a/docs/img/use-taxonomy.png
+++ b/docs/img/use-taxonomy.png
Binary files differ
diff --git a/docs/img/users-groups.png b/docs/img/users-groups.png
index 5c12358..b47296f 100644
--- a/docs/img/users-groups.png
+++ b/docs/img/users-groups.png
Binary files differ
diff --git a/docs/intro.md b/docs/intro.md
index 99b84c9..d985ff8 100644
--- a/docs/intro.md
+++ b/docs/intro.md
@@ -16,13 +16,26 @@
 
 ## Project Structure
 
-The Sling CMS project has three main modules:
+The Sling CMS project has five main modules:
 
  - builder - this is a Sling Starer builder, it contains the repoinit text files which define the dependencies and requirements to build Sling CMS. This will ultimately build the Sling CMS Jar.
+ - api - this is your API for interacting with Sling CMS
  - core - this is the Java code behind Sling CMS. This includes the Sling Models, Filters, Servlets, Post Operations and Rewriter code.
  - reference - this is a reference application for developers to use to extend Sling CMS, this includes both Java code and content loaded by the Sling Content Loader
  - ui - this is a bulk of the content and scripts for the Sling CMS. Most of this is located under */libs/sling-cms* although there are some other directories for configurations
  
+## Using the API
+
+The API can be imported into your Maven project with the following dependency include in your pom.xml in the `dependencies` element:
+	
+		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.cms.api</artifactId>
+			<version>CURRENT_VERSION</version>
+			<scope>provided</scope>
+		</dependency>
+		
+ 
 ## Front End Code
 
 Sling CMS uses Gulp to build the front end code which is them packaged by Maven into the overall project build. This can be a bit chatty over the network if you run `mvn clean install` with every build, so unless you are updating the front end code, it's often better to just run `mvn install`
@@ -33,4 +46,4 @@
 
 ## CMS Content
 
-The Sling CMS uses Sling Resource Merge to allow developers to overlay content provided in the base CMS. THis means that although the default content is stored in */libs/sling-cms/content* it is actually used from */mnt/overlay/sling-cms/content* a default Resource Rsolver Factory configuration them maps this path to */cms* for shorter URLs.
\ No newline at end of file
+The Sling CMS uses Sling Resource Merge to allow developers to overlay content provided in the base CMS. THis means that although the default content is stored in */libs/sling-cms/content* it is actually used from */mnt/overlay/sling-cms/content* a default Resource Rsolver Factory configuration them maps this path to */cms* for shorter URLs.
diff --git a/docs/quickstart.md b/docs/quickstart.md
index 8d562a2..de300c1 100644
--- a/docs/quickstart.md
+++ b/docs/quickstart.md
@@ -33,6 +33,8 @@
  2. Change directory into the *sling-org-apache-sling-app-cms/vagrant* directory
  3. Run the command `vagrant up`
  4. Add the following entries into your HOSTS file:
- 		127.0.0.1	sling2.apache.org
- 		127.0.0.1	cms.sling.apache.org
+ 
+        127.0.0.1 sling2.apache.org
+        127.0.0.1 cms.sling.apache.org
+        
  5. Open a browser to [http://cms.sling.apache.org:8090/](http://cms.sling.apache.org:8090/) to view Sling CMS or [http://sling2.apache.org:8090/](http://sling2.apache.org:8090/) to view the published site
diff --git a/docs/releases.md b/docs/releases.md
new file mode 100644
index 0000000..8045633
--- /dev/null
+++ b/docs/releases.md
@@ -0,0 +1,54 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	you 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. -->
+[Apache Sling](https://sling.apache.org) > [Sling CMS](https://github.com/apache/sling-org-apache-sling-app-cms) > Versions
+
+# Versions
+
+## 0.10.0 - CURRENT VERSION
+
+Major UI update to use Bulma framework. Significant enhancements and updates. Update to separate out API from core code.
+
+ * [Download](https://search.maven.org/remotecontent?filepath=org/apache/sling/org.apache.sling.cms.builder/0.10.0/org.apache.sling.cms.builder-0.10.0.jar)
+ * [JavaDoc](http://javadoc.io/doc/org.apache.sling/org.apache.sling.cms.api/0.10.0)
+
+
+#### Release Notes
+
+##### Bug
+
+*   \[[SLING-7807](https://issues.apache.org/jira/browse/SLING-7807)\] - CMS - Error Handler Returns 404
+*   \[[SLING-7818](https://issues.apache.org/jira/browse/SLING-7818)\] - CMS - Core Packages Exposed
+*   \[[SLING-7861](https://issues.apache.org/jira/browse/SLING-7861)\] - CMS - UI - Delete / Move Page Error
+*   \[[SLING-7862](https://issues.apache.org/jira/browse/SLING-7862)\] - CMS - UI - Editor Shows Previous Form
+*   \[[SLING-7885](https://issues.apache.org/jira/browse/SLING-7885)\] - CMS - Core - UGC Service Not Registered
+
+##### New Feature
+
+*   \[[SLING-7819](https://issues.apache.org/jira/browse/SLING-7819)\] - CMS - Add Markdown Support
+
+##### Improvement
+
+*   \[[SLING-7806](https://issues.apache.org/jira/browse/SLING-7806)\] - CMS - Reference - RSS Feed Flexibility / Features
+*   \[[SLING-7808](https://issues.apache.org/jira/browse/SLING-7808)\] - CMS - Add File Optimization Support
+*   \[[SLING-7817](https://issues.apache.org/jira/browse/SLING-7817)\] - CMS - Reference - Search Enhancements
+*   \[[SLING-7852](https://issues.apache.org/jira/browse/SLING-7852)\] - CMS - UI - Improve Modal Interactions
+*   \[[SLING-7853](https://issues.apache.org/jira/browse/SLING-7853)\] - CMS - UI - Rich Text Editor Scrolling Problem in Mobile
+*   \[[SLING-7854](https://issues.apache.org/jira/browse/SLING-7854)\] - CMS - UI - Add Pathing / Search Support
+*   \[[SLING-7855](https://issues.apache.org/jira/browse/SLING-7855)\] - CMS - UI - Improve Content Table View
+*   \[[SLING-7858](https://issues.apache.org/jira/browse/SLING-7858)\] - Convert CSS to a Framework
+
+## 0.9.0
+
+Initial release of Sling CMS, focus on core functionality.
+
+ * [Download](https://search.maven.org/remotecontent?filepath=org/apache/sling/org.apache.sling.cms.builder/0.10.0/org.apache.sling.cms.builder-0.9.0.jar)
+ * [JavaDoc](http://javadoc.io/doc/org.apache.sling/org.apache.sling.cms.core/0.9.0)
+ * [Documentation](https://github.com/apache/sling-org-apache-sling-app-cms/tree/1afa5da54257cad8a5bf4b28d76b88d13838433b)
\ No newline at end of file
diff --git a/docs/user-generated-content.md b/docs/user-generated-content.md
new file mode 100644
index 0000000..62258f4
--- /dev/null
+++ b/docs/user-generated-content.md
@@ -0,0 +1,48 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	you 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. -->
+[Apache Sling](https://sling.apache.org) > [Sling CMS](https://github.com/apache/sling-org-apache-sling-app-cms) > [Administration](administration.md) > User Generated Content
+
+# User Generated Content
+
+Sling CMS includes a console for curating User Generated Content. The content is organized into "buckets" each bucket corresponding to a form or entry method for UGC.
+
+Content by default is not "approved" and requires manual approval. Approval can result in the content either being moved to a path specified by the creating service or in the content being set to published, depending on the approval action.
+
+### Managing User Generated Content
+
+User Generated Content is stored under the path */etc/usergenerated*. To manage User Generated Content, use the User Generated Content console. This can be accessed in the sidebar:
+
+![User Generated Content Console](img/ugc-console.png)
+
+To moderate an individual piece of User Generated Content, select the content and select the eye button, this will open the UGC Approval Console from which you can approve or delete the content:
+
+![User Generated Content Approval](img/ugc-approval.png)
+
+### Creating User Generated Content
+
+To create User Generate Content, create a Servlet referencing the `UserGeneratedContentService` from the Sling CMS Core bundle.  
+
+    @Reference
+    private UserGeneratedContentService ugcService;
+
+From this service, you can create a UGC container given a bucket configuration:
+
+    private static final UGCBucketConfig BUCKET_CONFIG = new UGCBucketConfig();
+    static {
+        BUCKET_CONFIG.setAction(APPROVE_ACTION.MOVE);
+        BUCKET_CONFIG.setBucket("group/site/events");
+        BUCKET_CONFIG.setContentType(CONTENT_TYPE.OTHER);
+        BUCKET_CONFIG.setPathDepth(0);
+    }
+    Resource container = ugcService.createUGCContainer(request, BUCKET_CONFIG, title + "\n\n" + summary,
+        "/content/group/site/events");
+
+The container will be created with a privileged user with access to write to the */etc/usergenerated* path, so if you make any additions to the container be sure to use that Resource's Resource Resolver. 
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 34540a6..f9e2671 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,15 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-    license agreements. See the NOTICE file distributed with this work for additional 
-    information regarding copyright ownership. The ASF licenses this file to 
-    you 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to you 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+>
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.sling</groupId>
@@ -167,6 +164,12 @@
                 <version>16.0.2</version>
                 <scope>provided</scope>
             </dependency>
+            <dependency>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>oak-core</artifactId>
+                <version>1.6.8</version>
+                <scope>provided</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
diff --git a/ui/src/main/frontend/gulpfile.js b/ui/src/main/frontend/gulpfile.js
index 8d35fb6..f8cc434 100755
--- a/ui/src/main/frontend/gulpfile.js
+++ b/ui/src/main/frontend/gulpfile.js
@@ -24,6 +24,8 @@
 var sourcemaps = require('gulp-sourcemaps');
 var streamqueue = require('streamqueue');
 var saveLicense = require('uglify-save-license');
+var log = require('fancy-log');
+
 
 
 const apache2License = [
@@ -91,8 +93,8 @@
             output: {
                 comments: saveLicense
             }
-        }))
-         .pipe(concat('scripts-all.min.js'))
+        }).on('error', function (err) { log('[Error]' +  err.toString()); exit(1); }))
+        .pipe(concat('scripts-all.min.js'))
         .pipe(gulp.dest('./dist/jcr_root/static/clientlibs/sling-cms/js'));
 });
 
@@ -104,7 +106,6 @@
 
 gulp.task('editor-js', function() {
     return gulp.src([
-            './node_modules/jquery/dist/jquery.js',
             './src/js/editor.js'
         ])
         .pipe(uglify({
diff --git a/ui/src/main/frontend/package.json b/ui/src/main/frontend/package.json
index 808dc0e..f7918fd 100644
--- a/ui/src/main/frontend/package.json
+++ b/ui/src/main/frontend/package.json
@@ -12,7 +12,9 @@
   	"summernote": "^0.8.9",
   	"jam-icons": "^2.0.0",
   	"js-autocomplete": "^1.0.4",
-  	"datatables": "^1.10.18"
+  	"datatables": "^1.10.18",
+    "bulma": "^0.7.1",
+    "datatables-bulma": "^1.0.1"
   },
   "devDependencies": {
     "gulp": "^3.9.1",
@@ -25,8 +27,7 @@
     "gulp-sourcemaps": "^2.6.4",
     "streamqueue": "^1.1.2",
     "uglify-save-license": "^0.4.1",
-    "bulma": "^0.7.1",
-    "datatables-bulma": "^1.0.1"
+    "fancy-log": "^1.3.2"
   },
   "license": "Apache-2.0"
 }
\ No newline at end of file
diff --git a/ui/src/main/frontend/src/js/cms.js b/ui/src/main/frontend/src/js/cms.js
index 41cb831..730e823 100644
--- a/ui/src/main/frontend/src/js/cms.js
+++ b/ui/src/main/frontend/src/js/cms.js
@@ -169,7 +169,7 @@
 
       // mouse button down over the element
       element.addEventListener('mousedown', function(evt) {
-        if (document.querySelector('.modal-card-body').contains(evt.target)) {
+        if (evt.target.matches('.modal-card-body *')) {
           return;
         }
         mouseX = evt.clientX;
@@ -326,6 +326,19 @@
   }
 };
 
+
+    Sling.CMS.ext['navbar'] = {
+        init: function() {
+            document.querySelectorAll('.navbar-burger').forEach(function(burger){
+                burger.addEventListener('click', function(){
+                    var target = document.querySelector(burger.dataset.target);
+                    target.classList.toggle('is-active');
+                    burger.classList.toggle('is-active');
+                });
+            });
+        }
+    };
+
 Sling.CMS.ext['pageproperties'] = {
   decorate : function($ctx) {
     $ctx.find('.Sling-CMS__page-properties').each(function() {
@@ -444,26 +457,25 @@
   }
 };
 
-Sling.CMS.ext['searchselect'] = {
-  decorate : function($ctx) {
-    $ctx.find('.Search-Select-Button').click(function(evt) {
-      var $btn = $(evt.target);
-      var $active = Sling.CMS.ext['searchbutton'].active;
-      $active.val($btn.data('path'));
-      $btn.closest('.Modal').remove();
-    });
-  }
-}
 
-Sling.CMS.ext['searchbutton'] = {
-  active : null,
-  decorate : function($ctx) {
-    $ctx.find('.Search-Button').click(
-        function(evt) {
-          Sling.CMS.ext['searchbutton'].active = $(evt.target).closest(
-              '.Field-Input').find('.Field-Path');
-        });
-  }
+    Sling.CMS.ext['searchselect'] = {
+        decorate: function($ctx) {
+            $ctx.find('.search-select-button').click(function(evt){
+                var $btn = $(evt.target);
+                var $active = Sling.CMS.ext['searchbutton'].active;
+                $active.val($btn.data('path'));
+                $btn.closest('.modal').remove();
+            });
+        }
+    }
+    
+    Sling.CMS.ext['searchbutton'] = {
+        active: null,
+        decorate: function($ctx) {
+            $ctx.find('.search-button').click(function(evt){
+                Sling.CMS.ext['searchbutton'].active = $(evt.target).closest('.field').find('.pathfield');
+            });
+        }
 }
 
 Sling.CMS.ext['suffix-form'] = {
diff --git a/ui/src/main/frontend/src/js/editor.js b/ui/src/main/frontend/src/js/editor.js
index 198b2b1..6b19b7f 100644
--- a/ui/src/main/frontend/src/js/editor.js
+++ b/ui/src/main/frontend/src/js/editor.js
@@ -17,101 +17,115 @@
  * under the License.
  */ 
 if(!window.CMSEditor){
-	window.CMSEditor = {
-		init: function(){
-			$(".sling-cms-editor .button[data-sling-cms-action=add]").click(function(){
-				CMSEditor.ui.showModal('/cms/editor/add.html'+$(this).attr('data-sling-cms-path')+'?availableTypes='+$(this).data('sling-cms-available-types'));
-			});
-			$(".sling-cms-editor .button[data-sling-cms-action=delete]").click(function(){
-				CMSEditor.ui.showModal('/cms/editor/delete.html'+$(this).attr('data-sling-cms-path'));
-			});
-			$(".sling-cms-editor .button[data-sling-cms-action=edit]").click(function(){
-				CMSEditor.ui.showModal(
-					'/cms/editor/edit.html'+$(this).attr('data-sling-cms-path')+'?editor='+$(this).attr('data-sling-cms-edit'),
-					$(this).closest('.sling-cms-component').attr('data-sling-cms-title'));
-			});
-			$(".sling-cms-editor .button[data-sling-cms-action=reorder]").click(function(){
-				CMSEditor.ui.showModal('/cms/editor/reorder.html'+$(this).attr('data-sling-cms-path'));
-			});
-			
-			// closing the modal
-			$(".sling-cms-editor .delete").click(function(){
-				CMSEditor.ui.hideModal();
-			});
-			window.addEventListener('keypress',function(e){
-				if(e.keyCode==27 && CMSEditor.ui.modalDisplayed === true){
-					CMSEditor.ui.hideModal();
-				}
-			});
+    window.CMSEditor = {
+        init: function(){
+            CMSEditor.util.attachClick('.sling-cms-editor .button[data-sling-cms-action=add]', function(evt){
+                CMSEditor.ui.showModal('/cms/editor/add.html'+this.dataset.slingCmsPath+'?availableTypes='+this.dataset.slingCmsAvailableTypes, this.title);
+            });
+            CMSEditor.util.attachClick('.sling-cms-editor .button[data-sling-cms-action=delete]', function(evt){
+                CMSEditor.ui.showModal('/cms/editor/delete.html'+this.dataset.slingCmsPath, this.title);
+            });
+            CMSEditor.util.attachClick('.sling-cms-editor .button[data-sling-cms-action=edit]', function(evt){
+                CMSEditor.ui.showModal(
+                    '/cms/editor/edit.html'+this.dataset.slingCmsPath+'?editor='+this.dataset.slingCmsEdit,
+                    CMSEditor.util.findParent(this,'.sling-cms-component').dataset.slingCmsTitle || this.title);
+            });
+            CMSEditor.util.attachClick('.sling-cms-editor .button[data-sling-cms-action=reorder]', function(evt){
+                CMSEditor.ui.showModal('/cms/editor/reorder.html'+this.dataset.slingCmsPath, this.title);
+            });
+            
+            // closing the modal
+            CMSEditor.util.attachClick('.sling-cms-editor .close-modal', function(){
+                CMSEditor.ui.hideModal();
+            });
+            window.addEventListener('keypress',function(e){
+                if(e.keyCode==27 && CMSEditor.ui.modalDisplayed === true){
+                    CMSEditor.ui.hideModal();
+                }
+            });
 
-			var mouseX;
-			var mouseY;
-			
-			function draggable(element) {
-				var mouseDown = false;
-				
-				var elementX = 0;
-				var elementY = 0;
+            var mouseX;
+            var mouseY;
+            
+            function draggable(element) {
+                var mouseDown = false;
+                var elementX = 0;
+                var elementY = 0;
 
-				  // mouse button down over the element
-				element.addEventListener('mousedown', function(evt){
-					console.log('mousedown');
-					mouseX = evt.clientX;
-					mouseY = evt.clientY;
-					mouseDown = true;
-				});
-				
-				var moveComplete = function(evt){
-					console.log('mouseup');
-					mouseDown = false;
-					elementX = parseInt(element.style.left) || 0;
-					elementY = parseInt(element.style.top) || 0;
-					return false;
-				}
-				
-				element.addEventListener('mouseup', moveComplete);
-				document.addEventListener('mouseout', moveComplete);
-				
-				document.addEventListener('mousemove', function(event) {
-					if (!mouseDown) {
-						return;
-					}
-					console.log('mousemove');
-				    var deltaX = event.clientX - mouseX;
-				    var deltaY = event.clientY - mouseY;
-				    element.style.left = elementX + deltaX + 'px';
-				    element.style.top = elementY + deltaY + 'px';
-				    return false;
-				});
-			}
-			draggable($(".sling-cms-editor .modal-card")[0]);
-		},
-		ui: {
-			modalDisplayed: false,
-			hideModal: function() {
-				if(CMSEditor.ui.modalDisplayed) {
-					$('.sling-cms-editor .modal').removeClass('is-active');
-					CMSEditor.ui.modalDisplayed = false;
-				}
-			},
-			showModal: function(url, title){
-				title = title || '';
-				if(CMSEditor.ui.modalDisplayed) {
-					CMSEditor.ui.hideModal();
-				}
-				
-				$(".sling-cms-editor .modal-card-title").text(title);
-				$('.sling-cms-editor .modal-card-body').html('<iframe class="modal-frame" src="'+url+'"></iframe>');
-				$('.sling-cms-editor .modal').addClass('is-active');
+                  // mouse button down over the element
+                element.addEventListener('mousedown', function(evt){
+                    if(evt.target.matches('.modal-card-body *')){
+                        return;
+                    }
+                    mouseX = evt.clientX;
+                    mouseY = evt.clientY;
+                    mouseDown = true;
+                });
+                
+                var moveComplete = function(evt){
+                    mouseDown = false;
+                    elementX = parseInt(element.style.left) || 0;
+                    elementY = parseInt(element.style.top) || 0;
+                    return false;
+                }
+                
+                element.addEventListener('mouseup', moveComplete);
+                document.addEventListener('mouseout', moveComplete);
+                
+                document.addEventListener('mousemove', function(event) {
+                    if (!mouseDown) {
+                        return;
+                    }
+                    var deltaX = event.clientX - mouseX;
+                    var deltaY = event.clientY - mouseY;
+                    element.style.left = elementX + deltaX + 'px';
+                    element.style.top = elementY + deltaY + 'px';
+                    return false;
+                });
+            }
+            draggable(document.querySelector('.sling-cms-editor .modal-card'));
+        },
+        ui: {
+            modalDisplayed: false,
+            hideModal: function() {
+                if(CMSEditor.ui.modalDisplayed) {
+                    document.querySelector('.sling-cms-editor .modal').classList.remove('is-active');
+                    CMSEditor.ui.modalDisplayed = false;
+                }
+            },
+            showModal: function(url, title){
+                title = title || '';
+                if(CMSEditor.ui.modalDisplayed) {
+                    CMSEditor.ui.hideModal();
+                }
+                document.querySelector('.sling-cms-editor .modal-card-title').innerText = title;
+                document.querySelector('.sling-cms-editor .modal-card-body').innerHTML = '<iframe class="modal-frame" src="'+url+'"></iframe>';
+                document.querySelector('.sling-cms-editor .modal').classList.add('is-active');
 
-				CMSEditor.ui.modalDisplayed = true;
-			}
-		}
-	}
-	
-	if (document.readyState === 'complete') {
-		CMSEditor.init();
-	} else {
-		document.addEventListener('DOMContentLoaded',CMSEditor.init,false);
-	}
+                CMSEditor.ui.modalDisplayed = true;
+            }
+        },
+        util: {
+            attachClick: function(exp, cb){
+                document.querySelectorAll(exp).forEach(function(el){
+                    el.addEventListener('click', cb, false);
+                });
+            },
+            findParent: function(el,exp){
+                if(el == null || el.parentElement == null){
+                    return null
+                } else if(el.parentElement.matches(exp)){
+                    return el.parentElement;
+                } else {
+                    return CMSEditor.util.findParent(el.parentElement, exp);
+                }
+            }
+        }
+    }
+    
+    if (document.readyState === 'complete') {
+        CMSEditor.init();
+    } else {
+        document.addEventListener('DOMContentLoaded',CMSEditor.init,false);
+    }
 }
\ No newline at end of file
diff --git a/ui/src/main/frontend/src/scss/cms.scss b/ui/src/main/frontend/src/scss/cms.scss
index 7d2c848..4b914da 100644
--- a/ui/src/main/frontend/src/scss/cms.scss
+++ b/ui/src/main/frontend/src/scss/cms.scss
@@ -64,6 +64,10 @@
 	font-size: 120%;
 }
 
+.editor-page {
+	overflow-y: auto;
+}
+
 .is-draggable {
 	position: relative;
 }
@@ -92,6 +96,11 @@
 	padding: 1em;
 }
 
+#search-results .tile {
+    flex-wrap: wrap;
+    padding: .5em;
+}
+
 table.dataTable thead .sorting:after,
 table.dataTable thead .sorting_asc:after,
 table.dataTable thead .sorting_desc:after,
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/editconfig/editconfig.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/editconfig/editconfig.jsp
index b688572..69e44fa 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/editconfig/editconfig.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/editconfig/editconfig.jsp
@@ -17,4 +17,6 @@
  * under the License.
  */ --%>
 <%@include file="/libs/sling-cms/global.jsp"%>
-<sling:include resource="${slingRequest.requestPathInfo.suffixResource}" />
\ No newline at end of file
+<c:if test="${slingRequest.requestPathInfo.suffixResource != null}">
+    <sling:include resource="${slingRequest.requestPathInfo.suffixResource}" />
+</c:if>
\ No newline at end of file
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/searchresults/searchresults.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/searchresults/searchresults.jsp
index 186358f..e746b13 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/searchresults/searchresults.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/searchresults/searchresults.jsp
@@ -18,47 +18,47 @@
  */ --%>
  <%@include file="/libs/sling-cms/global.jsp"%>
 <div id="search-results">
-	<div class="Grid">
-	<sling:adaptTo adaptable="${slingRequest}" adaptTo="org.apache.sling.cms.core.models.SearchResults" var="results" />
-		<c:forEach var="result" items="${results.results}" begin="0" end="20" varStatus="status">
-			<div class="Cell Search-Result Small-50">
-				<div class="Search-Result__Container">
-					<c:choose>
-						<c:when test="${not empty result.valueMap['jcr:content/jcr:title']}">
-							<c:set var="title" value="${result.valueMap['jcr:content/jcr:title']}" />
-						</c:when>
-						<c:when test="${not empty result.valueMap['jcr:title']}">
-							<c:set var="title" value="${result.valueMap['jcr:title']}" />
-						</c:when>
-						<c:otherwise>
-							<c:set var="title" value="${result.name}" />
-						</c:otherwise>
-					</c:choose>
-					<c:choose>
-						<c:when test="${result.valueMap['jcr:primaryType'] == 'sling:Page'}">
-							<c:set var="icon" value="document" />
-						</c:when>
-						<c:when test="${result.valueMap['jcr:primaryType'] == 'nt:file' || result.valueMap['jcr:primaryType'] == 'sling:File'}">
-							<c:set var="icon" value="file" />
-						</c:when>
-						<c:when test="${result.valueMap['jcr:primaryType'] == 'nt:folder' || result.valueMap['jcr:primaryType'] == 'sling:Folder' || result.valueMap['jcr:primaryType'] == 'sling:OrderedFolder'}">
-							<c:set var="icon" value="folder" />
-						</c:when>
-						<c:otherwise>
-							<c:set var="icon" value="sitemap" />
-						</c:otherwise>
-					</c:choose>
-					<h4>
-						<span class="jam jam-${icon}"></span>
-						${sling:encode(title,'HTML')}
-					</h4>
-					<small>
-						<em>${result.path}</em>
-					</small><br/>
-					<br />
-					<a href="#" class="Button Search-Select-Button" data-path="${result.path}">Select</a>
-				</div>
-			</div>
-		</c:forEach>
-	</div>
+    <div class="tile is-ancestor">
+    <sling:adaptTo adaptable="${slingRequest}" adaptTo="org.apache.sling.cms.core.models.SearchResults" var="results" />
+        <c:forEach var="result" items="${results.results}" begin="0" end="20" varStatus="status">
+            <div class="tile is-6 is-child">
+                <div class="box">
+                    <c:choose>
+                        <c:when test="${not empty result.valueMap['jcr:content/jcr:title']}">
+                            <c:set var="title" value="${result.valueMap['jcr:content/jcr:title']}" />
+                        </c:when>
+                        <c:when test="${not empty result.valueMap['jcr:title']}">
+                            <c:set var="title" value="${result.valueMap['jcr:title']}" />
+                        </c:when>
+                        <c:otherwise>
+                            <c:set var="title" value="${result.name}" />
+                        </c:otherwise>
+                    </c:choose>
+                    <c:choose>
+                        <c:when test="${result.valueMap['jcr:primaryType'] == 'sling:Page'}">
+                            <c:set var="icon" value="document" />
+                        </c:when>
+                        <c:when test="${result.valueMap['jcr:primaryType'] == 'nt:file' || result.valueMap['jcr:primaryType'] == 'sling:File'}">
+                            <c:set var="icon" value="file" />
+                        </c:when>
+                        <c:when test="${result.valueMap['jcr:primaryType'] == 'nt:folder' || result.valueMap['jcr:primaryType'] == 'sling:Folder' || result.valueMap['jcr:primaryType'] == 'sling:OrderedFolder'}">
+                            <c:set var="icon" value="folder" />
+                        </c:when>
+                        <c:otherwise>
+                            <c:set var="icon" value="sitemap" />
+                        </c:otherwise>
+                    </c:choose>
+                    <h4>
+                        <span class="jam jam-${icon}"></span>
+                        ${sling:encode(title,'HTML')}
+                    </h4>
+                    <small>
+                        <em>${result.path}</em>
+                    </small><br/>
+                    <br />
+                    <a href="#" class="button search-select-button" data-path="${result.path}">Select</a>
+                </div>
+            </div>
+        </c:forEach>
+    </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/suffixswitch/suffixswitch.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/suffixswitch/suffixswitch.jsp
index 7127cb3..e704711 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/suffixswitch/suffixswitch.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/suffixswitch/suffixswitch.jsp
@@ -32,7 +32,7 @@
                     <input class="input pathfield" type="text" name="suffix" required="required" data-type="${properties.type}" data-base="${properties.base}" autocomplete="off" />
                 </div>
                 <div class="control">
-                    <a href="/cms/shared/search.html" class="button Fetch-Modal Search-Button" data-title="Search" data-path=".Main-Content > *">
+                    <a href="/cms/shared/search.html" class="button Fetch-Modal search-button" data-title="Search" data-path=".Main-Content > *">
                         <span class="jam jam-search"></span>
                     </a>
                 </div>
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/fields/path/path.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/fields/path/path.jsp
index 682979e..15ab141 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/fields/path/path.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/fields/path/path.jsp
@@ -50,7 +50,7 @@
               <input class="input pathfield" type="text" name="${properties.name}" value="${editProperties[properties.name]}" ${required} ${disabled} data-type="${properties.type}" data-base="${properties.basePath}" autocomplete="off" />
           </div>
           <div class="control">
-              <a href="/cms/shared/search.html" class="button Fetch-Modal Search-Button" data-title="Search" data-path=".Main-Content > *">
+              <a href="/cms/shared/search.html" class="button Fetch-Modal search-button" data-title="Search" data-path=".Main-Content > *">
                   <span class="jam jam-search"></span>
               </a>
           </div>
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/finalize.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/finalize.jsp
index ff8882d..5f3bec8 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/finalize.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/finalize.jsp
@@ -26,7 +26,7 @@
 				<div class="modal-card">
 					<header class="modal-card-head">
 						<p class="modal-card-title"></p>
-						<button class="button delete is-small" aria-label="close">
+						<button class="button close-modal is-small" aria-label="close">
 							<span class="jam jam-close"></span>
 						</button>
 					</header>
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/general/container/container.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/general/container/container.jsp
index 2de28c0..a231422 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/general/container/container.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/general/container/container.jsp
@@ -34,7 +34,7 @@
 		<div class="level has-background-grey">
 			<div class="level-left">
 				<div class="level-item">
-					<button class="button" data-sling-cms-action="add" data-sling-cms-path="${resource.path}" data-sling-cms-available-types="${availableTypes}" title="Add">
+					<button class="button" data-sling-cms-action="add" data-sling-cms-path="${resource.path}" data-sling-cms-available-types="${availableTypes}" title="Add Component">
 						&#43;
 					</button>
 				</div>
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/base/nav.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/base/nav.jsp
index 2e6fd9e..7dc39b8 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/base/nav.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/base/nav.jsp
@@ -18,22 +18,20 @@
  */ --%>
 <%@include file="/libs/sling-cms/global.jsp"%>
 <nav class="navbar is-transparent" role="navigation" aria-label="main mavigation">
-<div class="navbar-brand">
-<a class="navbar-item" href="http://sling.apache.org" >
-    <img src="/static/clientlibs/sling-cms/img/sling-logo.svg" width="100" alt="Apache Sling"/>
-</a>
-<a href="/cms/start.html" class="navbar-item" title="CMS Home"><span class="icon"><i class="jam jam-home-f"></i></span></a>
-<div class="navbar-item">
-</div>
-<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
-  <span aria-hidden="true"></span>
-  <span aria-hidden="true"></span>
-  <span aria-hidden="true"></span>
-</a>
-</div>
-<div class="navbar-menu">
-<div class="navbar-end">
-<a class="navbar-item " href="/system/sling/logout" title="Logout of Apache Sling CMS"><span>${resourceResolver.userID} </span><i class="jam jam-log-out"></i></a>
-</div>
-</div>
-</nav>
\ No newline at end of file
+    <div class="navbar-brand">
+        <a class="navbar-item" href="http://sling.apache.org" >
+            <img src="/static/clientlibs/sling-cms/img/sling-logo.svg" width="100" alt="Apache Sling"/>
+        </a>
+        <a href="/cms/start.html" class="navbar-item" title="CMS Home"><span class="icon"><i class="jam jam-home-f"></i></span></a>
+        <a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="#top-navbar-menu">
+          <span aria-hidden="true"></span>
+          <span aria-hidden="true"></span>
+          <span aria-hidden="true"></span>
+        </a>
+    </div>
+    <div class="navbar-menu" id="top-navbar-menu">
+        <div class="navbar-end">
+            <a class="navbar-item " href="/system/sling/logout" title="Logout of Apache Sling CMS"><span>${resourceResolver.userID} </span><i class="jam jam-log-out"></i></a>
+        </div>
+    </div>
+</nav>
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/body.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/body.jsp
index d8db3b3..d3cb509 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/body.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/body.jsp
@@ -17,7 +17,7 @@
  * under the License.
  */ --%>
  <%@include file="/libs/sling-cms/global.jsp"%>
-<body class="Editor-Page">
+<body>
 	<sling:include path="container" resourceType="sling-cms/components/general/container"  />
 	<sling:call script="scripts.jsp" />
 </body>
\ No newline at end of file
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/editor.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/editor.jsp
new file mode 100644
index 0000000..a9a0a52
--- /dev/null
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/pages/editor/editor.jsp
@@ -0,0 +1,23 @@
+<%-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */ --%>
+ <%@include file="/libs/sling-cms/global.jsp"%>
+<html lang="en" class="editor-page">
+	<sling:call script="head.jsp" />
+	<sling:call script="body.jsp" />
+</html>
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/content/shared/search.json b/ui/src/main/resources/jcr_root/libs/sling-cms/content/shared/search.json
new file mode 100644
index 0000000..326e8bb
--- /dev/null
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/content/shared/search.json
@@ -0,0 +1,53 @@
+{
+	"jcr:primaryType": "sling:Page",
+	"jcr:content": {
+		"sling:resourceType": "sling-cms/components/pages/base",
+		"jcr:title": "Search",
+		"jcr:primaryType": "nt:unstructured",
+		"container": {
+			"jcr:primaryType": "nt:unstructured",
+			"sling:resourceType": "sling-cms/components/general/container",
+			"searchform": {
+				"jcr:primaryType": "nt:unstructured",
+				"sling:resourceType": "sling-cms/components/cms/getform",
+				"button": "Search",
+				"load": "#search-results .is-ancestor",
+				"target": "#search-results",
+				"fields": {
+					"jcr:primaryType": "nt:unstructured",
+					"sling:resourceType": "sling-cms/components/general/container",
+					"term": {
+						"jcr:primaryType": "nt:unstructured",
+						"sling:resourceType": "sling-cms/components/editor/fields/text",
+						"label": "Term",
+						"name": "term",
+						"required": "required"
+					},
+					"type": {
+						"jcr:primaryType": "nt:unstructured",
+						"sling:resourceType": "sling-cms/components/editor/fields/select",
+						"name": "type",
+						"label": "Content Type",
+						"options": [
+							"Page=sling:Page",
+							"File=sling:File",
+							"Folder=sling:Folder",
+							"Everything=nt:base"
+						]
+					},
+					"path": {
+						"jcr:primaryType": "nt:unstructured",
+						"sling:resourceType": "sling-cms/components/editor/fields/path",
+						"label": "Path",
+						"name": "path",
+						"hidesearch": true
+					}
+				}
+			},
+			"searchresults": {
+				"jcr:primaryType": "nt:unstructured",
+				"sling:resourceType": "sling-cms/components/cms/searchresults"
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/ui/src/main/resources/jcr_root/libs/sling/servlet/errorhandler/default.jsp b/ui/src/main/resources/jcr_root/libs/sling/servlet/errorhandler/default.jsp
index e2b9f80..55f605a 100644
--- a/ui/src/main/resources/jcr_root/libs/sling/servlet/errorhandler/default.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling/servlet/errorhandler/default.jsp
@@ -15,5 +15,4 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- */ --%><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@include file="/libs/sling-cms/global.jsp"%><sling:adaptTo var="errorHandler" adaptable="${slingRequest}" adaptTo="org.apache.sling.cms.core.models.ErrorHandler" />
-<sling:include path="${sling:getRelativeResource(errorHandler.handler,'jcr:content').path}.html" resourceType="${sling:getRelativeResource(errorHandler.handler,'jcr:content').resourceType}" />
\ No newline at end of file
+ */ --%><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@include file="/libs/sling-cms/global.jsp"%><sling:adaptTo var="errorHandler" adaptable="${slingRequest}" adaptTo="org.apache.sling.cms.core.models.ErrorHandler" />
\ No newline at end of file